summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite.cpp47
-rw-r--r--scene/2d/animated_sprite.h50
-rw-r--r--scene/2d/area_2d.cpp4
-rw-r--r--scene/2d/area_2d.h4
-rw-r--r--scene/2d/camera_2d.cpp4
-rw-r--r--scene/2d/canvas_item.cpp247
-rw-r--r--scene/2d/canvas_item.h71
-rw-r--r--scene/2d/collision_object_2d.cpp4
-rw-r--r--scene/2d/collision_shape_2d.cpp2
-rw-r--r--scene/2d/cpu_particles_2d.cpp82
-rw-r--r--scene/2d/cpu_particles_2d.h14
-rw-r--r--scene/2d/light_2d.cpp28
-rw-r--r--scene/2d/light_2d.h14
-rw-r--r--scene/2d/line_2d.cpp9
-rw-r--r--scene/2d/line_2d.h6
-rw-r--r--scene/2d/mesh_instance_2d.cpp12
-rw-r--r--scene/2d/mesh_instance_2d.h12
-rw-r--r--scene/2d/multimesh_instance_2d.cpp12
-rw-r--r--scene/2d/multimesh_instance_2d.h12
-rw-r--r--scene/2d/navigation_2d.cpp714
-rw-r--r--scene/2d/navigation_2d.h137
-rw-r--r--scene/2d/navigation_agent_2d.cpp341
-rw-r--r--scene/2d/navigation_agent_2d.h150
-rw-r--r--scene/2d/navigation_obstacle_2d.cpp154
-rw-r--r--scene/2d/navigation_obstacle_2d.h71
-rw-r--r--scene/2d/navigation_polygon.cpp95
-rw-r--r--scene/2d/navigation_polygon.h13
-rw-r--r--scene/2d/particles_2d.cpp12
-rw-r--r--scene/2d/particles_2d.h12
-rw-r--r--scene/2d/path_2d.cpp12
-rw-r--r--scene/2d/path_texture.cpp12
-rw-r--r--scene/2d/path_texture.h18
-rw-r--r--scene/2d/physics_body_2d.cpp142
-rw-r--r--scene/2d/physics_body_2d.h15
-rw-r--r--scene/2d/polygon_2d.cpp76
-rw-r--r--scene/2d/polygon_2d.h23
-rw-r--r--scene/2d/ray_cast_2d.cpp8
-rw-r--r--scene/2d/remote_transform_2d.cpp7
-rw-r--r--scene/2d/sprite.cpp66
-rw-r--r--scene/2d/sprite.h24
-rw-r--r--scene/2d/tile_map.cpp22
-rw-r--r--scene/2d/tile_map.h2
-rw-r--r--scene/2d/touch_screen_button.cpp12
-rw-r--r--scene/2d/touch_screen_button.h12
-rw-r--r--scene/3d/area.cpp4
-rw-r--r--scene/3d/area.h4
-rw-r--r--scene/3d/baked_lightmap.cpp26
-rw-r--r--scene/3d/baked_lightmap.h8
-rw-r--r--scene/3d/camera.cpp18
-rw-r--r--scene/3d/camera.h4
-rw-r--r--scene/3d/cpu_particles.cpp42
-rw-r--r--scene/3d/gi_probe.cpp428
-rw-r--r--scene/3d/gi_probe.h86
-rw-r--r--scene/3d/immediate_geometry.cpp4
-rw-r--r--scene/3d/immediate_geometry.h4
-rw-r--r--scene/3d/light.cpp23
-rw-r--r--scene/3d/light.h12
-rw-r--r--scene/3d/mesh_instance.cpp12
-rw-r--r--scene/3d/navigation.cpp704
-rw-r--r--scene/3d/navigation.h147
-rw-r--r--scene/3d/navigation_agent.cpp361
-rw-r--r--scene/3d/navigation_agent.h162
-rw-r--r--scene/3d/navigation_mesh_instance.cpp258
-rw-r--r--scene/3d/navigation_mesh_instance.h75
-rw-r--r--scene/3d/navigation_obstacle.cpp163
-rw-r--r--scene/3d/navigation_obstacle.h71
-rw-r--r--scene/3d/particles.cpp10
-rw-r--r--scene/3d/physics_body.cpp282
-rw-r--r--scene/3d/physics_body.h37
-rw-r--r--scene/3d/ray_cast.cpp18
-rw-r--r--scene/3d/remote_transform.cpp7
-rw-r--r--scene/3d/skeleton.cpp81
-rw-r--r--scene/3d/skeleton.h6
-rw-r--r--scene/3d/soft_body.cpp51
-rw-r--r--scene/3d/soft_body.h3
-rw-r--r--scene/3d/sprite_3d.cpp46
-rw-r--r--scene/3d/sprite_3d.h12
-rw-r--r--scene/3d/vehicle_body.cpp3
-rw-r--r--scene/3d/visual_instance.cpp4
-rw-r--r--scene/3d/visual_instance.h1
-rw-r--r--scene/3d/voxel_light_baker.cpp2486
-rw-r--r--scene/3d/voxelizer.cpp1224
-rw-r--r--scene/3d/voxelizer.h (renamed from scene/3d/voxel_light_baker.h)117
-rw-r--r--scene/3d/world_environment.cpp49
-rw-r--r--scene/3d/world_environment.h4
-rw-r--r--scene/animation/animation_player.cpp22
-rw-r--r--scene/animation/animation_player.h10
-rw-r--r--scene/animation/animation_tree.cpp17
-rw-r--r--scene/animation/animation_tree.h1
-rw-r--r--scene/animation/animation_tree_player.cpp1866
-rw-r--r--scene/animation/animation_tree_player.h487
-rw-r--r--scene/animation/root_motion_view.cpp2
-rw-r--r--scene/animation/skeleton_ik.cpp13
-rw-r--r--scene/animation/skeleton_ik.h3
-rw-r--r--scene/animation/tween.cpp11
-rw-r--r--scene/debugger/script_debugger_remote.cpp45
-rw-r--r--scene/debugger/script_debugger_remote.h3
-rw-r--r--scene/gui/box_container.cpp2
-rw-r--r--scene/gui/button.cpp10
-rw-r--r--scene/gui/button.h6
-rw-r--r--scene/gui/check_box.cpp12
-rw-r--r--scene/gui/check_button.cpp8
-rw-r--r--scene/gui/color_picker.cpp3
-rw-r--r--scene/gui/container.cpp2
-rw-r--r--scene/gui/control.cpp28
-rw-r--r--scene/gui/control.h6
-rw-r--r--scene/gui/file_dialog.cpp4
-rw-r--r--scene/gui/file_dialog.h2
-rw-r--r--scene/gui/gradient_edit.cpp1
-rw-r--r--scene/gui/graph_edit.cpp11
-rw-r--r--scene/gui/graph_node.cpp20
-rw-r--r--scene/gui/graph_node.h6
-rw-r--r--scene/gui/grid_container.cpp2
-rw-r--r--scene/gui/item_list.cpp18
-rw-r--r--scene/gui/item_list.h16
-rw-r--r--scene/gui/line_edit.cpp49
-rw-r--r--scene/gui/line_edit.h7
-rw-r--r--scene/gui/nine_patch_rect.cpp6
-rw-r--r--scene/gui/nine_patch_rect.h6
-rw-r--r--scene/gui/option_button.cpp10
-rw-r--r--scene/gui/option_button.h6
-rw-r--r--scene/gui/panel.cpp2
-rw-r--r--scene/gui/panel_container.cpp2
-rw-r--r--scene/gui/popup_menu.cpp28
-rw-r--r--scene/gui/popup_menu.h18
-rw-r--r--scene/gui/rich_text_label.cpp32
-rw-r--r--scene/gui/rich_text_label.h4
-rw-r--r--scene/gui/scroll_bar.cpp18
-rw-r--r--scene/gui/slider.cpp10
-rw-r--r--scene/gui/spin_box.cpp4
-rw-r--r--scene/gui/spin_box.h2
-rw-r--r--scene/gui/split_container.cpp12
-rw-r--r--scene/gui/tab_container.cpp52
-rw-r--r--scene/gui/tab_container.h4
-rw-r--r--scene/gui/tabs.cpp66
-rw-r--r--scene/gui/tabs.h14
-rw-r--r--scene/gui/text_edit.cpp81
-rw-r--r--scene/gui/text_edit.h20
-rw-r--r--scene/gui/texture_button.cpp32
-rw-r--r--scene/gui/texture_button.h30
-rw-r--r--scene/gui/texture_progress.cpp20
-rw-r--r--scene/gui/texture_progress.h20
-rw-r--r--scene/gui/texture_rect.cpp6
-rw-r--r--scene/gui/texture_rect.h6
-rw-r--r--scene/gui/tree.cpp53
-rw-r--r--scene/gui/tree.h33
-rw-r--r--scene/gui/video_player.cpp4
-rw-r--r--scene/gui/video_player.h2
-rw-r--r--scene/gui/viewport_container.cpp4
-rw-r--r--scene/main/canvas_layer.cpp4
-rw-r--r--scene/main/instance_placeholder.cpp6
-rw-r--r--scene/main/instance_placeholder.h1
-rw-r--r--scene/main/node.cpp135
-rw-r--r--scene/main/node.h31
-rw-r--r--scene/main/scene_tree.cpp54
-rw-r--r--scene/main/scene_tree.h3
-rw-r--r--scene/main/viewport.cpp241
-rw-r--r--scene/main/viewport.h82
-rw-r--r--scene/register_scene_types.cpp62
-rw-r--r--scene/resources/audio_stream_sample.cpp2
-rw-r--r--scene/resources/box_shape.cpp4
-rw-r--r--scene/resources/box_shape.h1
-rw-r--r--scene/resources/capsule_shape.cpp4
-rw-r--r--scene/resources/capsule_shape.h1
-rw-r--r--scene/resources/capsule_shape_2d.cpp4
-rw-r--r--scene/resources/capsule_shape_2d.h1
-rw-r--r--scene/resources/circle_shape_2d.cpp4
-rw-r--r--scene/resources/circle_shape_2d.h1
-rw-r--r--scene/resources/concave_polygon_shape.cpp10
-rw-r--r--scene/resources/concave_polygon_shape.h3
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp10
-rw-r--r--scene/resources/concave_polygon_shape_2d.h1
-rw-r--r--scene/resources/convex_polygon_shape.cpp10
-rw-r--r--scene/resources/convex_polygon_shape.h1
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp8
-rw-r--r--scene/resources/convex_polygon_shape_2d.h1
-rw-r--r--scene/resources/cylinder_shape.cpp4
-rw-r--r--scene/resources/cylinder_shape.h1
-rw-r--r--scene/resources/default_theme/default_theme.cpp14
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/dynamic_font.cpp61
-rw-r--r--scene/resources/dynamic_font.h10
-rw-r--r--scene/resources/environment.cpp604
-rw-r--r--scene/resources/environment.h177
-rw-r--r--scene/resources/font.cpp14
-rw-r--r--scene/resources/font.h6
-rw-r--r--scene/resources/height_map_shape.cpp4
-rw-r--r--scene/resources/height_map_shape.h1
-rw-r--r--scene/resources/line_shape_2d.cpp6
-rw-r--r--scene/resources/line_shape_2d.h1
-rw-r--r--scene/resources/material.cpp1159
-rw-r--r--scene/resources/material.h191
-rw-r--r--scene/resources/mesh.cpp565
-rw-r--r--scene/resources/mesh.h31
-rw-r--r--scene/resources/mesh_library.cpp10
-rw-r--r--scene/resources/mesh_library.h8
-rw-r--r--scene/resources/multimesh.cpp95
-rw-r--r--scene/resources/multimesh.h33
-rw-r--r--scene/resources/navigation_mesh.cpp (renamed from scene/3d/navigation_mesh.cpp)196
-rw-r--r--scene/resources/navigation_mesh.h (renamed from scene/3d/navigation_mesh.h)32
-rw-r--r--scene/resources/particles_material.cpp39
-rw-r--r--scene/resources/particles_material.h30
-rw-r--r--scene/resources/plane_shape.h4
-rw-r--r--scene/resources/primitive_meshes.cpp29
-rw-r--r--scene/resources/primitive_meshes.h4
-rw-r--r--scene/resources/ray_shape.cpp4
-rw-r--r--scene/resources/ray_shape.h1
-rw-r--r--scene/resources/rectangle_shape_2d.cpp4
-rw-r--r--scene/resources/rectangle_shape_2d.h1
-rw-r--r--scene/resources/resource_format_text.cpp6
-rw-r--r--scene/resources/segment_shape_2d.cpp8
-rw-r--r--scene/resources/segment_shape_2d.h2
-rw-r--r--scene/resources/shader.cpp8
-rw-r--r--scene/resources/shader.h6
-rw-r--r--scene/resources/shape.h3
-rw-r--r--scene/resources/shape_2d.h2
-rw-r--r--scene/resources/sky.cpp112
-rw-r--r--scene/resources/sky.h30
-rw-r--r--scene/resources/sphere_shape.cpp4
-rw-r--r--scene/resources/sphere_shape.h1
-rw-r--r--scene/resources/style_box.cpp12
-rw-r--r--scene/resources/style_box.h12
-rw-r--r--scene/resources/surface_tool.cpp2
-rw-r--r--scene/resources/text_file.h2
-rw-r--r--scene/resources/texture.cpp1334
-rw-r--r--scene/resources/texture.h365
-rw-r--r--scene/resources/theme.cpp14
-rw-r--r--scene/resources/theme.h10
-rw-r--r--scene/resources/tile_set.cpp48
-rw-r--r--scene/resources/tile_set.h12
-rw-r--r--scene/resources/video_stream.h3
-rw-r--r--scene/resources/visual_shader.cpp3
-rw-r--r--scene/resources/visual_shader.h2
-rw-r--r--scene/resources/visual_shader_nodes.cpp175
-rw-r--r--scene/resources/visual_shader_nodes.h60
-rw-r--r--scene/resources/world.cpp18
-rw-r--r--scene/resources/world.h4
237 files changed, 8280 insertions, 11145 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index 917ced5feb..b98820d5ac 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -34,6 +34,7 @@
#include "scene/scene_string_names.h"
#define NORMAL_SUFFIX "_normal"
+#define SPECULAR_SUFFIX "_specular"
#ifdef TOOLS_ENABLED
Dictionary AnimatedSprite::_edit_get_state() const {
@@ -68,7 +69,7 @@ bool AnimatedSprite::_edit_use_rect() const {
if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) {
return false;
}
- Ref<Texture> t;
+ Ref<Texture2D> t;
if (animation)
t = frames->get_frame(animation, frame);
return t.is_valid();
@@ -84,7 +85,7 @@ Rect2 AnimatedSprite::_get_rect() const {
return Rect2();
}
- Ref<Texture> t;
+ Ref<Texture2D> t;
if (animation)
t = frames->get_frame(animation, frame);
if (t.is_null())
@@ -101,7 +102,7 @@ Rect2 AnimatedSprite::_get_rect() const {
return Rect2(ofs, s);
}
-void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos) {
+void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
@@ -150,6 +151,7 @@ void SpriteFrames::add_animation(const StringName &p_anim) {
animations[p_anim] = Anim();
animations[p_anim].normal_name = String(p_anim) + NORMAL_SUFFIX;
+ animations[p_anim].specular_name = String(p_anim) + SPECULAR_SUFFIX;
}
bool SpriteFrames::has_animation(const StringName &p_anim) const {
@@ -170,6 +172,7 @@ void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &
animations.erase(p_prev);
animations[p_next] = anim;
animations[p_next].normal_name = String(p_next) + NORMAL_SUFFIX;
+ animations[p_next].specular_name = String(p_next) + SPECULAR_SUFFIX;
}
Vector<String> SpriteFrames::_get_animation_list() const {
@@ -438,11 +441,12 @@ void AnimatedSprite::_notification(int p_what) {
if (!frames->has_animation(animation))
return;
- Ref<Texture> texture = frames->get_frame(animation, frame);
+ Ref<Texture2D> texture = frames->get_frame(animation, frame);
if (texture.is_null())
return;
- Ref<Texture> normal = frames->get_normal_frame(animation, frame);
+ Ref<Texture2D> normal = frames->get_normal_frame(animation, frame);
+ Ref<Texture2D> specular = frames->get_specular_frame(animation, frame);
RID ci = get_canvas_item();
@@ -462,7 +466,7 @@ void AnimatedSprite::_notification(int p_what) {
if (vflip)
dst_rect.size.y = -dst_rect.size.y;
- texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal);
+ texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal, specular, Color(specular_color.r, specular_color.g, specular_color.b, shininess));
} break;
}
@@ -674,6 +678,24 @@ String AnimatedSprite::get_configuration_warning() const {
return String();
}
+void AnimatedSprite::set_specular_color(const Color &p_color) {
+ specular_color = p_color;
+ update();
+}
+
+Color AnimatedSprite::get_specular_color() const {
+ return specular_color;
+}
+
+void AnimatedSprite::set_shininess(float p_shininess) {
+ shininess = CLAMP(p_shininess, 0.0, 1.0);
+ update();
+}
+
+float AnimatedSprite::get_shininess() const {
+ return shininess;
+}
+
void AnimatedSprite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_sprite_frames", "sprite_frames"), &AnimatedSprite::set_sprite_frames);
@@ -707,16 +729,27 @@ void AnimatedSprite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_speed_scale", "speed_scale"), &AnimatedSprite::set_speed_scale);
ClassDB::bind_method(D_METHOD("get_speed_scale"), &AnimatedSprite::get_speed_scale);
+ ClassDB::bind_method(D_METHOD("set_specular_color", "color"), &AnimatedSprite::set_specular_color);
+ ClassDB::bind_method(D_METHOD("get_specular_color"), &AnimatedSprite::get_specular_color);
+
+ ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &AnimatedSprite::set_shininess);
+ ClassDB::bind_method(D_METHOD("get_shininess"), &AnimatedSprite::get_shininess);
+
ClassDB::bind_method(D_METHOD("_res_changed"), &AnimatedSprite::_res_changed);
ADD_SIGNAL(MethodInfo("frame_changed"));
ADD_SIGNAL(MethodInfo("animation_finished"));
+ ADD_GROUP("Animation", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale"), "set_speed_scale", "get_speed_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing");
+ ADD_GROUP("Lighting", "");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess");
+ ADD_GROUP("Offset", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h");
@@ -736,4 +769,6 @@ AnimatedSprite::AnimatedSprite() {
animation = "default";
timeout = 0;
is_over = false;
+ specular_color = Color(1, 1, 1, 1);
+ shininess = 1.0;
}
diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h
index cd00a4e181..37d093e3d8 100644
--- a/scene/2d/animated_sprite.h
+++ b/scene/2d/animated_sprite.h
@@ -42,7 +42,7 @@ class SpriteFrames : public Resource {
float speed;
bool loop;
- Vector<Ref<Texture> > frames;
+ Vector<Ref<Texture2D> > frames;
Anim() {
loop = true;
@@ -50,8 +50,12 @@ class SpriteFrames : public Resource {
}
StringName normal_name;
+ StringName specular_name;
};
+ Color specular_color;
+ float shininess;
+
Map<StringName, Anim> animations;
Array _get_frames() const;
@@ -80,34 +84,48 @@ public:
void set_animation_loop(const StringName &p_anim, bool p_loop);
bool get_animation_loop(const StringName &p_anim) const;
- void add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos = -1);
+ void add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos = -1);
int get_frame_count(const StringName &p_anim) const;
- _FORCE_INLINE_ Ref<Texture> get_frame(const StringName &p_anim, int p_idx) const {
+ _FORCE_INLINE_ Ref<Texture2D> get_frame(const StringName &p_anim, int p_idx) const {
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_V_MSG(!E, Ref<Texture>(), "Animation '" + String(p_anim) + "' doesn't exist.");
- ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>());
+ ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist.");
+ ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
if (p_idx >= E->get().frames.size())
- return Ref<Texture>();
+ return Ref<Texture2D>();
return E->get().frames[p_idx];
}
- _FORCE_INLINE_ Ref<Texture> get_normal_frame(const StringName &p_anim, int p_idx) const {
+ _FORCE_INLINE_ Ref<Texture2D> get_normal_frame(const StringName &p_anim, int p_idx) const {
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
- ERR_FAIL_COND_V_MSG(!E, Ref<Texture>(), "Animation '" + String(p_anim) + "' doesn't exist.");
- ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>());
+ ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist.");
+ ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
const Map<StringName, Anim>::Element *EN = animations.find(E->get().normal_name);
if (!EN || p_idx >= EN->get().frames.size())
- return Ref<Texture>();
+ return Ref<Texture2D>();
+
+ return EN->get().frames[p_idx];
+ }
+
+ _FORCE_INLINE_ Ref<Texture2D> get_specular_frame(const StringName &p_anim, int p_idx) const {
+
+ const Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_V(!E, Ref<Texture2D>());
+ ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
+
+ const Map<StringName, Anim>::Element *EN = animations.find(E->get().specular_name);
+
+ if (!EN || p_idx >= EN->get().frames.size())
+ return Ref<Texture2D>();
return EN->get().frames[p_idx];
}
- void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture> &p_frame) {
+ void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture2D> &p_frame) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
ERR_FAIL_COND(p_idx < 0);
@@ -150,6 +168,9 @@ class AnimatedSprite : public Node2D {
bool _is_playing() const;
Rect2 _get_rect() const;
+ Color specular_color;
+ float shininess;
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -197,8 +218,11 @@ public:
void set_flip_v(bool p_flip);
bool is_flipped_v() const;
- void set_modulate(const Color &p_color);
- Color get_modulate() const;
+ void set_specular_color(const Color &p_color);
+ Color get_specular_color() const;
+
+ void set_shininess(float p_shininess);
+ float get_shininess() const;
virtual String get_configuration_warning() const;
AnimatedSprite();
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 8302ba5336..b661db2e52 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -148,7 +148,7 @@ void Area2D::_body_exit_tree(ObjectID p_id) {
}
}
-void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape) {
+void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) {
bool body_in = p_status == Physics2DServer::AREA_BODY_ADDED;
ObjectID objid = p_instance;
@@ -251,7 +251,7 @@ void Area2D::_area_exit_tree(ObjectID p_id) {
}
}
-void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape) {
+void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) {
bool area_in = p_status == Physics2DServer::AREA_BODY_ADDED;
ObjectID objid = p_instance;
diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h
index 6d9386c535..c5e6635412 100644
--- a/scene/2d/area_2d.h
+++ b/scene/2d/area_2d.h
@@ -62,7 +62,7 @@ private:
bool monitorable;
bool locked;
- void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape);
+ void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape);
void _body_enter_tree(ObjectID p_id);
void _body_exit_tree(ObjectID p_id);
@@ -94,7 +94,7 @@ private:
Map<ObjectID, BodyState> body_map;
- void _area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape);
+ void _area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape);
void _area_enter_tree(ObjectID p_id);
void _area_exit_tree(ObjectID p_id);
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index e9f8c5dff2..7ec770597e 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -608,7 +608,7 @@ void Camera2D::set_custom_viewport(Node *p_viewport) {
if (custom_viewport) {
custom_viewport_id = custom_viewport->get_instance_id();
} else {
- custom_viewport_id = 0;
+ custom_viewport_id = ObjectID();
}
if (is_inside_tree()) {
@@ -795,7 +795,7 @@ Camera2D::Camera2D() {
smoothing_enabled = false;
limit_smoothing_enabled = false;
custom_viewport = NULL;
- custom_viewport_id = 0;
+
process_mode = CAMERA2D_PROCESS_IDLE;
smoothing = 5.0;
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 5631aa3355..aca0c4c959 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -572,6 +572,9 @@ void CanvasItem::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
+ _update_texture_filter_changed(false);
+ _update_texture_repeat_changed(false);
+
first_draw = true;
if (get_parent()) {
CanvasItem *ci = Object::cast_to<CanvasItem>(get_parent());
@@ -717,30 +720,30 @@ void CanvasItem::item_rect_changed(bool p_size_changed) {
emit_signal(SceneStringNames::get_singleton()->item_rect_changed);
}
-void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width, bool p_antialiased) {
+void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
}
-void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) {
+void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
colors.push_back(p_color);
- VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, colors, p_width, p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, colors, p_width);
}
-void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
+void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width);
}
-void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width, bool p_antialiased) {
+void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width) {
Vector<Point2> points;
points.resize(p_point_count);
@@ -750,26 +753,26 @@ void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start
points.set(i, p_center + Vector2(Math::cos(theta), Math::sin(theta)) * p_radius);
}
- draw_polyline(points, p_color, p_width, p_antialiased);
+ draw_polyline(points, p_color, p_width);
}
-void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) {
+void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
colors.push_back(p_color);
- VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width, p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width);
}
-void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
+void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width);
}
-void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width, bool p_antialiased) {
+void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
@@ -778,10 +781,6 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
WARN_PRINT("The draw_rect() \"width\" argument has no effect when \"filled\" is \"true\".");
}
- if (p_antialiased) {
- WARN_PRINT("The draw_rect() \"antialiased\" argument has no effect when \"filled\" is \"true\".");
- }
-
VisualServer::get_singleton()->canvas_item_add_rect(canvas_item, p_rect, p_color);
} else {
// Thick lines are offset depending on their width to avoid partial overlapping.
@@ -798,29 +797,25 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
p_rect.position + Size2(-offset, 0),
p_rect.position + Size2(p_rect.size.width + offset, 0),
p_color,
- p_width,
- p_antialiased);
+ p_width);
VisualServer::get_singleton()->canvas_item_add_line(
canvas_item,
p_rect.position + Size2(p_rect.size.width, offset),
p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset),
p_color,
- p_width,
- p_antialiased);
+ p_width);
VisualServer::get_singleton()->canvas_item_add_line(
canvas_item,
p_rect.position + Size2(p_rect.size.width + offset, p_rect.size.height),
p_rect.position + Size2(-offset, p_rect.size.height),
p_color,
- p_width,
- p_antialiased);
+ p_width);
VisualServer::get_singleton()->canvas_item_add_line(
canvas_item,
p_rect.position + Size2(0, p_rect.size.height - offset),
p_rect.position + Size2(0, offset),
p_color,
- p_width,
- p_antialiased);
+ p_width);
}
}
@@ -831,27 +826,27 @@ void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p
VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
}
-void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture> &p_normal_map) {
+void CanvasItem::draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
- p_texture->draw(canvas_item, p_pos, p_modulate, false, p_normal_map);
+ p_texture->draw(canvas_item, p_pos, p_modulate, false, p_normal_map, p_specular_map, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat));
}
-void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) {
+void CanvasItem::draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
- p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map);
+ p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat));
}
-void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) {
+void CanvasItem::draw_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
- p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_clip_uv);
+ p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat), p_clip_uv);
}
void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) {
@@ -861,14 +856,15 @@ void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p
p_style_box->draw(canvas_item, p_rect);
}
-void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width, const Ref<Texture> &p_normal_map) {
+void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, float p_width, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ RID rid_specular = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width, rid_normal);
+ VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width, rid_normal, rid_specular, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat));
}
void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) {
@@ -886,17 +882,18 @@ void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) {
VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix);
}
-void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) {
+void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ RID rid_specular = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid, rid_normal, p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid, rid_normal, rid_specular, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat));
}
-void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) {
+void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
@@ -904,24 +901,28 @@ void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Colo
colors.push_back(p_color);
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ RID rid_specular = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, p_antialiased);
+ VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, rid_specular, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat));
}
-void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, const Transform2D &p_transform, const Color &p_modulate) {
+void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, const Transform2D &p_transform, const Color &p_modulate, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND(p_mesh.is_null());
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ RID specular_map_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), p_transform, p_modulate, texture_rid, normal_map_rid);
+ VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), p_transform, p_modulate, texture_rid, normal_map_rid, specular_map_rid, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat));
}
-void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) {
+void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND(p_multimesh.is_null());
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid, normal_map_rid);
+ RID specular_map_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+
+ VisualServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid, normal_map_rid, specular_map_rid, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat));
}
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) {
@@ -996,7 +997,7 @@ ObjectID CanvasItem::get_canvas_layer_instance_id() const {
if (canvas_layer) {
return canvas_layer->get_instance_id();
} else {
- return 0;
+ return ObjectID();
}
}
@@ -1170,25 +1171,25 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("_is_on_top"), &CanvasItem::_is_on_top);
//ClassDB::bind_method(D_METHOD("get_transform"),&CanvasItem::get_transform);
- ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width", "antialiased"), &CanvasItem::draw_arc, DEFVAL(1.0), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(1.0), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width"), &CanvasItem::draw_line, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width"), &CanvasItem::draw_polyline, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width"), &CanvasItem::draw_arc, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::draw_multiline, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle);
- ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose", "normal_map"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture", "rect", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map", "specular_map", "specular_shinness", "texture_filter", "texture_repeat"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
+ ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose", "normal_map", "specular_map", "specular_shinness", "texture_filter", "texture_repeat"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
+ ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture", "rect", "src_rect", "modulate", "transpose", "normal_map", "specular_map", "clip_uv", "specular_shinness", "texture_filter", "texture_repeat"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(true), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
ClassDB::bind_method(D_METHOD("draw_style_box", "style_box", "rect"), &CanvasItem::draw_style_box);
- ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width", "normal_map"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width", "normal_map", "specular_map", "specular_shinness", "texture_filter", "texture_repeat"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
+ ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture", "normal_map", "specular_map", "specular_shinness", "texture_filter", "texture_repeat"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
+ ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "specular_map", "specular_shinness", "texture_filter", "texture_repeat"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1)));
- ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()), DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1)));
- ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture>()));
+ ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "specular_map", "transform", "modulate", "specular_shinness", "texture_filter", "texture_repeat"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
+ ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map", "specular_map", "specular_shinness", "texture_filter", "texture_repeat"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform);
ClassDB::bind_method(D_METHOD("draw_set_transform_matrix", "xform"), &CanvasItem::draw_set_transform_matrix);
@@ -1221,6 +1222,12 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("make_canvas_position_local", "screen_point"), &CanvasItem::make_canvas_position_local);
ClassDB::bind_method(D_METHOD("make_input_local", "event"), &CanvasItem::make_input_local);
+ ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &CanvasItem::set_texture_filter);
+ ClassDB::bind_method(D_METHOD("get_texture_filter"), &CanvasItem::get_texture_filter);
+
+ ClassDB::bind_method(D_METHOD("set_texture_repeat", "mode"), &CanvasItem::set_texture_repeat);
+ ClassDB::bind_method(D_METHOD("get_texture_repeat"), &CanvasItem::get_texture_repeat);
+
BIND_VMETHOD(MethodInfo("_draw"));
ADD_GROUP("Visibility", "");
@@ -1231,6 +1238,10 @@ void CanvasItem::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_on_top", PROPERTY_HINT_NONE, "", 0), "_set_on_top", "_is_on_top"); //compatibility
ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_light_mask", "get_light_mask");
+ ADD_GROUP("Texture", "texture_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "ParentNode,Nearest,Linear,MipmapNearest,MipmapLinear,MipmapNearestAniso,MipmapLinearAniso"), "set_texture_filter", "get_texture_filter");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "ParentNode,Disabled,Enabled,Mirror"), "set_texture_repeat", "get_texture_repeat");
+
ADD_GROUP("Material", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material");
@@ -1243,18 +1254,26 @@ void CanvasItem::_bind_methods() {
ADD_SIGNAL(MethodInfo("hide"));
ADD_SIGNAL(MethodInfo("item_rect_changed"));
- BIND_ENUM_CONSTANT(BLEND_MODE_MIX);
- BIND_ENUM_CONSTANT(BLEND_MODE_ADD);
- BIND_ENUM_CONSTANT(BLEND_MODE_SUB);
- BIND_ENUM_CONSTANT(BLEND_MODE_MUL);
- BIND_ENUM_CONSTANT(BLEND_MODE_PREMULT_ALPHA);
- BIND_ENUM_CONSTANT(BLEND_MODE_DISABLED);
-
BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED);
BIND_CONSTANT(NOTIFICATION_DRAW);
BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
BIND_CONSTANT(NOTIFICATION_ENTER_CANVAS);
BIND_CONSTANT(NOTIFICATION_EXIT_CANVAS);
+
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_PARENT_NODE);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_REPEAT_PARENT_NODE);
+ BIND_ENUM_CONSTANT(TEXTURE_REPEAT_DISABLED);
+ BIND_ENUM_CONSTANT(TEXTURE_REPEAT_ENABLED);
+ BIND_ENUM_CONSTANT(TEXTURE_REPEAT_MIRROR);
+ BIND_ENUM_CONSTANT(TEXTURE_REPEAT_MAX);
}
Transform2D CanvasItem::get_canvas_transform() const {
@@ -1318,6 +1337,102 @@ int CanvasItem::get_canvas_layer() const {
return 0;
}
+void CanvasItem::_update_texture_filter_changed(bool p_propagate) {
+
+ if (!is_inside_tree()) {
+ return;
+ }
+
+ if (texture_filter == TEXTURE_FILTER_PARENT_NODE) {
+ CanvasItem *parent_item = get_parent_item();
+ if (parent_item) {
+ texture_filter_cache = parent_item->texture_filter_cache;
+ } else {
+ //from viewport
+ switch (get_viewport()->get_default_canvas_item_texture_filter()) {
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST: texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST; break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR: texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS: texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS; break;
+ default: {
+ }
+ }
+ }
+ } else {
+ texture_filter_cache = VS::CanvasItemTextureFilter(texture_filter);
+ }
+ VS::get_singleton()->canvas_item_set_default_texture_filter(get_canvas_item(), texture_filter_cache);
+ update();
+
+ if (p_propagate) {
+ for (List<CanvasItem *>::Element *E = children_items.front(); E; E = E->next()) {
+ if (!E->get()->toplevel && E->get()->texture_filter == TEXTURE_FILTER_PARENT_NODE) {
+ E->get()->_update_texture_filter_changed(true);
+ }
+ }
+ }
+}
+
+void CanvasItem::set_texture_filter(TextureFilter p_texture_filter) {
+ ERR_FAIL_INDEX(p_texture_filter, TEXTURE_FILTER_MAX);
+ if (texture_filter == p_texture_filter) {
+ return;
+ }
+ texture_filter = p_texture_filter;
+ _update_texture_filter_changed(true);
+}
+
+CanvasItem::TextureFilter CanvasItem::get_texture_filter() const {
+ return texture_filter;
+}
+
+void CanvasItem::_update_texture_repeat_changed(bool p_propagate) {
+
+ if (!is_inside_tree()) {
+ return;
+ }
+
+ if (texture_repeat == TEXTURE_REPEAT_PARENT_NODE) {
+ CanvasItem *parent_item = get_parent_item();
+ if (parent_item) {
+ texture_repeat_cache = parent_item->texture_repeat_cache;
+ } else {
+ //from viewport
+ switch (get_viewport()->get_default_canvas_item_texture_repeat()) {
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: texture_repeat_cache = VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED: texture_repeat_cache = VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED; break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR: texture_repeat_cache = VS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR; break;
+ default: {
+ }
+ }
+ }
+ } else {
+ texture_repeat_cache = VS::CanvasItemTextureRepeat(texture_repeat);
+ }
+ VS::get_singleton()->canvas_item_set_default_texture_repeat(get_canvas_item(), texture_repeat_cache);
+ update();
+ if (p_propagate) {
+ for (List<CanvasItem *>::Element *E = children_items.front(); E; E = E->next()) {
+ if (!E->get()->toplevel && E->get()->texture_repeat == TEXTURE_REPEAT_PARENT_NODE) {
+ E->get()->_update_texture_repeat_changed(true);
+ }
+ }
+ }
+}
+
+void CanvasItem::set_texture_repeat(TextureRepeat p_texture_repeat) {
+ ERR_FAIL_INDEX(p_texture_repeat, TEXTURE_REPEAT_MAX);
+ if (texture_repeat == p_texture_repeat) {
+ return;
+ }
+ texture_repeat = p_texture_repeat;
+ _update_texture_repeat_changed(true);
+}
+
+CanvasItem::TextureRepeat CanvasItem::get_texture_repeat() const {
+ return texture_repeat;
+}
+
CanvasItem::CanvasItem() :
xform_change(this) {
@@ -1338,6 +1453,10 @@ CanvasItem::CanvasItem() :
notify_local_transform = false;
notify_transform = false;
light_mask = 1;
+ texture_repeat = TEXTURE_REPEAT_PARENT_NODE;
+ texture_filter = TEXTURE_FILTER_PARENT_NODE;
+ texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
+ texture_repeat_cache = VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
C = NULL;
}
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 8814d99edd..1b0359f6ec 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -166,14 +166,23 @@ class CanvasItem : public Node {
GDCLASS(CanvasItem, Node);
public:
- enum BlendMode {
+ enum TextureFilter {
+ TEXTURE_FILTER_PARENT_NODE,
+ TEXTURE_FILTER_NEAREST,
+ TEXTURE_FILTER_LINEAR,
+ TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS,
+ TEXTURE_FILTER_LINEAR_WITH_MIPMAPS,
+ TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC,
+ TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC,
+ TEXTURE_FILTER_MAX
+ };
- BLEND_MODE_MIX, //default
- BLEND_MODE_ADD,
- BLEND_MODE_SUB,
- BLEND_MODE_MUL,
- BLEND_MODE_PREMULT_ALPHA,
- BLEND_MODE_DISABLED
+ enum TextureRepeat {
+ TEXTURE_REPEAT_PARENT_NODE,
+ TEXTURE_REPEAT_DISABLED,
+ TEXTURE_REPEAT_ENABLED,
+ TEXTURE_REPEAT_MIRROR,
+ TEXTURE_REPEAT_MAX,
};
private:
@@ -203,6 +212,12 @@ private:
bool notify_local_transform;
bool notify_transform;
+ VS::CanvasItemTextureFilter texture_filter_cache;
+ VS::CanvasItemTextureRepeat texture_repeat_cache;
+
+ TextureFilter texture_filter;
+ TextureRepeat texture_repeat;
+
Ref<Material> material;
mutable Transform2D global_transform;
@@ -223,6 +238,9 @@ private:
bool _is_on_top() const { return !is_draw_behind_parent_enabled(); }
static CanvasItem *current_item_drawn;
+ friend class Viewport;
+ void _update_texture_repeat_changed(bool p_propagate);
+ void _update_texture_filter_changed(bool p_propagate);
protected:
_FORCE_INLINE_ void _notify_transform() {
@@ -305,24 +323,24 @@ public:
/* DRAWING API */
- void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
- void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
- void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
- void draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
- void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
- void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
- void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0, bool p_antialiased = false);
+ void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0);
+ void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0);
+ void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0);
+ void draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width = 1.0);
+ void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0);
+ void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0);
+ void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0);
void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color);
- void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture> &p_normal_map = Ref<Texture>());
- void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>());
- void draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = false);
+ void draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE);
+ void draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE);
+ void draw_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), bool p_clip_uv = false, TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE);
void draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect);
- void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture = Ref<Texture>(), float p_width = 1, const Ref<Texture> &p_normal_map = Ref<Texture>());
- void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false);
- void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false);
+ void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture = Ref<Texture2D>(), float p_width = 1, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE);
+ void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture2D> p_texture = Ref<Texture2D>(), const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE);
+ void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture2D> p_texture = Ref<Texture2D>(), const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE);
- void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1));
- void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map);
+ void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE);
+ void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE);
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1);
float draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", const Color &p_modulate = Color(1, 1, 1));
@@ -383,6 +401,12 @@ public:
void force_update_transform();
+ void set_texture_filter(TextureFilter p_texture_filter);
+ TextureFilter get_texture_filter() const;
+
+ void set_texture_repeat(TextureRepeat p_texture_repeat);
+ TextureRepeat get_texture_repeat() const;
+
// Used by control nodes to retrieve the parent's anchorable area
virtual Rect2 get_anchorable_rect() const { return Rect2(0, 0, 0, 0); };
@@ -392,6 +416,7 @@ public:
~CanvasItem();
};
-VARIANT_ENUM_CAST(CanvasItem::BlendMode);
+VARIANT_ENUM_CAST(CanvasItem::TextureFilter)
+VARIANT_ENUM_CAST(CanvasItem::TextureRepeat)
#endif // CANVAS_ITEM_H
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 3e9e63a7f0..4af2e846f7 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -95,9 +95,9 @@ void CollisionObject2D::_notification(int p_what) {
case NOTIFICATION_EXIT_CANVAS: {
if (area)
- Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, 0);
+ Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, ObjectID());
else
- Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, 0);
+ Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, ObjectID());
} break;
}
}
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index eace4c64fc..bb975350a6 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -130,7 +130,7 @@ void CollisionShape2D::_notification(int p_what) {
draw_col = draw_col.darkened(0.25);
}
Vector2 line_to(0, 20);
- draw_line(Vector2(), line_to, draw_col, 2, true);
+ draw_line(Vector2(), line_to, draw_col, 2);
Vector<Vector2> pts;
float tsize = 8;
pts.push_back(line_to + (Vector2(0, tsize)));
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index f59e3461b1..449951bc6c 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "cpu_particles_2d.h"
-
+#include "core/core_string_names.h"
#include "scene/2d/canvas_item.h"
#include "scene/2d/particles_2d.h"
#include "scene/resources/particles_material.h"
@@ -58,8 +58,8 @@ void CPUParticles2D::set_amount(int p_amount) {
}
}
- particle_data.resize((8 + 4 + 1) * p_amount);
- VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_2D, VS::MULTIMESH_COLOR_8BIT, VS::MULTIMESH_CUSTOM_DATA_FLOAT);
+ particle_data.resize((8 + 4 + 4) * p_amount);
+ VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_2D, true, true);
particle_order.resize(p_amount);
}
@@ -169,10 +169,20 @@ void CPUParticles2D::_update_mesh_texture() {
vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, tex_size.y));
vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y));
PoolVector<Vector2> uvs;
- uvs.push_back(Vector2(0, 0));
- uvs.push_back(Vector2(1, 0));
- uvs.push_back(Vector2(1, 1));
- uvs.push_back(Vector2(0, 1));
+ AtlasTexture *atlas_texure = Object::cast_to<AtlasTexture>(*texture);
+ if (atlas_texure && atlas_texure->get_atlas().is_valid()) {
+ Rect2 region_rect = atlas_texure->get_region();
+ Size2 atlas_size = atlas_texure->get_atlas()->get_size();
+ uvs.push_back(Vector2(region_rect.position.x / atlas_size.x, region_rect.position.y / atlas_size.y));
+ uvs.push_back(Vector2((region_rect.position.x + region_rect.size.x) / atlas_size.x, region_rect.position.y / atlas_size.y));
+ uvs.push_back(Vector2((region_rect.position.x + region_rect.size.x) / atlas_size.x, (region_rect.position.y + region_rect.size.y) / atlas_size.y));
+ uvs.push_back(Vector2(region_rect.position.x / atlas_size.x, (region_rect.position.y + region_rect.size.y) / atlas_size.y));
+ } else {
+ uvs.push_back(Vector2(0, 0));
+ uvs.push_back(Vector2(1, 0));
+ uvs.push_back(Vector2(1, 1));
+ uvs.push_back(Vector2(0, 1));
+ }
PoolVector<Color> colors;
colors.push_back(Color(1, 1, 1, 1));
colors.push_back(Color(1, 1, 1, 1));
@@ -197,25 +207,42 @@ void CPUParticles2D::_update_mesh_texture() {
VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VS::PRIMITIVE_TRIANGLES, arr);
}
-void CPUParticles2D::set_texture(const Ref<Texture> &p_texture) {
+void CPUParticles2D::set_texture(const Ref<Texture2D> &p_texture) {
+ if (p_texture == texture)
+ return;
+
+ if (texture.is_valid())
+ texture->disconnect(CoreStringNames::get_singleton()->changed, this, "_texture_changed");
texture = p_texture;
+
+ if (texture.is_valid())
+ texture->connect(CoreStringNames::get_singleton()->changed, this, "_texture_changed");
+
update();
_update_mesh_texture();
}
-Ref<Texture> CPUParticles2D::get_texture() const {
+void CPUParticles2D::_texture_changed() {
+
+ if (texture.is_valid()) {
+ update();
+ _update_mesh_texture();
+ }
+}
+
+Ref<Texture2D> CPUParticles2D::get_texture() const {
return texture;
}
-void CPUParticles2D::set_normalmap(const Ref<Texture> &p_normalmap) {
+void CPUParticles2D::set_normalmap(const Ref<Texture2D> &p_normalmap) {
normalmap = p_normalmap;
update();
}
-Ref<Texture> CPUParticles2D::get_normalmap() const {
+Ref<Texture2D> CPUParticles2D::get_normalmap() const {
return normalmap;
}
@@ -998,18 +1025,18 @@ void CPUParticles2D::_update_particle_data_buffer() {
}
Color c = r[idx].color;
- uint8_t *data8 = (uint8_t *)&ptr[8];
- data8[0] = CLAMP(c.r * 255.0, 0, 255);
- data8[1] = CLAMP(c.g * 255.0, 0, 255);
- data8[2] = CLAMP(c.b * 255.0, 0, 255);
- data8[3] = CLAMP(c.a * 255.0, 0, 255);
-
- ptr[9] = r[idx].custom[0];
- ptr[10] = r[idx].custom[1];
- ptr[11] = r[idx].custom[2];
- ptr[12] = r[idx].custom[3];
-
- ptr += 13;
+
+ ptr[8] = c.r;
+ ptr[9] = c.g;
+ ptr[10] = c.b;
+ ptr[11] = c.a;
+
+ ptr[12] = r[idx].custom[0];
+ ptr[13] = r[idx].custom[1];
+ ptr[14] = r[idx].custom[2];
+ ptr[15] = r[idx].custom[3];
+
+ ptr += 16;
}
}
@@ -1050,7 +1077,7 @@ void CPUParticles2D::_update_render_thread() {
update_mutex->lock();
#endif
- VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
+ VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
#ifndef NO_THREADS
update_mutex->unlock();
@@ -1123,7 +1150,7 @@ void CPUParticles2D::_notification(int p_what) {
zeromem(ptr, sizeof(float) * 8);
}
- ptr += 13;
+ ptr += 16;
}
}
}
@@ -1259,8 +1286,8 @@ void CPUParticles2D::_bind_methods() {
// No visibility_rect property contrarily to Particles2D, it's updated automatically.
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates");
ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime"), "set_draw_order", "get_draw_order");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normalmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normalmap", "get_normalmap");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normalmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normalmap", "get_normalmap");
BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX);
BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
@@ -1315,6 +1342,7 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles);
ClassDB::bind_method(D_METHOD("_update_render_thread"), &CPUParticles2D::_update_render_thread);
+ ClassDB::bind_method(D_METHOD("_texture_changed"), &CPUParticles2D::_texture_changed);
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");
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 085ec99ea0..5eb563bbbc 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -147,8 +147,8 @@ private:
DrawOrder draw_order;
- Ref<Texture> texture;
- Ref<Texture> normalmap;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normalmap;
////////
@@ -186,6 +186,8 @@ private:
void _set_redraw(bool p_redraw);
+ void _texture_changed();
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -228,11 +230,11 @@ public:
void set_draw_passes(int p_count);
int get_draw_passes() const;
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
- void set_normalmap(const Ref<Texture> &p_normalmap);
- Ref<Texture> get_normalmap() const;
+ void set_normalmap(const Ref<Texture2D> &p_normalmap);
+ Ref<Texture2D> get_normalmap() const;
///////////////////
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 1bffaf8084..0b66d34ece 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -125,7 +125,7 @@ bool Light2D::is_editor_only() const {
return editor_only;
}
-void Light2D::set_texture(const Ref<Texture> &p_texture) {
+void Light2D::set_texture(const Ref<Texture2D> &p_texture) {
texture = p_texture;
if (texture.is_valid())
@@ -136,7 +136,7 @@ void Light2D::set_texture(const Ref<Texture> &p_texture) {
update_configuration_warning();
}
-Ref<Texture> Light2D::get_texture() const {
+Ref<Texture2D> Light2D::get_texture() const {
return texture;
}
@@ -296,18 +296,8 @@ int Light2D::get_shadow_buffer_size() const {
return shadow_buffer_size;
}
-void Light2D::set_shadow_gradient_length(float p_multiplier) {
-
- shadow_gradient_length = p_multiplier;
- VS::get_singleton()->canvas_light_set_shadow_gradient_length(canvas_light, p_multiplier);
-}
-
-float Light2D::get_shadow_gradient_length() const {
-
- return shadow_gradient_length;
-}
-
void Light2D::set_shadow_filter(ShadowFilter p_filter) {
+ ERR_FAIL_INDEX(p_filter, SHADOW_FILTER_MAX);
shadow_filter = p_filter;
VS::get_singleton()->canvas_light_set_shadow_filter(canvas_light, VS::CanvasLightShadowFilter(p_filter));
}
@@ -426,9 +416,6 @@ void Light2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_smooth", "smooth"), &Light2D::set_shadow_smooth);
ClassDB::bind_method(D_METHOD("get_shadow_smooth"), &Light2D::get_shadow_smooth);
- ClassDB::bind_method(D_METHOD("set_shadow_gradient_length", "multiplier"), &Light2D::set_shadow_gradient_length);
- ClassDB::bind_method(D_METHOD("get_shadow_gradient_length"), &Light2D::get_shadow_gradient_length);
-
ClassDB::bind_method(D_METHOD("set_shadow_filter", "filter"), &Light2D::set_shadow_filter);
ClassDB::bind_method(D_METHOD("get_shadow_filter"), &Light2D::get_shadow_filter);
@@ -437,7 +424,7 @@ void Light2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
@@ -455,8 +442,7 @@ void Light2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow_enabled", "is_shadow_enabled");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF7,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13"), "set_shadow_filter", "get_shadow_filter");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask");
@@ -466,10 +452,7 @@ void Light2D::_bind_methods() {
BIND_ENUM_CONSTANT(MODE_MASK);
BIND_ENUM_CONSTANT(SHADOW_FILTER_NONE);
- BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF3);
BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF5);
- BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF7);
- BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF9);
BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF13);
}
@@ -490,7 +473,6 @@ Light2D::Light2D() {
item_shadow_mask = 1;
mode = MODE_ADD;
shadow_buffer_size = 2048;
- shadow_gradient_length = 0;
energy = 1.0;
shadow_color = Color(0, 0, 0, 0);
shadow_filter = SHADOW_FILTER_NONE;
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index 65db5c6ee6..7134029441 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -47,11 +47,9 @@ public:
enum ShadowFilter {
SHADOW_FILTER_NONE,
- SHADOW_FILTER_PCF3,
SHADOW_FILTER_PCF5,
- SHADOW_FILTER_PCF7,
- SHADOW_FILTER_PCF9,
SHADOW_FILTER_PCF13,
+ SHADOW_FILTER_MAX
};
private:
@@ -72,9 +70,8 @@ private:
int item_shadow_mask;
int shadow_buffer_size;
float shadow_smooth;
- float shadow_gradient_length;
Mode mode;
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
Vector2 texture_offset;
ShadowFilter shadow_filter;
@@ -104,8 +101,8 @@ public:
void set_editor_only(bool p_editor_only);
bool is_editor_only() const;
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
void set_texture_offset(const Vector2 &p_offset);
Vector2 get_texture_offset() const;
@@ -149,9 +146,6 @@ public:
void set_shadow_buffer_size(int p_size);
int get_shadow_buffer_size() const;
- void set_shadow_gradient_length(float p_multiplier);
- float get_shadow_gradient_length() const;
-
void set_shadow_filter(ShadowFilter p_filter);
ShadowFilter get_shadow_filter() const;
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index c31840c8e1..92d06d6056 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -188,12 +188,12 @@ Ref<Gradient> Line2D::get_gradient() const {
return _gradient;
}
-void Line2D::set_texture(const Ref<Texture> &p_texture) {
+void Line2D::set_texture(const Ref<Texture2D> &p_texture) {
_texture = p_texture;
update();
}
-Ref<Texture> Line2D::get_texture() const {
+Ref<Texture2D> Line2D::get_texture() const {
return _texture;
}
@@ -317,8 +317,7 @@ void Line2D::_draw() {
lb.vertices,
lb.colors,
lb.uvs, Vector<int>(), Vector<float>(),
- texture_rid, -1, RID(),
- _antialiased, true);
+ texture_rid);
// DEBUG
// Draw wireframe
@@ -407,7 +406,7 @@ void Line2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_color"), "set_default_color", "get_default_color");
ADD_GROUP("Fill", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile,Stretch"), "set_texture_mode", "get_texture_mode");
ADD_GROUP("Capping", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode");
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index 3c7239f67c..b7e7f59403 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -89,8 +89,8 @@ public:
void set_gradient(const Ref<Gradient> &gradient);
Ref<Gradient> get_gradient() const;
- void set_texture(const Ref<Texture> &texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &texture);
+ Ref<Texture2D> get_texture() const;
void set_texture_mode(const LineTextureMode mode);
LineTextureMode get_texture_mode() const;
@@ -132,7 +132,7 @@ private:
Ref<Curve> _curve;
Color _default_color;
Ref<Gradient> _gradient;
- Ref<Texture> _texture;
+ Ref<Texture2D> _texture;
LineTextureMode _texture_mode;
float _sharp_limit;
int _round_precision;
diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp
index 93432ec40b..5e258be700 100644
--- a/scene/2d/mesh_instance_2d.cpp
+++ b/scene/2d/mesh_instance_2d.cpp
@@ -53,8 +53,8 @@ void MeshInstance2D::_bind_methods() {
ADD_SIGNAL(MethodInfo("texture_changed"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
}
void MeshInstance2D::set_mesh(const Ref<Mesh> &p_mesh) {
@@ -68,7 +68,7 @@ Ref<Mesh> MeshInstance2D::get_mesh() const {
return mesh;
}
-void MeshInstance2D::set_texture(const Ref<Texture> &p_texture) {
+void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
if (p_texture == texture)
return;
@@ -78,18 +78,18 @@ void MeshInstance2D::set_texture(const Ref<Texture> &p_texture) {
_change_notify("texture");
}
-void MeshInstance2D::set_normal_map(const Ref<Texture> &p_texture) {
+void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) {
normal_map = p_texture;
update();
}
-Ref<Texture> MeshInstance2D::get_normal_map() const {
+Ref<Texture2D> MeshInstance2D::get_normal_map() const {
return normal_map;
}
-Ref<Texture> MeshInstance2D::get_texture() const {
+Ref<Texture2D> MeshInstance2D::get_texture() const {
return texture;
}
diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h
index 51f75a3ead..3356f44e91 100644
--- a/scene/2d/mesh_instance_2d.h
+++ b/scene/2d/mesh_instance_2d.h
@@ -38,8 +38,8 @@ class MeshInstance2D : public Node2D {
Ref<Mesh> mesh;
- Ref<Texture> texture;
- Ref<Texture> normal_map;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
protected:
void _notification(int p_what);
@@ -53,11 +53,11 @@ public:
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
- void set_normal_map(const Ref<Texture> &p_texture);
- Ref<Texture> get_normal_map() const;
+ void set_normal_map(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_normal_map() const;
MeshInstance2D();
};
diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp
index 028459e778..6620027020 100644
--- a/scene/2d/multimesh_instance_2d.cpp
+++ b/scene/2d/multimesh_instance_2d.cpp
@@ -53,8 +53,8 @@ void MultiMeshInstance2D::_bind_methods() {
ADD_SIGNAL(MethodInfo("texture_changed"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multimesh", PROPERTY_HINT_RESOURCE_TYPE, "MultiMesh"), "set_multimesh", "get_multimesh");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
}
void MultiMeshInstance2D::set_multimesh(const Ref<MultiMesh> &p_multimesh) {
@@ -68,7 +68,7 @@ Ref<MultiMesh> MultiMeshInstance2D::get_multimesh() const {
return multimesh;
}
-void MultiMeshInstance2D::set_texture(const Ref<Texture> &p_texture) {
+void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
if (p_texture == texture)
return;
@@ -78,18 +78,18 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture> &p_texture) {
_change_notify("texture");
}
-Ref<Texture> MultiMeshInstance2D::get_texture() const {
+Ref<Texture2D> MultiMeshInstance2D::get_texture() const {
return texture;
}
-void MultiMeshInstance2D::set_normal_map(const Ref<Texture> &p_texture) {
+void MultiMeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) {
normal_map = p_texture;
update();
}
-Ref<Texture> MultiMeshInstance2D::get_normal_map() const {
+Ref<Texture2D> MultiMeshInstance2D::get_normal_map() const {
return normal_map;
}
diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h
index c3f3e52920..a843606ebf 100644
--- a/scene/2d/multimesh_instance_2d.h
+++ b/scene/2d/multimesh_instance_2d.h
@@ -39,8 +39,8 @@ class MultiMeshInstance2D : public Node2D {
Ref<MultiMesh> multimesh;
- Ref<Texture> texture;
- Ref<Texture> normal_map;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
protected:
void _notification(int p_what);
@@ -54,11 +54,11 @@ public:
void set_multimesh(const Ref<MultiMesh> &p_multimesh);
Ref<MultiMesh> get_multimesh() const;
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
- void set_normal_map(const Ref<Texture> &p_texture);
- Ref<Texture> get_normal_map() const;
+ void set_normal_map(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_normal_map() const;
MultiMeshInstance2D();
~MultiMeshInstance2D();
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
index 9209cc5074..de01d97ad9 100644
--- a/scene/2d/navigation_2d.cpp
+++ b/scene/2d/navigation_2d.cpp
@@ -29,710 +29,52 @@
/*************************************************************************/
#include "navigation_2d.h"
+#include "servers/navigation_2d_server.h"
-#define USE_ENTRY_POINT
-
-void Navigation2D::_navpoly_link(int p_id) {
-
- ERR_FAIL_COND(!navpoly_map.has(p_id));
- NavMesh &nm = navpoly_map[p_id];
- ERR_FAIL_COND(nm.linked);
-
- PoolVector<Vector2> vertices = nm.navpoly->get_vertices();
- int len = vertices.size();
- if (len == 0)
- return;
-
- PoolVector<Vector2>::Read r = vertices.read();
-
- for (int i = 0; i < nm.navpoly->get_polygon_count(); i++) {
-
- //build
-
- List<Polygon>::Element *P = nm.polygons.push_back(Polygon());
- Polygon &p = P->get();
- p.owner = &nm;
-
- Vector<int> poly = nm.navpoly->get_polygon(i);
- int plen = poly.size();
- const int *indices = poly.ptr();
- bool valid = true;
- p.edges.resize(plen);
-
- Vector2 center;
- float sum = 0;
-
- for (int j = 0; j < plen; j++) {
-
- int idx = indices[j];
- if (idx < 0 || idx >= len) {
- valid = false;
- break;
- }
-
- Polygon::Edge e;
- Vector2 ep = nm.xform.xform(r[idx]);
- center += ep;
- e.point = _get_point(ep);
- p.edges.write[j] = e;
-
- int idxn = indices[(j + 1) % plen];
- if (idxn < 0 || idxn >= len) {
- valid = false;
- break;
- }
-
- Vector2 epn = nm.xform.xform(r[idxn]);
-
- sum += (epn.x - ep.x) * (epn.y + ep.y);
- }
-
- p.clockwise = sum > 0;
-
- if (!valid) {
- nm.polygons.pop_back();
- ERR_CONTINUE(!valid);
- }
-
- p.center = center / plen;
-
- //connect
-
- for (int j = 0; j < plen; j++) {
-
- int next = (j + 1) % plen;
- EdgeKey ek(p.edges[j].point, p.edges[next].point);
-
- Map<EdgeKey, Connection>::Element *C = connections.find(ek);
- if (!C) {
+void Navigation2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_rid"), &Navigation2D::get_rid);
- Connection c;
- c.A = &p;
- c.A_edge = j;
- c.B = NULL;
- c.B_edge = -1;
- connections[ek] = c;
- } else {
+ ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true));
- if (C->get().B != NULL) {
- ConnectionPending pending;
- pending.polygon = &p;
- pending.edge = j;
- p.edges.write[j].P = C->get().pending.push_back(pending);
- continue;
- }
+ ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation2D::set_cell_size);
+ ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation2D::get_cell_size);
- C->get().B = &p;
- C->get().B_edge = j;
- C->get().A->edges.write[C->get().A_edge].C = &p;
- C->get().A->edges.write[C->get().A_edge].C_edge = j;
- p.edges.write[j].C = C->get().A;
- p.edges.write[j].C_edge = C->get().A_edge;
- //connection successful.
- }
- }
- }
+ ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation2D::set_edge_connection_margin);
+ ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation2D::get_edge_connection_margin);
- nm.linked = true;
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size"), "set_cell_size", "get_cell_size");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
}
-void Navigation2D::_navpoly_unlink(int p_id) {
-
- ERR_FAIL_COND(!navpoly_map.has(p_id));
- NavMesh &nm = navpoly_map[p_id];
- ERR_FAIL_COND(!nm.linked);
-
- for (List<Polygon>::Element *E = nm.polygons.front(); E; E = E->next()) {
-
- Polygon &p = E->get();
-
- int ec = p.edges.size();
- Polygon::Edge *edges = p.edges.ptrw();
-
- for (int i = 0; i < ec; i++) {
- int next = (i + 1) % ec;
-
- EdgeKey ek(edges[i].point, edges[next].point);
- Map<EdgeKey, Connection>::Element *C = connections.find(ek);
- ERR_CONTINUE(!C);
-
- if (edges[i].P) {
- C->get().pending.erase(edges[i].P);
- edges[i].P = NULL;
-
- } else if (C->get().B) {
- //disconnect
+void Navigation2D::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ Navigation2DServer::get_singleton()->map_set_active(map, true);
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
- C->get().B->edges.write[C->get().B_edge].C = NULL;
- C->get().B->edges.write[C->get().B_edge].C_edge = -1;
- C->get().A->edges.write[C->get().A_edge].C = NULL;
- C->get().A->edges.write[C->get().A_edge].C_edge = -1;
-
- if (C->get().A == &E->get()) {
-
- C->get().A = C->get().B;
- C->get().A_edge = C->get().B_edge;
- }
- C->get().B = NULL;
- C->get().B_edge = -1;
-
- if (C->get().pending.size()) {
- //reconnect if something is pending
- ConnectionPending cp = C->get().pending.front()->get();
- C->get().pending.pop_front();
-
- C->get().B = cp.polygon;
- C->get().B_edge = cp.edge;
- C->get().A->edges.write[C->get().A_edge].C = cp.polygon;
- C->get().A->edges.write[C->get().A_edge].C_edge = cp.edge;
- cp.polygon->edges.write[cp.edge].C = C->get().A;
- cp.polygon->edges.write[cp.edge].C_edge = C->get().A_edge;
- cp.polygon->edges.write[cp.edge].P = NULL;
- }
-
- } else {
- connections.erase(C);
- //erase
- }
- }
+ Navigation2DServer::get_singleton()->map_set_active(map, false);
+ } break;
}
-
- nm.polygons.clear();
-
- nm.linked = false;
-}
-
-int Navigation2D::navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner) {
-
- int id = last_id++;
- NavMesh nm;
- nm.linked = false;
- nm.navpoly = p_mesh;
- nm.xform = p_xform;
- nm.owner = p_owner;
- navpoly_map[id] = nm;
-
- _navpoly_link(id);
-
- return id;
}
-void Navigation2D::navpoly_set_transform(int p_id, const Transform2D &p_xform) {
-
- ERR_FAIL_COND(!navpoly_map.has(p_id));
- NavMesh &nm = navpoly_map[p_id];
- if (nm.xform == p_xform)
- return; //bleh
- _navpoly_unlink(p_id);
- nm.xform = p_xform;
- _navpoly_link(p_id);
+void Navigation2D::set_cell_size(float p_cell_size) {
+ cell_size = p_cell_size;
+ Navigation2DServer::get_singleton()->map_set_cell_size(map, cell_size);
}
-void Navigation2D::navpoly_remove(int p_id) {
- ERR_FAIL_COND(!navpoly_map.has(p_id));
- _navpoly_unlink(p_id);
- navpoly_map.erase(p_id);
+void Navigation2D::set_edge_connection_margin(float p_edge_connection_margin) {
+ edge_connection_margin = p_edge_connection_margin;
+ Navigation2DServer::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
}
Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) {
-
- Polygon *begin_poly = NULL;
- Polygon *end_poly = NULL;
- Vector2 begin_point;
- Vector2 end_point;
- float begin_d = 1e20;
- float end_d = 1e20;
-
- //look for point inside triangle
-
- for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- if (begin_d || end_d) {
- for (int i = 2; i < p.edges.size(); i++) {
-
- if (begin_d > 0) {
-
- if (Geometry::is_point_in_triangle(p_start, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) {
-
- begin_poly = &p;
- begin_point = p_start;
- begin_d = 0;
- if (end_d == 0)
- break;
- }
- }
-
- if (end_d > 0) {
-
- if (Geometry::is_point_in_triangle(p_end, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) {
-
- end_poly = &p;
- end_point = p_end;
- end_d = 0;
- if (begin_d == 0)
- break;
- }
- }
- }
- }
-
- p.prev_edge = -1;
- }
- }
-
- //start or end not inside triangle.. look for closest segment :|
- if (begin_d || end_d) {
- for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- int es = p.edges.size();
- for (int i = 0; i < es; i++) {
-
- Vector2 edge[2] = {
- _get_vertex(p.edges[i].point),
- _get_vertex(p.edges[(i + 1) % es].point)
- };
-
- if (begin_d > 0) {
- Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_start, edge);
- float d = spoint.distance_to(p_start);
- if (d < begin_d) {
- begin_poly = &p;
- begin_point = spoint;
- begin_d = d;
- }
- }
-
- if (end_d > 0) {
- Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_end, edge);
- float d = spoint.distance_to(p_end);
- if (d < end_d) {
- end_poly = &p;
- end_point = spoint;
- end_d = d;
- }
- }
- }
- }
- }
- }
-
- if (!begin_poly || !end_poly) {
-
- return Vector<Vector2>(); //no path
- }
-
- if (begin_poly == end_poly) {
-
- Vector<Vector2> path;
- path.resize(2);
- path.write[0] = begin_point;
- path.write[1] = end_point;
- return path;
- }
-
- bool found_route = false;
-
- List<Polygon *> open_list;
-
- begin_poly->entry = p_start;
-
- for (int i = 0; i < begin_poly->edges.size(); i++) {
-
- if (begin_poly->edges[i].C) {
-
- begin_poly->edges[i].C->prev_edge = begin_poly->edges[i].C_edge;
-#ifdef USE_ENTRY_POINT
- Vector2 edge[2] = {
- _get_vertex(begin_poly->edges[i].point),
- _get_vertex(begin_poly->edges[(i + 1) % begin_poly->edges.size()].point)
- };
-
- Vector2 entry = Geometry::get_closest_point_to_segment_2d(begin_poly->entry, edge);
- begin_poly->edges[i].C->distance = begin_poly->entry.distance_to(entry);
- begin_poly->edges[i].C->entry = entry;
-#else
- begin_poly->edges[i].C->distance = begin_poly->center.distance_to(begin_poly->edges[i].C->center);
-#endif
- open_list.push_back(begin_poly->edges[i].C);
-
- if (begin_poly->edges[i].C == end_poly) {
- found_route = true;
- }
- }
- }
-
- while (!found_route) {
-
- if (open_list.size() == 0) {
- break;
- }
- //check open list
-
- List<Polygon *>::Element *least_cost_poly = NULL;
- float least_cost = 1e30;
-
- //this could be faster (cache previous results)
- for (List<Polygon *>::Element *E = open_list.front(); E; E = E->next()) {
-
- Polygon *p = E->get();
-
- float cost = p->distance;
-
-#ifdef USE_ENTRY_POINT
- int es = p->edges.size();
-
- float shortest_distance = 1e30;
-
- for (int i = 0; i < es; i++) {
- Polygon::Edge &e = p->edges.write[i];
-
- if (!e.C)
- continue;
-
- Vector2 edge[2] = {
- _get_vertex(p->edges[i].point),
- _get_vertex(p->edges[(i + 1) % es].point)
- };
-
- Vector2 edge_point = Geometry::get_closest_point_to_segment_2d(p->entry, edge);
- float dist = p->entry.distance_to(edge_point);
- if (dist < shortest_distance)
- shortest_distance = dist;
- }
-
- cost += shortest_distance;
-#else
- cost += p->center.distance_to(end_point);
-#endif
- if (cost < least_cost) {
- least_cost_poly = E;
- least_cost = cost;
- }
- }
-
- Polygon *p = least_cost_poly->get();
- //open the neighbours for search
- int es = p->edges.size();
-
- for (int i = 0; i < es; i++) {
-
- Polygon::Edge &e = p->edges.write[i];
-
- if (!e.C)
- continue;
-
-#ifdef USE_ENTRY_POINT
- Vector2 edge[2] = {
- _get_vertex(p->edges[i].point),
- _get_vertex(p->edges[(i + 1) % es].point)
- };
-
- Vector2 edge_entry = Geometry::get_closest_point_to_segment_2d(p->entry, edge);
- float distance = p->entry.distance_to(edge_entry) + p->distance;
-
-#else
-
- float distance = p->center.distance_to(e.C->center) + p->distance;
-
-#endif
-
- if (e.C->prev_edge != -1) {
- //oh this was visited already, can we win the cost?
-
- if (e.C->distance > distance) {
-
- e.C->prev_edge = e.C_edge;
- e.C->distance = distance;
-#ifdef USE_ENTRY_POINT
- e.C->entry = edge_entry;
-#endif
- }
- } else {
- //add to open neighbours
-
- e.C->prev_edge = e.C_edge;
- e.C->distance = distance;
-#ifdef USE_ENTRY_POINT
- e.C->entry = edge_entry;
-#endif
-
- open_list.push_back(e.C);
-
- if (e.C == end_poly) {
- //oh my reached end! stop algorithm
- found_route = true;
- break;
- }
- }
- }
-
- if (found_route)
- break;
-
- open_list.erase(least_cost_poly);
- }
-
- if (found_route) {
-
- Vector<Vector2> path;
-
- if (p_optimize) {
- //string pulling
-
- Vector2 apex_point = end_point;
- Vector2 portal_left = apex_point;
- Vector2 portal_right = apex_point;
- Polygon *left_poly = end_poly;
- Polygon *right_poly = end_poly;
- Polygon *p = end_poly;
-
- while (p) {
-
- Vector2 left;
- Vector2 right;
-
-//#define CLOCK_TANGENT(m_a,m_b,m_c) ( ((m_a)-(m_c)).cross((m_a)-(m_b)) )
-#define CLOCK_TANGENT(m_a, m_b, m_c) ((((m_a).x - (m_c).x) * ((m_b).y - (m_c).y) - ((m_b).x - (m_c).x) * ((m_a).y - (m_c).y)))
-
- if (p == begin_poly) {
- left = begin_point;
- right = begin_point;
- } else {
- int prev = p->prev_edge;
- int prev_n = (p->prev_edge + 1) % p->edges.size();
- left = _get_vertex(p->edges[prev].point);
- right = _get_vertex(p->edges[prev_n].point);
-
- if (p->clockwise) {
- SWAP(left, right);
- }
- /*if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){
- SWAP(left,right);
- }*/
- }
-
- bool skip = false;
-
- /*
- print_line("-----\nAPEX: "+(apex_point-end_point));
- print_line("LEFT:");
- print_line("\tPortal: "+(portal_left-end_point));
- print_line("\tPoint: "+(left-end_point));
- print_line("\tLeft Tangent: "+rtos(CLOCK_TANGENT(apex_point,portal_left,left)));
- print_line("\tLeft Distance: "+rtos(portal_left.distance_squared_to(apex_point)));
- print_line("\tLeft Test: "+rtos(CLOCK_TANGENT(apex_point,left,portal_right)));
- print_line("RIGHT:");
- print_line("\tPortal: "+(portal_right-end_point));
- print_line("\tPoint: "+(right-end_point));
- print_line("\tRight Tangent: "+rtos(CLOCK_TANGENT(apex_point,portal_right,right)));
- print_line("\tRight Distance: "+rtos(portal_right.distance_squared_to(apex_point)));
- print_line("\tRight Test: "+rtos(CLOCK_TANGENT(apex_point,right,portal_left)));
- */
-
- if (CLOCK_TANGENT(apex_point, portal_left, left) >= 0) {
- //process
- if (portal_left.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) {
- left_poly = p;
- portal_left = left;
- } else {
-
- apex_point = portal_right;
- p = right_poly;
- left_poly = p;
- portal_left = apex_point;
- portal_right = apex_point;
- if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point))
- path.push_back(apex_point);
- skip = true;
- }
- }
-
- if (!skip && CLOCK_TANGENT(apex_point, portal_right, right) <= 0) {
- //process
- if (portal_right.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) {
- right_poly = p;
- portal_right = right;
- } else {
-
- apex_point = portal_left;
- p = left_poly;
- right_poly = p;
- portal_right = apex_point;
- portal_left = apex_point;
- if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point))
- path.push_back(apex_point);
- }
- }
-
- if (p != begin_poly)
- p = p->edges[p->prev_edge].C;
- else
- p = NULL;
- }
-
- } else {
- //midpoints
- Polygon *p = end_poly;
-
- while (true) {
- int prev = p->prev_edge;
- int prev_n = (p->prev_edge + 1) % p->edges.size();
- Vector2 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point)) * 0.5;
- path.push_back(point);
- p = p->edges[prev].C;
- if (p == begin_poly)
- break;
- }
- }
-
- if (!path.size() || !path[path.size() - 1].is_equal_approx(begin_point)) {
- path.push_back(begin_point); // Add the begin point
- } else {
- path.write[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point
- }
-
- path.invert();
-
- if (path.size() <= 1 || !path[path.size() - 1].is_equal_approx(end_point)) {
- path.push_back(end_point); // Add the end point
- } else {
- path.write[path.size() - 1] = end_point; // Replace last midpoint by the exact end point
- }
-
- return path;
- }
-
- return Vector<Vector2>();
-}
-
-Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) {
-
- Vector2 closest_point = Vector2();
- float closest_point_d = 1e20;
-
- for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- for (int i = 2; i < p.edges.size(); i++) {
-
- if (Geometry::is_point_in_triangle(p_point, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) {
-
- return p_point; //inside triangle, nothing else to discuss
- }
- }
- }
- }
-
- for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- int es = p.edges.size();
- for (int i = 0; i < es; i++) {
-
- Vector2 edge[2] = {
- _get_vertex(p.edges[i].point),
- _get_vertex(p.edges[(i + 1) % es].point)
- };
-
- Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_point, edge);
- float d = spoint.distance_squared_to(p_point);
- if (d < closest_point_d) {
-
- closest_point = spoint;
- closest_point_d = d;
- }
- }
- }
- }
-
- return closest_point;
-}
-
-Object *Navigation2D::get_closest_point_owner(const Vector2 &p_point) {
-
- Object *owner = NULL;
- Vector2 closest_point = Vector2();
- float closest_point_d = 1e20;
-
- for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- for (int i = 2; i < p.edges.size(); i++) {
-
- if (Geometry::is_point_in_triangle(p_point, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) {
-
- return E->get().owner;
- }
- }
- }
- }
-
- for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- int es = p.edges.size();
- for (int i = 0; i < es; i++) {
-
- Vector2 edge[2] = {
- _get_vertex(p.edges[i].point),
- _get_vertex(p.edges[(i + 1) % es].point)
- };
-
- Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_point, edge);
- float d = spoint.distance_squared_to(p_point);
- if (d < closest_point_d) {
-
- closest_point = spoint;
- closest_point_d = d;
- owner = E->get().owner;
- }
- }
- }
- }
-
- return owner;
-}
-
-void Navigation2D::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("navpoly_add", "mesh", "xform", "owner"), &Navigation2D::navpoly_add, DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("navpoly_set_transform", "id", "xform"), &Navigation2D::navpoly_set_transform);
- ClassDB::bind_method(D_METHOD("navpoly_remove", "id"), &Navigation2D::navpoly_remove);
-
- ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point);
- ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner);
+ return Navigation2DServer::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
}
Navigation2D::Navigation2D() {
- ERR_FAIL_COND(sizeof(Point) != 8);
- cell_size = 1; // one pixel
- last_id = 1;
+ map = Navigation2DServer::get_singleton()->map_create();
+ set_cell_size(10); // Ten pixels
+ set_edge_connection_margin(100);
}
diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h
index 41b9aea35a..08642a5489 100644
--- a/scene/2d/navigation_2d.h
+++ b/scene/2d/navigation_2d.h
@@ -38,135 +38,30 @@ class Navigation2D : public Node2D {
GDCLASS(Navigation2D, Node2D);
- union Point {
+ RID map;
+ real_t cell_size;
+ real_t edge_connection_margin;
- struct {
- int64_t x : 32;
- int64_t y : 32;
- };
-
- uint64_t key;
- bool operator<(const Point &p_key) const { return key < p_key.key; }
- };
-
- struct EdgeKey {
-
- Point a;
- Point b;
-
- bool operator<(const EdgeKey &p_key) const {
- return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key);
- };
-
- EdgeKey(const Point &p_a = Point(), const Point &p_b = Point()) :
- a(p_a),
- b(p_b) {
- if (a.key > b.key) {
- SWAP(a, b);
- }
- }
- };
-
- struct NavMesh;
- struct Polygon;
-
- struct ConnectionPending {
-
- Polygon *polygon;
- int edge;
- };
-
- struct Polygon {
-
- struct Edge {
- Point point;
- Polygon *C; //connection
- int C_edge;
- List<ConnectionPending>::Element *P;
- Edge() {
- C = NULL;
- C_edge = -1;
- P = NULL;
- }
- };
-
- Vector<Edge> edges;
-
- Vector2 center;
- Vector2 entry;
-
- float distance;
- int prev_edge;
-
- bool clockwise;
-
- NavMesh *owner;
- };
-
- struct Connection {
-
- Polygon *A;
- int A_edge;
- Polygon *B;
- int B_edge;
-
- List<ConnectionPending> pending;
-
- Connection() {
- A = NULL;
- B = NULL;
- A_edge = -1;
- B_edge = -1;
- }
- };
-
- Map<EdgeKey, Connection> connections;
-
- struct NavMesh {
-
- Object *owner;
- Transform2D xform;
- bool linked;
- Ref<NavigationPolygon> navpoly;
- List<Polygon> polygons;
- };
-
- _FORCE_INLINE_ Point _get_point(const Vector2 &p_pos) const {
-
- int x = int(Math::floor(p_pos.x / cell_size));
- int y = int(Math::floor(p_pos.y / cell_size));
+protected:
+ static void _bind_methods();
+ void _notification(int p_what);
- Point p;
- p.key = 0;
- p.x = x;
- p.y = y;
- return p;
+public:
+ RID get_rid() const {
+ return map;
}
- _FORCE_INLINE_ Vector2 _get_vertex(const Point &p_point) const {
-
- return Vector2(p_point.x, p_point.y) * cell_size;
+ void set_cell_size(float p_cell_size);
+ float get_cell_size() const {
+ return cell_size;
}
- void _navpoly_link(int p_id);
- void _navpoly_unlink(int p_id);
-
- float cell_size;
- Map<int, NavMesh> navpoly_map;
- int last_id;
-
-protected:
- static void _bind_methods();
-
-public:
- //API should be as dynamic as possible
- int navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner = NULL);
- void navpoly_set_transform(int p_id, const Transform2D &p_xform);
- void navpoly_remove(int p_id);
+ void set_edge_connection_margin(float p_edge_connection_margin);
+ float get_edge_connection_margin() const {
+ return edge_connection_margin;
+ }
Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true);
- Vector2 get_closest_point(const Vector2 &p_point);
- Object *get_closest_point_owner(const Vector2 &p_point);
Navigation2D();
};
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
new file mode 100644
index 0000000000..d019d72bc9
--- /dev/null
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -0,0 +1,341 @@
+/*************************************************************************/
+/* navigation_agent_2d.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "navigation_agent_2d.h"
+
+#include "core/engine.h"
+#include "scene/2d/navigation_2d.h"
+#include "servers/navigation_2d_server.h"
+
+void NavigationAgent2D::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance);
+ ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance);
+
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent2D::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent2D::get_radius);
+
+ ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent2D::set_navigation_node);
+ ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent2D::get_navigation_node);
+
+ ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent2D::set_neighbor_dist);
+ ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent2D::get_neighbor_dist);
+
+ ClassDB::bind_method(D_METHOD("set_max_neighbors", "max_neighbors"), &NavigationAgent2D::set_max_neighbors);
+ ClassDB::bind_method(D_METHOD("get_max_neighbors"), &NavigationAgent2D::get_max_neighbors);
+
+ ClassDB::bind_method(D_METHOD("set_time_horizon", "time_horizon"), &NavigationAgent2D::set_time_horizon);
+ ClassDB::bind_method(D_METHOD("get_time_horizon"), &NavigationAgent2D::get_time_horizon);
+
+ ClassDB::bind_method(D_METHOD("set_max_speed", "max_speed"), &NavigationAgent2D::set_max_speed);
+ ClassDB::bind_method(D_METHOD("get_max_speed"), &NavigationAgent2D::get_max_speed);
+
+ ClassDB::bind_method(D_METHOD("set_path_max_distance", "max_speed"), &NavigationAgent2D::set_path_max_distance);
+ ClassDB::bind_method(D_METHOD("get_path_max_distance"), &NavigationAgent2D::get_path_max_distance);
+
+ ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent2D::set_target_location);
+ ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent2D::get_target_location);
+ ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent2D::get_next_location);
+ ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent2D::distance_to_target);
+ ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent2D::set_velocity);
+ ClassDB::bind_method(D_METHOD("get_nav_path"), &NavigationAgent2D::get_nav_path);
+ ClassDB::bind_method(D_METHOD("get_nav_path_index"), &NavigationAgent2D::get_nav_path_index);
+ ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent2D::is_target_reached);
+ ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent2D::is_target_reachable);
+ ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent2D::is_navigation_finished);
+ ClassDB::bind_method(D_METHOD("get_final_location"), &NavigationAgent2D::get_final_location);
+
+ ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent2D::_avoidance_done);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01"), "set_target_desired_distance", "get_target_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "neighbor_dist", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_neighbor_dist", "get_neighbor_dist");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_time_horizon", "get_time_horizon");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_max_speed", "get_max_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1"), "set_path_max_distance", "get_path_max_distance");
+
+ ADD_SIGNAL(MethodInfo("path_changed"));
+ ADD_SIGNAL(MethodInfo("target_reached"));
+ ADD_SIGNAL(MethodInfo("navigation_finished"));
+ ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity")));
+}
+
+void NavigationAgent2D::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+
+ agent_parent = Object::cast_to<Node2D>(get_parent());
+
+ Navigation2DServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+
+ // Search the navigation node and set it
+ {
+ Navigation2D *nav = NULL;
+ Node *p = get_parent();
+ while (p != NULL) {
+ nav = Object::cast_to<Navigation2D>(p);
+ if (nav != NULL)
+ p = NULL;
+ else
+ p = p->get_parent();
+ }
+
+ set_navigation(nav);
+ }
+
+ set_physics_process_internal(true);
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ agent_parent = NULL;
+ set_navigation(NULL);
+ set_physics_process_internal(false);
+ } break;
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ if (agent_parent) {
+
+ Navigation2DServer::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().get_origin());
+ if (!target_reached) {
+ if (distance_to_target() < target_desired_distance) {
+ emit_signal("target_reached");
+ target_reached = true;
+ }
+ }
+ }
+ } break;
+ }
+}
+
+NavigationAgent2D::NavigationAgent2D() :
+ agent_parent(NULL),
+ navigation(NULL),
+ agent(RID()),
+ target_desired_distance(1.0),
+ path_max_distance(3.0),
+ velocity_submitted(false),
+ target_reached(false),
+ navigation_finished(true) {
+ agent = Navigation2DServer::get_singleton()->agent_create();
+ set_neighbor_dist(500.0);
+ set_max_neighbors(10);
+ set_time_horizon(20.0);
+ set_radius(10.0);
+ set_max_speed(200.0);
+}
+
+NavigationAgent2D::~NavigationAgent2D() {
+ Navigation2DServer::get_singleton()->free(agent);
+ agent = RID(); // Pointless
+}
+
+void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
+ if (navigation == p_nav)
+ return; // Pointless
+
+ navigation = p_nav;
+ Navigation2DServer::get_singleton()->agent_set_map(agent, navigation == NULL ? RID() : navigation->get_rid());
+}
+
+void NavigationAgent2D::set_navigation_node(Node *p_nav) {
+ Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
+ ERR_FAIL_COND(nav == NULL);
+ set_navigation(nav);
+}
+
+Node *NavigationAgent2D::get_navigation_node() const {
+ return Object::cast_to<Node>(navigation);
+}
+
+void NavigationAgent2D::set_target_desired_distance(real_t p_dd) {
+ target_desired_distance = p_dd;
+}
+
+void NavigationAgent2D::set_radius(real_t p_radius) {
+ radius = p_radius;
+ Navigation2DServer::get_singleton()->agent_set_radius(agent, radius);
+}
+
+void NavigationAgent2D::set_neighbor_dist(real_t p_dist) {
+ neighbor_dist = p_dist;
+ Navigation2DServer::get_singleton()->agent_set_neighbor_dist(agent, neighbor_dist);
+}
+
+void NavigationAgent2D::set_max_neighbors(int p_count) {
+ max_neighbors = p_count;
+ Navigation2DServer::get_singleton()->agent_set_max_neighbors(agent, max_neighbors);
+}
+
+void NavigationAgent2D::set_time_horizon(real_t p_time) {
+ time_horizon = p_time;
+ Navigation2DServer::get_singleton()->agent_set_time_horizon(agent, time_horizon);
+}
+
+void NavigationAgent2D::set_max_speed(real_t p_max_speed) {
+ max_speed = p_max_speed;
+ Navigation2DServer::get_singleton()->agent_set_max_speed(agent, max_speed);
+}
+
+void NavigationAgent2D::set_path_max_distance(real_t p_pmd) {
+ path_max_distance = p_pmd;
+}
+
+real_t NavigationAgent2D::get_path_max_distance() {
+ return path_max_distance;
+}
+
+void NavigationAgent2D::set_target_location(Vector2 p_location) {
+ target_location = p_location;
+ navigation_path.clear();
+ target_reached = false;
+ navigation_finished = false;
+}
+
+Vector2 NavigationAgent2D::get_target_location() const {
+ return target_location;
+}
+
+Vector2 NavigationAgent2D::get_next_location() {
+ update_navigation();
+ if (navigation_path.size() == 0) {
+ ERR_FAIL_COND_V(agent_parent == NULL, Vector2());
+ return agent_parent->get_global_transform().get_origin();
+ } else {
+ return navigation_path[nav_path_index];
+ }
+}
+
+real_t NavigationAgent2D::distance_to_target() const {
+ ERR_FAIL_COND_V(agent_parent == NULL, 0.0);
+ return agent_parent->get_global_transform().get_origin().distance_to(target_location);
+}
+
+bool NavigationAgent2D::is_target_reached() const {
+ return target_reached;
+}
+
+bool NavigationAgent2D::is_target_reachable() {
+ return target_desired_distance >= get_final_location().distance_to(target_location);
+}
+
+bool NavigationAgent2D::is_navigation_finished() {
+ update_navigation();
+ return navigation_finished;
+}
+
+Vector2 NavigationAgent2D::get_final_location() {
+ update_navigation();
+ if (navigation_path.size() == 0) {
+ return Vector2();
+ }
+ return navigation_path[navigation_path.size() - 1];
+}
+
+void NavigationAgent2D::set_velocity(Vector2 p_velocity) {
+ target_velocity = p_velocity;
+ Navigation2DServer::get_singleton()->agent_set_target_velocity(agent, target_velocity);
+ Navigation2DServer::get_singleton()->agent_set_velocity(agent, prev_safe_velocity);
+ velocity_submitted = true;
+}
+
+void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) {
+ const Vector2 velocity = Vector2(p_new_velocity.x, p_new_velocity.z);
+ prev_safe_velocity = velocity;
+
+ if (!velocity_submitted) {
+ target_velocity = Vector2();
+ return;
+ }
+ velocity_submitted = false;
+
+ emit_signal("velocity_computed", velocity);
+}
+
+String NavigationAgent2D::get_configuration_warning() const {
+ if (!Object::cast_to<Node2D>(get_parent())) {
+ return TTR("The NavigationAgent2D can be used only under a Node2D node");
+ }
+
+ return String();
+}
+
+void NavigationAgent2D::update_navigation() {
+
+ if (agent_parent == NULL) return;
+ if (navigation == NULL) return;
+ if (update_frame_id == Engine::get_singleton()->get_physics_frames()) return;
+
+ update_frame_id = Engine::get_singleton()->get_physics_frames();
+
+ Vector2 o = agent_parent->get_global_transform().get_origin();
+
+ bool reload_path = false;
+
+ if (Navigation2DServer::get_singleton()->agent_is_map_changed(agent)) {
+ reload_path = true;
+ } else if (navigation_path.size() == 0) {
+ reload_path = true;
+ } else {
+ // Check if too far from the navigation path
+ if (nav_path_index > 0) {
+ Vector2 segment[2];
+ segment[0] = navigation_path[nav_path_index - 1];
+ segment[1] = navigation_path[nav_path_index];
+ Vector2 p = Geometry::get_closest_point_to_segment_2d(o, segment);
+ if (o.distance_to(p) >= path_max_distance) {
+ // To faraway, reload path
+ reload_path = true;
+ }
+ }
+ }
+
+ if (reload_path) {
+ navigation_path = Navigation2DServer::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true);
+ navigation_finished = false;
+ nav_path_index = 0;
+ emit_signal("path_changed");
+ }
+
+ if (navigation_path.size() == 0)
+ return;
+
+ // Check if we can advance the navigation path
+ if (navigation_finished == false) {
+ // Advances to the next far away location.
+ while (o.distance_to(navigation_path[nav_path_index]) < target_desired_distance) {
+ nav_path_index += 1;
+ if (nav_path_index == navigation_path.size()) {
+ nav_path_index -= 1;
+ navigation_finished = true;
+ emit_signal("navigation_finished");
+ break;
+ }
+ }
+ }
+}
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
new file mode 100644
index 0000000000..26eccfc949
--- /dev/null
+++ b/scene/2d/navigation_agent_2d.h
@@ -0,0 +1,150 @@
+/*************************************************************************/
+/* navigation_agent_2d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef NAVIGATION_AGENT_2D_H
+#define NAVIGATION_AGENT_2D_H
+
+#include "core/vector.h"
+#include "scene/main/node.h"
+
+class Node2D;
+class Navigation2D;
+
+class NavigationAgent2D : public Node {
+ GDCLASS(NavigationAgent2D, Node);
+
+ Node2D *agent_parent;
+ Navigation2D *navigation;
+
+ RID agent;
+
+ real_t target_desired_distance;
+ real_t radius;
+ real_t neighbor_dist;
+ int max_neighbors;
+ real_t time_horizon;
+ real_t max_speed;
+
+ real_t path_max_distance;
+
+ Vector2 target_location;
+ Vector<Vector2> navigation_path;
+ int nav_path_index;
+ bool velocity_submitted;
+ Vector2 prev_safe_velocity;
+ /// The submitted target velocity
+ Vector2 target_velocity;
+ bool target_reached;
+ bool navigation_finished;
+ // No initialized on purpose
+ uint32_t update_frame_id;
+
+protected:
+ static void _bind_methods();
+ void _notification(int p_what);
+
+public:
+ NavigationAgent2D();
+ virtual ~NavigationAgent2D();
+
+ void set_navigation(Navigation2D *p_nav);
+ const Navigation2D *get_navigation() const {
+ return navigation;
+ }
+
+ void set_navigation_node(Node *p_nav);
+ Node *get_navigation_node() const;
+
+ RID get_rid() const {
+ return agent;
+ }
+
+ void set_target_desired_distance(real_t p_dd);
+ real_t get_target_desired_distance() const {
+ return target_desired_distance;
+ }
+
+ void set_radius(real_t p_radius);
+ real_t get_radius() const {
+ return radius;
+ }
+
+ void set_neighbor_dist(real_t p_dist);
+ real_t get_neighbor_dist() const {
+ return neighbor_dist;
+ }
+
+ void set_max_neighbors(int p_count);
+ int get_max_neighbors() const {
+ return max_neighbors;
+ }
+
+ void set_time_horizon(real_t p_time);
+ real_t get_time_horizon() const {
+ return time_horizon;
+ }
+
+ void set_max_speed(real_t p_max_speed);
+ real_t get_max_speed() const {
+ return max_speed;
+ }
+
+ void set_path_max_distance(real_t p_pmd);
+ real_t get_path_max_distance();
+
+ void set_target_location(Vector2 p_location);
+ Vector2 get_target_location() const;
+
+ Vector2 get_next_location();
+
+ Vector<Vector2> get_nav_path() const {
+ return navigation_path;
+ }
+
+ int get_nav_path_index() const {
+ return nav_path_index;
+ }
+
+ real_t distance_to_target() const;
+ bool is_target_reached() const;
+ bool is_target_reachable();
+ bool is_navigation_finished();
+ Vector2 get_final_location();
+
+ void set_velocity(Vector2 p_velocity);
+ void _avoidance_done(Vector3 p_new_velocity);
+
+ virtual String get_configuration_warning() const;
+
+private:
+ void update_navigation();
+};
+
+#endif
diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp
new file mode 100644
index 0000000000..cc9f5740a9
--- /dev/null
+++ b/scene/2d/navigation_obstacle_2d.cpp
@@ -0,0 +1,154 @@
+/*************************************************************************/
+/* navigation_obstacle_2d.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "navigation_obstacle_2d.h"
+
+#include "scene/2d/collision_shape_2d.h"
+#include "scene/2d/navigation_2d.h"
+#include "scene/2d/physics_body_2d.h"
+#include "servers/navigation_2d_server.h"
+
+void NavigationObstacle2D::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node);
+ ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node);
+}
+
+void NavigationObstacle2D::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+
+ update_agent_shape();
+
+ // Search the navigation node and set it
+ {
+ Navigation2D *nav = NULL;
+ Node *p = get_parent();
+ while (p != NULL) {
+ nav = Object::cast_to<Navigation2D>(p);
+ if (nav != NULL)
+ p = NULL;
+ else
+ p = p->get_parent();
+ }
+
+ set_navigation(nav);
+ }
+
+ set_physics_process_internal(true);
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ set_navigation(NULL);
+ set_physics_process_internal(false);
+ } break;
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ Node2D *node = Object::cast_to<Node2D>(get_parent());
+ if (node) {
+ Navigation2DServer::get_singleton()->agent_set_position(agent, node->get_global_transform().get_origin());
+ }
+
+ } break;
+ }
+}
+
+NavigationObstacle2D::NavigationObstacle2D() :
+ navigation(NULL),
+ agent(RID()) {
+ agent = Navigation2DServer::get_singleton()->agent_create();
+}
+
+NavigationObstacle2D::~NavigationObstacle2D() {
+ Navigation2DServer::get_singleton()->free(agent);
+ agent = RID(); // Pointless
+}
+
+void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) {
+ if (navigation == p_nav)
+ return; // Pointless
+
+ navigation = p_nav;
+ Navigation2DServer::get_singleton()->agent_set_map(agent, navigation == NULL ? RID() : navigation->get_rid());
+}
+
+void NavigationObstacle2D::set_navigation_node(Node *p_nav) {
+ Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
+ ERR_FAIL_COND(nav == NULL);
+ set_navigation(nav);
+}
+
+Node *NavigationObstacle2D::get_navigation_node() const {
+ return Object::cast_to<Node>(navigation);
+}
+
+String NavigationObstacle2D::get_configuration_warning() const {
+ if (!Object::cast_to<Node2D>(get_parent())) {
+ return TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object.");
+ }
+
+ return String();
+}
+
+void NavigationObstacle2D::update_agent_shape() {
+ Node *node = get_parent();
+
+ // Estimate the radius of this physics body
+ real_t radius = 0.0;
+ for (int i(0); i < node->get_child_count(); i++) {
+ // For each collision shape
+ CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(node->get_child(i));
+ if (cs) {
+ // Take the distance between the Body center to the shape center
+ real_t r = cs->get_transform().get_origin().length();
+ if (cs->get_shape().is_valid()) {
+ // and add the enclosing shape radius
+ r += cs->get_shape()->get_enclosing_radius();
+ }
+ Size2 s = cs->get_global_transform().get_scale();
+ r *= MAX(s.x, s.y);
+ // Takes the biggest radius
+ radius = MAX(radius, r);
+ }
+ }
+ Node2D *node_2d = Object::cast_to<Node2D>(node);
+ if (node_2d) {
+ Vector2 s = node_2d->get_global_transform().get_scale();
+ radius *= MAX(s.x, s.y);
+ }
+
+ if (radius == 0.0)
+ radius = 1.0; // Never a 0 radius
+
+ // Initialize the Agent as an object
+ Navigation2DServer::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
+ Navigation2DServer::get_singleton()->agent_set_max_neighbors(agent, 0);
+ Navigation2DServer::get_singleton()->agent_set_time_horizon(agent, 0.0);
+ Navigation2DServer::get_singleton()->agent_set_radius(agent, radius);
+ Navigation2DServer::get_singleton()->agent_set_max_speed(agent, 0.0);
+}
diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h
new file mode 100644
index 0000000000..3935fe1bc5
--- /dev/null
+++ b/scene/2d/navigation_obstacle_2d.h
@@ -0,0 +1,71 @@
+/*************************************************************************/
+/* navigation_obstacle_2d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef NAVIGATION_OBSTACLE_2D_H
+#define NAVIGATION_OBSTACLE_2D_H
+
+#include "scene/main/node.h"
+
+class Navigation2D;
+
+class NavigationObstacle2D : public Node {
+ GDCLASS(NavigationObstacle2D, Node);
+
+ Navigation2D *navigation;
+
+ RID agent;
+
+protected:
+ static void _bind_methods();
+ void _notification(int p_what);
+
+public:
+ NavigationObstacle2D();
+ virtual ~NavigationObstacle2D();
+
+ void set_navigation(Navigation2D *p_nav);
+ const Navigation2D *get_navigation() const {
+ return navigation;
+ }
+
+ void set_navigation_node(Node *p_nav);
+ Node *get_navigation_node() const;
+
+ RID get_rid() const {
+ return agent;
+ }
+
+ virtual String get_configuration_warning() const;
+
+private:
+ void update_agent_shape();
+};
+
+#endif
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index ea79f89dd9..21b2bede05 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -32,7 +32,9 @@
#include "core/core_string_names.h"
#include "core/engine.h"
+#include "core/os/mutex.h"
#include "navigation_2d.h"
+#include "servers/navigation_2d_server.h"
#include "thirdparty/misc/triangulator.h"
@@ -80,6 +82,9 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double
void NavigationPolygon::set_vertices(const PoolVector<Vector2> &p_vertices) {
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
vertices = p_vertices;
rect_cache_dirty = true;
}
@@ -91,6 +96,9 @@ PoolVector<Vector2> NavigationPolygon::get_vertices() const {
void NavigationPolygon::_set_polygons(const Array &p_array) {
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
polygons.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
polygons.write[i].indices = p_array[i];
@@ -133,6 +141,9 @@ void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) {
Polygon polygon;
polygon.indices = p_polygon;
polygons.push_back(polygon);
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
}
void NavigationPolygon::add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index) {
@@ -153,6 +164,34 @@ Vector<int> NavigationPolygon::get_polygon(int p_idx) {
void NavigationPolygon::clear_polygons() {
polygons.clear();
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
+}
+
+Ref<NavigationMesh> NavigationPolygon::get_mesh() {
+ navmesh_generation->lock();
+ if (navmesh.is_null()) {
+ navmesh.instance();
+ PoolVector<Vector3> verts;
+ {
+ verts.resize(get_vertices().size());
+ PoolVector<Vector3>::Write w = verts.write();
+
+ PoolVector<Vector2>::Read r = get_vertices().read();
+
+ for (int i(0); i < get_vertices().size(); i++) {
+ w[i] = Vector3(r[i].x, 0.0, r[i].y);
+ }
+ }
+ navmesh->set_vertices(verts);
+
+ for (int i(0); i < get_polygon_count(); i++) {
+ navmesh->add_polygon(get_polygon(i));
+ }
+ }
+ navmesh_generation->unlock();
+ return navmesh;
}
void NavigationPolygon::add_outline(const PoolVector<Vector2> &p_outline) {
@@ -191,6 +230,9 @@ void NavigationPolygon::clear_outlines() {
}
void NavigationPolygon::make_polygons_from_outlines() {
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
List<TriangulatorPoly> in_poly, out_poly;
Vector2 outside_point(-1e10, -1e10);
@@ -259,7 +301,7 @@ void NavigationPolygon::make_polygons_from_outlines() {
TriangulatorPartition tpart;
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
- ERR_PRINTS("NavigationPolygon: Convex partition failed!");
+ ERR_PRINT("NavigationPolygon: Convex partition failed!");
return;
}
@@ -320,7 +362,12 @@ void NavigationPolygon::_bind_methods() {
}
NavigationPolygon::NavigationPolygon() :
- rect_cache_dirty(true) {
+ rect_cache_dirty(true),
+ navmesh_generation(Mutex::create()) {
+}
+
+NavigationPolygon::~NavigationPolygon() {
+ memdelete(navmesh_generation);
}
void NavigationPolygonInstance::set_enabled(bool p_enabled) {
@@ -334,18 +381,12 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) {
if (!enabled) {
- if (nav_id != -1) {
- navigation->navpoly_remove(nav_id);
- nav_id = -1;
- }
+ Navigation2DServer::get_singleton()->region_set_map(region, RID());
} else {
if (navigation) {
- if (navpoly.is_valid()) {
-
- nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this);
- }
+ Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid());
}
}
@@ -382,9 +423,9 @@ void NavigationPolygonInstance::_notification(int p_what) {
navigation = Object::cast_to<Navigation2D>(c);
if (navigation) {
- if (enabled && navpoly.is_valid()) {
+ if (enabled) {
- nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this);
+ Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid());
}
break;
}
@@ -395,19 +436,14 @@ void NavigationPolygonInstance::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
- if (navigation && nav_id != -1) {
- navigation->navpoly_set_transform(nav_id, get_relative_transform_to_parent(navigation));
- }
+ Navigation2DServer::get_singleton()->region_set_transform(region, get_global_transform());
} break;
case NOTIFICATION_EXIT_TREE: {
if (navigation) {
- if (nav_id != -1) {
- navigation->navpoly_remove(nav_id);
- nav_id = -1;
- }
+ Navigation2DServer::get_singleton()->region_set_map(region, RID());
}
navigation = NULL;
} break;
@@ -466,24 +502,18 @@ void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolyg
return;
}
- if (navigation && nav_id != -1) {
- navigation->navpoly_remove(nav_id);
- nav_id = -1;
- }
-
if (navpoly.is_valid()) {
navpoly->disconnect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed");
}
+
navpoly = p_navpoly;
+ Navigation2DServer::get_singleton()->region_set_navpoly(region, p_navpoly);
+
if (navpoly.is_valid()) {
navpoly->connect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed");
}
_navpoly_changed();
- if (navigation && navpoly.is_valid() && enabled) {
- nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this);
- }
-
_change_notify("navpoly");
update_configuration_warning();
}
@@ -536,8 +566,13 @@ void NavigationPolygonInstance::_bind_methods() {
NavigationPolygonInstance::NavigationPolygonInstance() {
- navigation = NULL;
- nav_id = -1;
enabled = true;
set_notify_transform(true);
+ region = Navigation2DServer::get_singleton()->region_create();
+
+ navigation = NULL;
+}
+
+NavigationPolygonInstance::~NavigationPolygonInstance() {
+ Navigation2DServer::get_singleton()->free(region);
}
diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h
index cbc1711a32..8d3d8543c4 100644
--- a/scene/2d/navigation_polygon.h
+++ b/scene/2d/navigation_polygon.h
@@ -32,6 +32,9 @@
#define NAVIGATION_POLYGON_H
#include "scene/2d/node_2d.h"
+#include "scene/resources/navigation_mesh.h"
+
+class Mutex;
class NavigationPolygon : public Resource {
@@ -47,6 +50,10 @@ class NavigationPolygon : public Resource {
mutable Rect2 item_rect;
mutable bool rect_cache_dirty;
+ Mutex *navmesh_generation;
+ // Navigation mesh
+ Ref<NavigationMesh> navmesh;
+
protected:
static void _bind_methods();
@@ -81,7 +88,10 @@ public:
Vector<int> get_polygon(int p_idx);
void clear_polygons();
+ Ref<NavigationMesh> get_mesh();
+
NavigationPolygon();
+ ~NavigationPolygon();
};
class Navigation2D;
@@ -91,7 +101,7 @@ class NavigationPolygonInstance : public Node2D {
GDCLASS(NavigationPolygonInstance, Node2D);
bool enabled;
- int nav_id;
+ RID region;
Navigation2D *navigation;
Ref<NavigationPolygon> navpoly;
@@ -116,6 +126,7 @@ public:
String get_configuration_warning() const;
NavigationPolygonInstance();
+ ~NavigationPolygonInstance();
};
#endif // NAVIGATIONPOLYGON_H
diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp
index 746feeaa82..d3bc7b6a5a 100644
--- a/scene/2d/particles_2d.cpp
+++ b/scene/2d/particles_2d.cpp
@@ -268,22 +268,22 @@ Rect2 Particles2D::capture_rect() const {
return r;
}
-void Particles2D::set_texture(const Ref<Texture> &p_texture) {
+void Particles2D::set_texture(const Ref<Texture2D> &p_texture) {
texture = p_texture;
update();
}
-Ref<Texture> Particles2D::get_texture() const {
+Ref<Texture2D> Particles2D::get_texture() const {
return texture;
}
-void Particles2D::set_normal_map(const Ref<Texture> &p_normal_map) {
+void Particles2D::set_normal_map(const Ref<Texture2D> &p_normal_map) {
normal_map = p_normal_map;
update();
}
-Ref<Texture> Particles2D::get_normal_map() const {
+Ref<Texture2D> Particles2D::get_normal_map() const {
return normal_map;
}
@@ -399,8 +399,8 @@ void Particles2D::_bind_methods() {
ADD_GROUP("Process Material", "process_");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticlesMaterial"), "set_process_material", "get_process_material");
ADD_GROUP("Textures", "");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX);
BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h
index 56c328fc38..66281d7950 100644
--- a/scene/2d/particles_2d.h
+++ b/scene/2d/particles_2d.h
@@ -64,8 +64,8 @@ private:
DrawOrder draw_order;
- Ref<Texture> texture;
- Ref<Texture> normal_map;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
void _update_particle_emission_transform();
@@ -108,11 +108,11 @@ public:
void set_draw_order(DrawOrder p_order);
DrawOrder get_draw_order() const;
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
- void set_normal_map(const Ref<Texture> &p_normal_map);
- Ref<Texture> get_normal_map() const;
+ void set_normal_map(const Ref<Texture2D> &p_normal_map);
+ Ref<Texture2D> get_normal_map() const;
virtual String get_configuration_warning() const;
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index 6ae008548e..d83c163b4c 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -112,7 +112,7 @@ void Path2D::_notification(int p_what) {
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
- draw_line(prev_p, p, color, line_width, true);
+ draw_line(prev_p, p, color, line_width);
prev_p = p;
}
}
@@ -120,9 +120,15 @@ void Path2D::_notification(int p_what) {
}
void Path2D::_curve_changed() {
+ if (!is_inside_tree()) {
+ return;
+ }
+
+ if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
+ return;
+ }
- if (is_inside_tree() && Engine::get_singleton()->is_editor_hint())
- update();
+ update();
}
void Path2D::set_curve(const Ref<Curve2D> &p_curve) {
diff --git a/scene/2d/path_texture.cpp b/scene/2d/path_texture.cpp
index df59c9e2bb..590f70a1b2 100644
--- a/scene/2d/path_texture.cpp
+++ b/scene/2d/path_texture.cpp
@@ -30,33 +30,33 @@
#include "path_texture.h"
-void PathTexture::set_begin_texture(const Ref<Texture> &p_texture) {
+void PathTexture::set_begin_texture(const Ref<Texture2D> &p_texture) {
begin = p_texture;
update();
}
-Ref<Texture> PathTexture::get_begin_texture() const {
+Ref<Texture2D> PathTexture::get_begin_texture() const {
return begin;
}
-void PathTexture::set_repeat_texture(const Ref<Texture> &p_texture) {
+void PathTexture::set_repeat_texture(const Ref<Texture2D> &p_texture) {
repeat = p_texture;
update();
}
-Ref<Texture> PathTexture::get_repeat_texture() const {
+Ref<Texture2D> PathTexture::get_repeat_texture() const {
return repeat;
}
-void PathTexture::set_end_texture(const Ref<Texture> &p_texture) {
+void PathTexture::set_end_texture(const Ref<Texture2D> &p_texture) {
end = p_texture;
update();
}
-Ref<Texture> PathTexture::get_end_texture() const {
+Ref<Texture2D> PathTexture::get_end_texture() const {
return end;
}
diff --git a/scene/2d/path_texture.h b/scene/2d/path_texture.h
index 9cfa004cfb..014d0dc959 100644
--- a/scene/2d/path_texture.h
+++ b/scene/2d/path_texture.h
@@ -36,21 +36,21 @@
class PathTexture : public Node2D {
GDCLASS(PathTexture, Node2D);
- Ref<Texture> begin;
- Ref<Texture> repeat;
- Ref<Texture> end;
+ Ref<Texture2D> begin;
+ Ref<Texture2D> repeat;
+ Ref<Texture2D> end;
int subdivs;
bool overlap;
public:
- void set_begin_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_begin_texture() const;
+ void set_begin_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_begin_texture() const;
- void set_repeat_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_repeat_texture() const;
+ void set_repeat_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_repeat_texture() const;
- void set_end_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_end_texture() const;
+ void set_end_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_end_texture() const;
void set_subdivisions(int p_amount);
int get_subdivisions() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index d42bd6adaf..29bfc39477 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -190,64 +190,6 @@ real_t StaticBody2D::get_constant_angular_velocity() const {
return constant_angular_velocity;
}
-#ifndef DISABLE_DEPRECATED
-void StaticBody2D::set_friction(real_t p_friction) {
-
- if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that
- return;
- }
-
- WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
-
- ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1.");
-
- if (physics_material_override.is_null()) {
- physics_material_override.instance();
- set_physics_material_override(physics_material_override);
- }
- physics_material_override->set_friction(p_friction);
-}
-
-real_t StaticBody2D::get_friction() const {
-
- WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
-
- if (physics_material_override.is_null()) {
- return 1;
- }
-
- return physics_material_override->get_friction();
-}
-
-void StaticBody2D::set_bounce(real_t p_bounce) {
-
- if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that
- return;
- }
-
- WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
-
- ERR_FAIL_COND_MSG(p_bounce < 0 || p_bounce > 1, "Bounce must be between 0 and 1.");
-
- if (physics_material_override.is_null()) {
- physics_material_override.instance();
- set_physics_material_override(physics_material_override);
- }
- physics_material_override->set_bounce(p_bounce);
-}
-
-real_t StaticBody2D::get_bounce() const {
-
- WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
-
- if (physics_material_override.is_null()) {
- return 0;
- }
-
- return physics_material_override->get_bounce();
-}
-#endif // DISABLE_DEPRECATED
-
void StaticBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
if (physics_material_override.is_valid()) {
if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
@@ -273,14 +215,6 @@ void StaticBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody2D::get_constant_linear_velocity);
ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody2D::get_constant_angular_velocity);
-#ifndef DISABLE_DEPRECATED
- ClassDB::bind_method(D_METHOD("set_friction", "friction"), &StaticBody2D::set_friction);
- ClassDB::bind_method(D_METHOD("get_friction"), &StaticBody2D::get_friction);
-
- ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &StaticBody2D::set_bounce);
- ClassDB::bind_method(D_METHOD("get_bounce"), &StaticBody2D::get_bounce);
-#endif // DISABLE_DEPRECATED
-
ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody2D::set_physics_material_override);
ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody2D::get_physics_material_override);
@@ -288,10 +222,6 @@ void StaticBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity");
-#ifndef DISABLE_DEPRECATED
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce");
-#endif // DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
}
@@ -613,62 +543,6 @@ real_t RigidBody2D::get_weight() const {
return mass * (real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10);
}
-#ifndef DISABLE_DEPRECATED
-void RigidBody2D::set_friction(real_t p_friction) {
-
- if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that
- return;
- }
-
- WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
-
- ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1.");
-
- if (physics_material_override.is_null()) {
- physics_material_override.instance();
- set_physics_material_override(physics_material_override);
- }
- physics_material_override->set_friction(p_friction);
-}
-real_t RigidBody2D::get_friction() const {
-
- WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
-
- if (physics_material_override.is_null()) {
- return 1;
- }
-
- return physics_material_override->get_friction();
-}
-
-void RigidBody2D::set_bounce(real_t p_bounce) {
-
- if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that
- return;
- }
-
- WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
-
- ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
-
- if (physics_material_override.is_null()) {
- physics_material_override.instance();
- set_physics_material_override(physics_material_override);
- }
- physics_material_override->set_bounce(p_bounce);
-}
-real_t RigidBody2D::get_bounce() const {
-
- WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
-
- if (physics_material_override.is_null()) {
- return 0;
- }
-
- return physics_material_override->get_bounce();
-}
-#endif // DISABLE_DEPRECATED
-
void RigidBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
if (physics_material_override.is_valid()) {
if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
@@ -968,14 +842,6 @@ void RigidBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody2D::set_weight);
ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody2D::get_weight);
-#ifndef DISABLE_DEPRECATED
- ClassDB::bind_method(D_METHOD("set_friction", "friction"), &RigidBody2D::set_friction);
- ClassDB::bind_method(D_METHOD("get_friction"), &RigidBody2D::get_friction);
-
- ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &RigidBody2D::set_bounce);
- ClassDB::bind_method(D_METHOD("get_bounce"), &RigidBody2D::get_bounce);
-#endif // DISABLE_DEPRECATED
-
ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody2D::set_physics_material_override);
ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody2D::get_physics_material_override);
@@ -1043,10 +909,6 @@ void RigidBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight");
-#ifndef DISABLE_DEPRECATED
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce");
-#endif // DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator");
@@ -1544,7 +1406,7 @@ Object *KinematicCollision2D::get_local_shape() const {
Object *KinematicCollision2D::get_collider() const {
- if (collision.collider) {
+ if (collision.collider.is_valid()) {
return ObjectDB::get_instance(collision.collider);
}
@@ -1608,7 +1470,7 @@ void KinematicCollision2D::_bind_methods() {
}
KinematicCollision2D::KinematicCollision2D() {
- collision.collider = 0;
+
collision.collider_shape = 0;
collision.local_shape = 0;
owner = NULL;
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 6766bafde3..20e9f3ffcf 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -87,13 +87,6 @@ protected:
static void _bind_methods();
public:
-#ifndef DISABLE_DEPRECATED
- void set_friction(real_t p_friction);
- real_t get_friction() const;
-
- void set_bounce(real_t p_bounce);
- real_t get_bounce() const;
-#endif
void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
Ref<PhysicsMaterial> get_physics_material_override() const;
@@ -211,14 +204,6 @@ public:
void set_weight(real_t p_weight);
real_t get_weight() const;
-#ifndef DISABLE_DEPRECATED
- void set_friction(real_t p_friction);
- real_t get_friction() const;
-
- void set_bounce(real_t p_bounce);
- real_t get_bounce() const;
-#endif
-
void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
Ref<PhysicsMaterial> get_physics_material_override() const;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index a6da027e0a..ba5b7d29e7 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -108,7 +108,7 @@ void Polygon2D::_notification(int p_what) {
skeleton_node = Object::cast_to<Skeleton2D>(get_node(skeleton));
}
- ObjectID new_skeleton_id = 0;
+ ObjectID new_skeleton_id;
if (skeleton_node) {
VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), skeleton_node->get_skeleton());
@@ -304,13 +304,10 @@ void Polygon2D::_notification(int p_what) {
colors.push_back(color);
}
- // Vector<int> indices = Geometry::triangulate_polygon(points);
- // VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID());
-
if (invert || polygons.size() == 0) {
Vector<int> indices = Geometry::triangulate_polygon(points);
if (indices.size()) {
- VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, RID(), antialiased);
+ VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, normal_map.is_valid() ? normal_map->get_rid() : RID(), specular_map.is_valid() ? specular_map->get_rid() : RID(), Color(specular_color.r, specular_color.g, specular_color.b, shininess));
}
} else {
//draw individual polygons
@@ -344,7 +341,7 @@ void Polygon2D::_notification(int p_what) {
}
if (total_indices.size()) {
- VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, RID(), antialiased);
+ VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID());
}
}
@@ -414,7 +411,7 @@ PoolVector<Color> Polygon2D::get_vertex_colors() const {
return vertex_colors;
}
-void Polygon2D::set_texture(const Ref<Texture> &p_texture) {
+void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) {
texture = p_texture;
@@ -428,11 +425,47 @@ void Polygon2D::set_texture(const Ref<Texture> &p_texture) {
}*/
update();
}
-Ref<Texture> Polygon2D::get_texture() const {
+Ref<Texture2D> Polygon2D::get_texture() const {
return texture;
}
+void Polygon2D::set_normal_map(const Ref<Texture2D> &p_normal_map) {
+ normal_map = p_normal_map;
+ update();
+}
+
+Ref<Texture2D> Polygon2D::get_normal_map() const {
+ return normal_map;
+}
+
+void Polygon2D::set_specular_map(const Ref<Texture2D> &p_specular_map) {
+ specular_map = p_specular_map;
+ update();
+}
+
+Ref<Texture2D> Polygon2D::get_specular_map() const {
+ return specular_map;
+}
+
+void Polygon2D::set_specular_color(const Color &p_specular_color) {
+ specular_color = p_specular_color;
+ update();
+}
+
+Color Polygon2D::get_specular_color() const {
+ return specular_color;
+}
+
+void Polygon2D::set_shininess(float p_shininess) {
+ shininess = CLAMP(p_shininess, 0.0, 1.0);
+ update();
+}
+
+float Polygon2D::get_shininess() const {
+ return shininess;
+}
+
void Polygon2D::set_texture_offset(const Vector2 &p_offset) {
tex_ofs = p_offset;
@@ -603,6 +636,18 @@ void Polygon2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Polygon2D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &Polygon2D::get_texture);
+ ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &Polygon2D::set_normal_map);
+ ClassDB::bind_method(D_METHOD("get_normal_map"), &Polygon2D::get_normal_map);
+
+ ClassDB::bind_method(D_METHOD("set_specular_map", "specular_map"), &Polygon2D::set_specular_map);
+ ClassDB::bind_method(D_METHOD("get_specular_map"), &Polygon2D::get_specular_map);
+
+ ClassDB::bind_method(D_METHOD("set_specular_color", "specular_color"), &Polygon2D::set_specular_color);
+ ClassDB::bind_method(D_METHOD("get_specular_color"), &Polygon2D::get_specular_color);
+
+ ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &Polygon2D::set_shininess);
+ ClassDB::bind_method(D_METHOD("get_shininess"), &Polygon2D::get_shininess);
+
ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &Polygon2D::set_texture_offset);
ClassDB::bind_method(D_METHOD("get_texture_offset"), &Polygon2D::get_texture_offset);
@@ -650,13 +695,18 @@ void Polygon2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased");
- ADD_GROUP("Texture", "");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_GROUP("Texture", "texture_");
+ ADD_GROUP("Texture2D", "");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_GROUP("Texture2D", "texture_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_offset"), "set_texture_offset", "get_texture_offset");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale"), "set_texture_scale", "get_texture_scale");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_texture_rotation_degrees", "get_texture_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation");
+ ADD_GROUP("Lighting", "");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "specular_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_specular_map", "get_specular_map");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess");
ADD_GROUP("Skeleton", "");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton");
@@ -684,5 +734,7 @@ Polygon2D::Polygon2D() {
color = Color(1, 1, 1);
rect_cache_dirty = true;
internal_vertices = 0;
- current_skeleton_id = 0;
+
+ specular_color = Color(1, 1, 1, 1);
+ shininess = 1.0;
}
diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h
index 07b8828532..4816e2c869 100644
--- a/scene/2d/polygon_2d.h
+++ b/scene/2d/polygon_2d.h
@@ -51,7 +51,12 @@ class Polygon2D : public Node2D {
Vector<Bone> bone_weights;
Color color;
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
+ Ref<Texture2D> specular_map;
+ Color specular_color;
+ float shininess;
+
Size2 tex_scale;
Vector2 tex_ofs;
bool tex_tile;
@@ -108,8 +113,20 @@ public:
void set_vertex_colors(const PoolVector<Color> &p_colors);
PoolVector<Color> get_vertex_colors() const;
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
+
+ void set_normal_map(const Ref<Texture2D> &p_normal_map);
+ Ref<Texture2D> get_normal_map() const;
+
+ void set_specular_map(const Ref<Texture2D> &p_specular_map);
+ Ref<Texture2D> get_specular_map() const;
+
+ void set_specular_color(const Color &p_specular_color);
+ Color get_specular_color() const;
+
+ void set_shininess(float p_shininess);
+ float get_shininess() const;
void set_texture_offset(const Vector2 &p_offset);
Vector2 get_texture_offset() const;
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 5098d5115a..fd6e0aebcc 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -78,7 +78,7 @@ bool RayCast2D::is_colliding() const {
}
Object *RayCast2D::get_collider() const {
- if (against == 0)
+ if (against.is_null())
return NULL;
return ObjectDB::get_instance(against);
@@ -176,7 +176,7 @@ void RayCast2D::_notification(int p_what) {
draw_col.g = g;
draw_col.b = g;
}
- draw_line(Vector2(), cast_to, draw_col, 2, true);
+ draw_line(Vector2(), cast_to, draw_col, 2);
Vector<Vector2> pts;
float tsize = 8;
pts.push_back(xf.xform(Vector2(tsize, 0)));
@@ -225,7 +225,7 @@ void RayCast2D::_update_raycast_state() {
against_shape = rr.shape;
} else {
collided = false;
- against = 0;
+ against = ObjectID();
against_shape = 0;
}
}
@@ -339,7 +339,7 @@ void RayCast2D::_bind_methods() {
RayCast2D::RayCast2D() {
enabled = false;
- against = 0;
+
collided = false;
against_shape = 0;
collision_mask = 1;
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index 53072f942d..ec50f5f922 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -33,7 +33,7 @@
void RemoteTransform2D::_update_cache() {
- cache = 0;
+ cache = ObjectID();
if (has_node(remote_node)) {
Node *node = get_node(remote_node);
if (!node || this == node || node->is_a_parent_of(this) || this->is_a_parent_of(node)) {
@@ -49,7 +49,7 @@ void RemoteTransform2D::_update_remote() {
if (!is_inside_tree())
return;
- if (!cache)
+ if (cache.is_null())
return;
Node2D *n = Object::cast_to<Node2D>(ObjectDB::get_instance(cache));
@@ -119,7 +119,7 @@ void RemoteTransform2D::_notification(int p_what) {
if (!is_inside_tree())
break;
- if (cache) {
+ if (cache.is_valid()) {
_update_remote();
}
@@ -225,6 +225,5 @@ RemoteTransform2D::RemoteTransform2D() {
update_remote_rotation = true;
update_remote_scale = true;
- cache = 0;
set_notify_transform(true);
}
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index 55daed0585..2fe39ca104 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -130,13 +130,13 @@ void Sprite::_notification(int p_what) {
Rect2 src_rect, dst_rect;
bool filter_clip;
_get_rects(src_rect, dst_rect, filter_clip);
- texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, filter_clip);
+ texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, specular, Color(specular_color.r, specular_color.g, specular_color.b, shininess), VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, filter_clip);
} break;
}
}
-void Sprite::set_texture(const Ref<Texture> &p_texture) {
+void Sprite::set_texture(const Ref<Texture2D> &p_texture) {
if (p_texture == texture)
return;
@@ -155,18 +155,47 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) {
_change_notify("texture");
}
-void Sprite::set_normal_map(const Ref<Texture> &p_texture) {
+void Sprite::set_normal_map(const Ref<Texture2D> &p_texture) {
normal_map = p_texture;
update();
}
-Ref<Texture> Sprite::get_normal_map() const {
+Ref<Texture2D> Sprite::get_normal_map() const {
return normal_map;
}
-Ref<Texture> Sprite::get_texture() const {
+void Sprite::set_specular_map(const Ref<Texture2D> &p_texture) {
+
+ specular = p_texture;
+ update();
+}
+
+Ref<Texture2D> Sprite::get_specular_map() const {
+
+ return specular;
+}
+
+void Sprite::set_specular_color(const Color &p_color) {
+ specular_color = p_color;
+ update();
+}
+
+Color Sprite::get_specular_color() const {
+ return specular_color;
+}
+
+void Sprite::set_shininess(float p_shininess) {
+ shininess = CLAMP(p_shininess, 0.0, 1.0);
+ update();
+}
+
+float Sprite::get_shininess() const {
+ return shininess;
+}
+
+Ref<Texture2D> Sprite::get_texture() const {
return texture;
}
@@ -334,9 +363,11 @@ bool Sprite::is_pixel_opaque(const Point2 &p_point) const {
if (vflip)
q.y = 1.0f - q.y;
q = q * src_rect.size + src_rect.position;
-
- bool is_repeat = texture->get_flags() & Texture::FLAG_REPEAT;
- bool is_mirrored_repeat = texture->get_flags() & Texture::FLAG_MIRRORED_REPEAT;
+#ifndef _MSC_VER
+#warning this need to be obtained from CanvasItem new repeat mode (but it needs to guess it from hierarchy, need to add a function for that)
+#endif
+ bool is_repeat = false;
+ bool is_mirrored_repeat = false;
if (is_repeat) {
int mirror_x = 0;
int mirror_y = 0;
@@ -415,6 +446,15 @@ void Sprite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &Sprite::set_normal_map);
ClassDB::bind_method(D_METHOD("get_normal_map"), &Sprite::get_normal_map);
+ ClassDB::bind_method(D_METHOD("set_specular_map", "specular_map"), &Sprite::set_specular_map);
+ ClassDB::bind_method(D_METHOD("get_specular_map"), &Sprite::get_specular_map);
+
+ ClassDB::bind_method(D_METHOD("set_specular_color", "specular_color"), &Sprite::set_specular_color);
+ ClassDB::bind_method(D_METHOD("get_specular_color"), &Sprite::get_specular_color);
+
+ ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &Sprite::set_shininess);
+ ClassDB::bind_method(D_METHOD("get_shininess"), &Sprite::get_shininess);
+
ClassDB::bind_method(D_METHOD("set_centered", "centered"), &Sprite::set_centered);
ClassDB::bind_method(D_METHOD("is_centered"), &Sprite::is_centered);
@@ -457,8 +497,12 @@ void Sprite::_bind_methods() {
ADD_SIGNAL(MethodInfo("frame_changed"));
ADD_SIGNAL(MethodInfo("texture_changed"));
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_GROUP("Lighting", "");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "specular_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_specular_map", "get_specular_map");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess");
ADD_GROUP("Offset", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
@@ -483,6 +527,8 @@ Sprite::Sprite() {
vflip = false;
region = false;
region_filter_clip = false;
+ shininess = 1.0;
+ specular_color = Color(1, 1, 1, 1);
frame = 0;
diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h
index d72bf3168d..a96f023231 100644
--- a/scene/2d/sprite.h
+++ b/scene/2d/sprite.h
@@ -38,8 +38,11 @@ class Sprite : public Node2D {
GDCLASS(Sprite, Node2D);
- Ref<Texture> texture;
- Ref<Texture> normal_map;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
+ Ref<Texture2D> specular;
+ Color specular_color;
+ float shininess;
bool centered;
Point2 offset;
@@ -82,11 +85,20 @@ public:
bool is_pixel_opaque(const Point2 &p_point) const;
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
- void set_normal_map(const Ref<Texture> &p_texture);
- Ref<Texture> get_normal_map() const;
+ void set_normal_map(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_normal_map() const;
+
+ void set_specular_map(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_specular_map() const;
+
+ void set_specular_color(const Color &p_color);
+ Color get_specular_color() const;
+
+ void set_shininess(float p_shininess);
+ float get_shininess() const;
void set_centered(bool p_center);
bool is_centered() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index b6db025d44..e3fda5b585 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -35,6 +35,7 @@
#include "core/method_bind_ext.gen.inc"
#include "core/os/os.h"
#include "scene/2d/area_2d.h"
+#include "servers/navigation_2d_server.h"
#include "servers/physics_2d_server.h"
int TileMap::_get_quadrant_size() const {
@@ -86,7 +87,7 @@ void TileMap::_notification(int p_what) {
if (navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
- navigation->navpoly_remove(F->get().id);
+ Navigation2DServer::get_singleton()->region_set_map(F->get().region, RID());
}
q.navpoly_ids.clear();
}
@@ -163,7 +164,7 @@ void TileMap::_update_quadrant_transform() {
if (navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
- navigation->navpoly_set_transform(F->get().id, nav_rel * F->get().xform);
+ Navigation2DServer::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform);
}
}
@@ -377,7 +378,7 @@ void TileMap::update_dirty_quadrants() {
if (navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
- navigation->navpoly_remove(E->get().id);
+ Navigation2DServer::get_singleton()->region_set_map(E->get().region, RID());
}
q.navpoly_ids.clear();
}
@@ -398,7 +399,7 @@ void TileMap::update_dirty_quadrants() {
//moment of truth
if (!tile_set->has_tile(c.id))
continue;
- Ref<Texture> tex = tile_set->tile_get_texture(c.id);
+ Ref<Texture2D> tex = tile_set->tile_get_texture(c.id);
Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id);
Vector2 wofs = _map_to_world(E->key().x, E->key().y);
@@ -541,7 +542,7 @@ void TileMap::update_dirty_quadrants() {
rect.position += tile_ofs;
}
- Ref<Texture> normal_map = tile_set->tile_get_normal_map(c.id);
+ Ref<Texture2D> normal_map = tile_set->tile_get_normal_map(c.id);
Color modulate = tile_set->tile_get_modulate(c.id);
Color self_modulate = get_self_modulate();
modulate = Color(modulate.r * self_modulate.r, modulate.g * self_modulate.g,
@@ -549,7 +550,7 @@ void TileMap::update_dirty_quadrants() {
if (r == Rect2()) {
tex->draw_rect(canvas_item, rect, false, modulate, c.transpose, normal_map);
} else {
- tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose, normal_map, clip_uv);
+ tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose, normal_map, Ref<Texture2D>(), Color(1, 1, 1, 1), VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, clip_uv);
}
Vector<TileSet::ShapeData> shapes = tile_set->tile_get_shapes(c.id);
@@ -611,10 +612,13 @@ void TileMap::update_dirty_quadrants() {
xform.set_origin(offset.floor() + q.pos);
_fix_cell_transform(xform, c, npoly_ofs, s);
- int pid = navigation->navpoly_add(navpoly, nav_rel * xform);
+ RID region = Navigation2DServer::get_singleton()->region_create();
+ Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid());
+ Navigation2DServer::get_singleton()->region_set_transform(region, nav_rel * xform);
+ Navigation2DServer::get_singleton()->region_set_navpoly(region, navpoly);
Quadrant::NavPoly np;
- np.id = pid;
+ np.region = region;
np.xform = xform;
q.navpoly_ids[E->key()] = np;
@@ -809,7 +813,7 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
if (navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
- navigation->navpoly_remove(E->get().id);
+ Navigation2DServer::get_singleton()->region_set_map(E->get().region, RID());
}
q.navpoly_ids.clear();
}
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 0875d197eb..d5ef7fc818 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -139,7 +139,7 @@ private:
SelfList<Quadrant> dirty_list;
struct NavPoly {
- int id;
+ RID region;
Transform2D xform;
};
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 42d9f88a60..beff74f496 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -34,24 +34,24 @@
#include "core/os/input.h"
#include "core/os/os.h"
-void TouchScreenButton::set_texture(const Ref<Texture> &p_texture) {
+void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) {
texture = p_texture;
update();
}
-Ref<Texture> TouchScreenButton::get_texture() const {
+Ref<Texture2D> TouchScreenButton::get_texture() const {
return texture;
}
-void TouchScreenButton::set_texture_pressed(const Ref<Texture> &p_texture_pressed) {
+void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pressed) {
texture_pressed = p_texture_pressed;
update();
}
-Ref<Texture> TouchScreenButton::get_texture_pressed() const {
+Ref<Texture2D> TouchScreenButton::get_texture_pressed() const {
return texture_pressed;
}
@@ -397,8 +397,8 @@ void TouchScreenButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("_input"), &TouchScreenButton::_input);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture_pressed", "get_texture_pressed");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed");
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");
diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h
index 28dba59402..42e93f7048 100644
--- a/scene/2d/touch_screen_button.h
+++ b/scene/2d/touch_screen_button.h
@@ -47,8 +47,8 @@ public:
};
private:
- Ref<Texture> texture;
- Ref<Texture> texture_pressed;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> texture_pressed;
Ref<BitMap> bitmask;
Ref<Shape2D> shape;
bool shape_centered;
@@ -79,11 +79,11 @@ public:
virtual bool _edit_use_rect() const;
#endif
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
- void set_texture_pressed(const Ref<Texture> &p_texture_pressed);
- Ref<Texture> get_texture_pressed() const;
+ void set_texture_pressed(const Ref<Texture2D> &p_texture_pressed);
+ Ref<Texture2D> get_texture_pressed() const;
void set_bitmask(const Ref<BitMap> &p_bitmask);
Ref<BitMap> get_bitmask() const;
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 67f57a1aa3..62908e2b0f 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -147,7 +147,7 @@ void Area::_body_exit_tree(ObjectID p_id) {
}
}
-void Area::_body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape) {
+void Area::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) {
bool body_in = p_status == PhysicsServer::AREA_BODY_ADDED;
ObjectID objid = p_instance;
@@ -340,7 +340,7 @@ void Area::_area_exit_tree(ObjectID p_id) {
}
}
-void Area::_area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape) {
+void Area::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) {
bool area_in = p_status == PhysicsServer::AREA_BODY_ADDED;
ObjectID objid = p_instance;
diff --git a/scene/3d/area.h b/scene/3d/area.h
index ca66f41f60..7fe61430fa 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -62,7 +62,7 @@ private:
bool monitorable;
bool locked;
- void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape);
+ void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape);
void _body_enter_tree(ObjectID p_id);
void _body_exit_tree(ObjectID p_id);
@@ -94,7 +94,7 @@ private:
Map<ObjectID, BodyState> body_map;
- void _area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape);
+ void _area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape);
void _area_enter_tree(ObjectID p_id);
void _area_exit_tree(ObjectID p_id);
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp
index 2234304e79..31a80bc2db 100644
--- a/scene/3d/baked_lightmap.cpp
+++ b/scene/3d/baked_lightmap.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#if 0
#include "baked_lightmap.h"
#include "core/io/config_file.h"
#include "core/io/resource_saver.h"
@@ -86,7 +87,7 @@ float BakedLightmapData::get_energy() const {
return energy;
}
-void BakedLightmapData::add_user(const NodePath &p_path, const Ref<Texture> &p_lightmap, int p_instance) {
+void BakedLightmapData::add_user(const NodePath &p_path, const Ref<Texture2D> &p_lightmap, int p_instance) {
ERR_FAIL_COND_MSG(p_lightmap.is_null(), "It's not a reference to a valid Texture object.");
User user;
@@ -105,9 +106,9 @@ NodePath BakedLightmapData::get_user_path(int p_user) const {
ERR_FAIL_INDEX_V(p_user, users.size(), NodePath());
return users[p_user].path;
}
-Ref<Texture> BakedLightmapData::get_user_lightmap(int p_user) const {
+Ref<Texture2D> BakedLightmapData::get_user_lightmap(int p_user) const {
- ERR_FAIL_INDEX_V(p_user, users.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_user, users.size(), Ref<Texture2D>());
return users[p_user].lightmap;
}
@@ -360,7 +361,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
//check for valid save path
DirAccessRef d = DirAccess::open(save_path);
if (!d) {
- ERR_PRINTS("Invalid Save Path '" + save_path + "'.");
+ ERR_PRINT("Invalid Save Path '" + save_path + "'.");
return BAKE_ERROR_NO_SAVE_PATH;
}
}
@@ -368,7 +369,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
Ref<BakedLightmapData> new_light_data;
new_light_data.instance();
- VoxelLightBaker baker;
+ Voxelizer baker;
int bake_subdiv;
int capture_subdiv;
@@ -413,7 +414,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
}
pmc = 0;
- baker.begin_bake_light(VoxelLightBaker::BakeQuality(bake_quality), VoxelLightBaker::BakeMode(bake_mode), propagation, energy);
+ baker.begin_bake_light(Voxelizer::BakeQuality(bake_quality), Voxelizer::BakeMode(bake_mode), propagation, energy);
for (List<PlotLight>::Element *E = light_list.front(); E; E = E->next()) {
@@ -465,7 +466,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
used_mesh_names.insert(mesh_name);
pmc++;
- VoxelLightBaker::LightMapData lm;
+ Voxelizer::LightMapData lm;
Error err;
if (bake_step_function) {
@@ -491,7 +492,6 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
Ref<Image> image;
image.instance();
- uint32_t tex_flags = Texture::FLAGS_DEFAULT;
if (hdr) {
//just save a regular image
@@ -534,11 +534,10 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
//This texture is saved to SRGB for two reasons:
// 1) first is so it looks better when doing the LINEAR->SRGB conversion (more accurate)
// 2) So it can be used in the GLES2 backend, which does not support linkear workflow
- tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR;
}
String image_path = save_path.plus_file(mesh_name);
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
if (ResourceLoader::import) {
@@ -583,7 +582,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
tex.instance();
}
- tex->create_from_image(image, tex_flags);
+ tex->create_from_image(image);
err = ResourceSaver::save(image_path, tex, ResourceSaver::FLAG_CHANGE_PATH);
if (set_path) {
@@ -628,7 +627,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
if (p_create_visual_debug) {
MultiMeshInstance *mmi = memnew(MultiMeshInstance);
- mmi->set_multimesh(baker.create_debug_multimesh(VoxelLightBaker::DEBUG_LIGHT));
+ mmi->set_multimesh(baker.create_debug_multimesh(Voxelizer::DEBUG_LIGHT));
add_child(mmi);
#ifdef TOOLS_ENABLED
if (get_tree()->get_edited_scene_root() == this) {
@@ -668,7 +667,7 @@ void BakedLightmap::_assign_lightmaps() {
ERR_FAIL_COND(!light_data.is_valid());
for (int i = 0; i < light_data->get_user_count(); i++) {
- Ref<Texture> lightmap = light_data->get_user_lightmap(i);
+ Ref<Texture2D> lightmap = light_data->get_user_lightmap(i);
ERR_CONTINUE(!lightmap.is_valid());
Node *node = get_node(light_data->get_user_path(i));
@@ -862,3 +861,4 @@ BakedLightmap::BakedLightmap() {
image_path = ".";
set_disable_scale(true);
}
+#endif
diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h
index 82354cc9f0..0633ffa641 100644
--- a/scene/3d/baked_lightmap.h
+++ b/scene/3d/baked_lightmap.h
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#if 0
#ifndef BAKED_INDIRECT_LIGHT_H
#define BAKED_INDIRECT_LIGHT_H
@@ -47,7 +48,7 @@ class BakedLightmapData : public Resource {
struct User {
NodePath path;
- Ref<Texture> lightmap;
+ Ref<Texture2D> lightmap;
int instance_index;
};
@@ -75,10 +76,10 @@ public:
void set_energy(float p_energy);
float get_energy() const;
- void add_user(const NodePath &p_path, const Ref<Texture> &p_lightmap, int p_instance = -1);
+ void add_user(const NodePath &p_path, const Ref<Texture2D> &p_lightmap, int p_instance = -1);
int get_user_count() const;
NodePath get_user_path(int p_user) const;
- Ref<Texture> get_user_lightmap(int p_user) const;
+ Ref<Texture2D> get_user_lightmap(int p_user) const;
int get_user_instance(int p_user) const;
void clear_users();
@@ -211,4 +212,5 @@ VARIANT_ENUM_CAST(BakedLightmap::BakeQuality);
VARIANT_ENUM_CAST(BakedLightmap::BakeMode);
VARIANT_ENUM_CAST(BakedLightmap::BakeError);
+#endif
#endif // BAKED_INDIRECT_LIGHT_H
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index 640189a26e..ac8d50c419 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -445,6 +445,21 @@ Ref<Environment> Camera::get_environment() const {
return environment;
}
+void Camera::set_effects(const Ref<CameraEffects> &p_effects) {
+
+ effects = p_effects;
+ if (effects.is_valid())
+ VS::get_singleton()->camera_set_camera_effects(camera, effects->get_rid());
+ else
+ VS::get_singleton()->camera_set_camera_effects(camera, RID());
+ _update_camera_mode();
+}
+
+Ref<CameraEffects> Camera::get_effects() const {
+
+ return effects;
+}
+
void Camera::set_keep_aspect_mode(KeepAspect p_aspect) {
keep_aspect = p_aspect;
VisualServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH);
@@ -512,6 +527,8 @@ void Camera::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cull_mask"), &Camera::get_cull_mask);
ClassDB::bind_method(D_METHOD("set_environment", "env"), &Camera::set_environment);
ClassDB::bind_method(D_METHOD("get_environment"), &Camera::get_environment);
+ ClassDB::bind_method(D_METHOD("set_effects", "env"), &Camera::set_effects);
+ ClassDB::bind_method(D_METHOD("get_effects"), &Camera::get_effects);
ClassDB::bind_method(D_METHOD("set_keep_aspect_mode", "mode"), &Camera::set_keep_aspect_mode);
ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode);
ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking);
@@ -527,6 +544,7 @@ void Camera::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height"), "set_keep_aspect_mode", "get_keep_aspect_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_effects", "get_effects");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset");
ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking");
diff --git a/scene/3d/camera.h b/scene/3d/camera.h
index e215783a58..6ac3ece798 100644
--- a/scene/3d/camera.h
+++ b/scene/3d/camera.h
@@ -82,6 +82,7 @@ private:
uint32_t layers;
Ref<Environment> environment;
+ Ref<CameraEffects> effects;
virtual bool _can_gizmo_scale() const;
@@ -157,6 +158,9 @@ public:
void set_environment(const Ref<Environment> &p_environment);
Ref<Environment> get_environment() const;
+ void set_effects(const Ref<CameraEffects> &p_effects);
+ Ref<CameraEffects> get_effects() const;
+
void set_keep_aspect_mode(KeepAspect p_aspect);
KeepAspect get_keep_aspect_mode() const;
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
index aa7a413548..6e26f7ce8f 100644
--- a/scene/3d/cpu_particles.cpp
+++ b/scene/3d/cpu_particles.cpp
@@ -72,8 +72,8 @@ void CPUParticles::set_amount(int p_amount) {
}
}
- particle_data.resize((12 + 4 + 1) * p_amount);
- VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_8BIT, VS::MULTIMESH_CUSTOM_DATA_FLOAT);
+ particle_data.resize((12 + 4 + 4) * p_amount);
+ VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_3D, true, true);
particle_order.resize(p_amount);
}
@@ -209,14 +209,14 @@ String CPUParticles::get_configuration_warning() const {
mesh_found = true;
for (int j = 0; j < get_mesh()->get_surface_count(); j++) {
anim_material_found = Object::cast_to<ShaderMaterial>(get_mesh()->surface_get_material(j).ptr()) != NULL;
- SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_mesh()->surface_get_material(j).ptr());
- anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);
+ StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_mesh()->surface_get_material(j).ptr());
+ anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
}
}
anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL;
- SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_material_override().ptr());
- anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);
+ StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_material_override().ptr());
+ anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
if (!mesh_found) {
if (warnings != String())
@@ -228,7 +228,7 @@ String CPUParticles::get_configuration_warning() const {
get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) {
if (warnings != String())
warnings += "\n";
- warnings += "- " + TTR("CPUParticles animation requires the usage of a SpatialMaterial whose Billboard Mode is set to \"Particle Billboard\".");
+ warnings += "- " + TTR("CPUParticles animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\".");
}
return warnings;
@@ -1093,18 +1093,18 @@ void CPUParticles::_update_particle_data_buffer() {
}
Color c = r[idx].color;
- uint8_t *data8 = (uint8_t *)&ptr[12];
- data8[0] = CLAMP(c.r * 255.0, 0, 255);
- data8[1] = CLAMP(c.g * 255.0, 0, 255);
- data8[2] = CLAMP(c.b * 255.0, 0, 255);
- data8[3] = CLAMP(c.a * 255.0, 0, 255);
-
- ptr[13] = r[idx].custom[0];
- ptr[14] = r[idx].custom[1];
- ptr[15] = r[idx].custom[2];
- ptr[16] = r[idx].custom[3];
-
- ptr += 17;
+
+ ptr[12] = c.r;
+ ptr[13] = c.g;
+ ptr[14] = c.b;
+ ptr[15] = c.a;
+
+ ptr[16] = r[idx].custom[0];
+ ptr[17] = r[idx].custom[1];
+ ptr[18] = r[idx].custom[2];
+ ptr[19] = r[idx].custom[3];
+
+ ptr += 20;
}
can_update = true;
@@ -1144,7 +1144,7 @@ void CPUParticles::_update_render_thread() {
update_mutex->lock();
#endif
if (can_update) {
- VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
+ VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
can_update = false; //wait for next time
}
@@ -1210,7 +1210,7 @@ void CPUParticles::_notification(int p_what) {
zeromem(ptr, sizeof(float) * 12);
}
- ptr += 17;
+ ptr += 20;
}
can_update = true;
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 99bc78f5d2..34540525af 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -32,116 +32,183 @@
#include "core/os/os.h"
+#include "core/method_bind_ext.gen.inc"
#include "mesh_instance.h"
-#include "voxel_light_baker.h"
+#include "voxelizer.h"
+
+void GIProbeData::_set_data(const Dictionary &p_data) {
+ ERR_FAIL_COND(!p_data.has("bounds"));
+ ERR_FAIL_COND(!p_data.has("octree_size"));
+ ERR_FAIL_COND(!p_data.has("octree_cells"));
+ ERR_FAIL_COND(!p_data.has("octree_data"));
+ ERR_FAIL_COND(!p_data.has("octree_df") && !p_data.has("octree_df_png"));
+ ERR_FAIL_COND(!p_data.has("level_counts"));
+ ERR_FAIL_COND(!p_data.has("to_cell_xform"));
+
+ AABB bounds = p_data["bounds"];
+ Vector3 octree_size = p_data["octree_size"];
+ PoolVector<uint8_t> octree_cells = p_data["octree_cells"];
+ PoolVector<uint8_t> octree_data = p_data["octree_data"];
+
+ PoolVector<uint8_t> octree_df;
+ if (p_data.has("octree_df")) {
+ octree_df = p_data["octree_df"];
+ } else if (p_data.has("octree_df_png")) {
+ PoolVector<uint8_t> octree_df_png = p_data["octree_df_png"];
+ Ref<Image> img;
+ img.instance();
+ Error err = img->load_png_from_buffer(octree_df_png);
+ ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND(img->get_format() != Image::FORMAT_L8);
+ octree_df = img->get_data();
+ }
+ PoolVector<int> octree_levels = p_data["level_counts"];
+ Transform to_cell_xform = p_data["to_cell_xform"];
+
+ allocate(to_cell_xform, bounds, octree_size, octree_cells, octree_data, octree_df, octree_levels);
+}
+
+Dictionary GIProbeData::_get_data() const {
+ Dictionary d;
+ d["bounds"] = get_bounds();
+ Vector3i otsize = get_octree_size();
+ d["octree_size"] = Vector3(otsize);
+ d["octree_cells"] = get_octree_cells();
+ d["octree_data"] = get_data_cells();
+ if (otsize != Vector3i()) {
+ Ref<Image> img;
+ img.instance();
+ img->create(otsize.x * otsize.y, otsize.z, false, Image::FORMAT_L8, get_distance_field());
+ PoolVector<uint8_t> df_png = img->save_png_to_buffer();
+ ERR_FAIL_COND_V(df_png.size() == 0, Dictionary());
+ d["octree_df_png"] = df_png;
+ } else {
+ d["octree_df"] = PoolVector<uint8_t>();
+ }
-void GIProbeData::set_bounds(const AABB &p_bounds) {
+ d["level_counts"] = get_level_counts();
+ d["to_cell_xform"] = get_to_cell_xform();
+ return d;
+}
- VS::get_singleton()->gi_probe_set_bounds(probe, p_bounds);
+void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const PoolVector<uint8_t> &p_octree_cells, const PoolVector<uint8_t> &p_data_cells, const PoolVector<uint8_t> &p_distance_field, const PoolVector<int> &p_level_counts) {
+ VS::get_singleton()->gi_probe_allocate(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts);
+ bounds = p_aabb;
+ to_cell_xform = p_to_cell_xform;
+ octree_size = p_octree_size;
}
AABB GIProbeData::get_bounds() const {
-
- return VS::get_singleton()->gi_probe_get_bounds(probe);
+ return bounds;
}
-
-void GIProbeData::set_cell_size(float p_size) {
-
- VS::get_singleton()->gi_probe_set_cell_size(probe, p_size);
+Vector3 GIProbeData::get_octree_size() const {
+ return octree_size;
}
-
-float GIProbeData::get_cell_size() const {
-
- return VS::get_singleton()->gi_probe_get_cell_size(probe);
+PoolVector<uint8_t> GIProbeData::get_octree_cells() const {
+ return VS::get_singleton()->gi_probe_get_octree_cells(probe);
}
-
-void GIProbeData::set_to_cell_xform(const Transform &p_xform) {
-
- VS::get_singleton()->gi_probe_set_to_cell_xform(probe, p_xform);
+PoolVector<uint8_t> GIProbeData::get_data_cells() const {
+ return VS::get_singleton()->gi_probe_get_data_cells(probe);
+}
+PoolVector<uint8_t> GIProbeData::get_distance_field() const {
+ return VS::get_singleton()->gi_probe_get_distance_field(probe);
}
+PoolVector<int> GIProbeData::get_level_counts() const {
+ return VS::get_singleton()->gi_probe_get_level_counts(probe);
+}
Transform GIProbeData::get_to_cell_xform() const {
-
- return VS::get_singleton()->gi_probe_get_to_cell_xform(probe);
+ return to_cell_xform;
}
-void GIProbeData::set_dynamic_data(const PoolVector<int> &p_data) {
+void GIProbeData::set_dynamic_range(float p_range) {
+ VS::get_singleton()->gi_probe_set_dynamic_range(probe, p_range);
+ dynamic_range = p_range;
+}
- VS::get_singleton()->gi_probe_set_dynamic_data(probe, p_data);
+float GIProbeData::get_dynamic_range() const {
+ return dynamic_range;
}
-PoolVector<int> GIProbeData::get_dynamic_data() const {
- return VS::get_singleton()->gi_probe_get_dynamic_data(probe);
+void GIProbeData::set_propagation(float p_propagation) {
+ VS::get_singleton()->gi_probe_set_propagation(probe, p_propagation);
+ propagation = p_propagation;
}
-void GIProbeData::set_dynamic_range(int p_range) {
+float GIProbeData::get_propagation() const {
+ return propagation;
+}
- VS::get_singleton()->gi_probe_set_dynamic_range(probe, p_range);
+void GIProbeData::set_anisotropy_strength(float p_anisotropy_strength) {
+ VS::get_singleton()->gi_probe_set_anisotropy_strength(probe, p_anisotropy_strength);
+ anisotropy_strength = p_anisotropy_strength;
}
-void GIProbeData::set_energy(float p_range) {
+float GIProbeData::get_anisotropy_strength() const {
+ return anisotropy_strength;
+}
- VS::get_singleton()->gi_probe_set_energy(probe, p_range);
+void GIProbeData::set_energy(float p_energy) {
+ VS::get_singleton()->gi_probe_set_energy(probe, p_energy);
+ energy = p_energy;
}
float GIProbeData::get_energy() const {
-
- return VS::get_singleton()->gi_probe_get_energy(probe);
+ return energy;
}
-void GIProbeData::set_bias(float p_range) {
-
- VS::get_singleton()->gi_probe_set_bias(probe, p_range);
+void GIProbeData::set_ao(float p_ao) {
+ VS::get_singleton()->gi_probe_set_ao(probe, p_ao);
+ ao = p_ao;
}
-float GIProbeData::get_bias() const {
-
- return VS::get_singleton()->gi_probe_get_bias(probe);
+float GIProbeData::get_ao() const {
+ return ao;
}
-void GIProbeData::set_normal_bias(float p_range) {
-
- VS::get_singleton()->gi_probe_set_normal_bias(probe, p_range);
+void GIProbeData::set_ao_size(float p_ao_size) {
+ VS::get_singleton()->gi_probe_set_ao_size(probe, p_ao_size);
+ ao_size = p_ao_size;
}
-float GIProbeData::get_normal_bias() const {
-
- return VS::get_singleton()->gi_probe_get_normal_bias(probe);
+float GIProbeData::get_ao_size() const {
+ return ao_size;
}
-void GIProbeData::set_propagation(float p_range) {
+void GIProbeData::set_bias(float p_bias) {
+ VS::get_singleton()->gi_probe_set_bias(probe, p_bias);
+ bias = p_bias;
+}
- VS::get_singleton()->gi_probe_set_propagation(probe, p_range);
+float GIProbeData::get_bias() const {
+ return bias;
}
-float GIProbeData::get_propagation() const {
+void GIProbeData::set_normal_bias(float p_normal_bias) {
+ VS::get_singleton()->gi_probe_set_normal_bias(probe, p_normal_bias);
+ normal_bias = p_normal_bias;
+}
- return VS::get_singleton()->gi_probe_get_propagation(probe);
+float GIProbeData::get_normal_bias() const {
+ return normal_bias;
}
void GIProbeData::set_interior(bool p_enable) {
-
VS::get_singleton()->gi_probe_set_interior(probe, p_enable);
+ interior = p_enable;
}
bool GIProbeData::is_interior() const {
-
- return VS::get_singleton()->gi_probe_is_interior(probe);
-}
-
-bool GIProbeData::is_compressed() const {
-
- return VS::get_singleton()->gi_probe_is_compressed(probe);
+ return interior;
}
-void GIProbeData::set_compress(bool p_enable) {
-
- VS::get_singleton()->gi_probe_set_compress(probe, p_enable);
+void GIProbeData::set_use_two_bounces(bool p_enable) {
+ VS::get_singleton()->gi_probe_set_use_two_bounces(probe, p_enable);
+ use_two_bounces = p_enable;
}
-int GIProbeData::get_dynamic_range() const {
-
- return VS::get_singleton()->gi_probe_get_dynamic_range(probe);
+bool GIProbeData::is_using_two_bounces() const {
+ return use_two_bounces;
}
RID GIProbeData::get_rid() const {
@@ -149,19 +216,24 @@ RID GIProbeData::get_rid() const {
return probe;
}
+void GIProbeData::_validate_property(PropertyInfo &property) const {
+ if (property.name == "anisotropy_strength") {
+ bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/quality/gi_probes/anisotropic");
+ if (!anisotropy_enabled) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+ }
+}
+
void GIProbeData::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("allocate", "to_cell_xform", "aabb", "octree_size", "octree_cells", "data_cells", "distance_field", "level_counts"), &GIProbeData::allocate);
- ClassDB::bind_method(D_METHOD("set_bounds", "bounds"), &GIProbeData::set_bounds);
ClassDB::bind_method(D_METHOD("get_bounds"), &GIProbeData::get_bounds);
-
- ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &GIProbeData::set_cell_size);
- ClassDB::bind_method(D_METHOD("get_cell_size"), &GIProbeData::get_cell_size);
-
- ClassDB::bind_method(D_METHOD("set_to_cell_xform", "to_cell_xform"), &GIProbeData::set_to_cell_xform);
+ ClassDB::bind_method(D_METHOD("get_octree_size"), &GIProbeData::get_octree_size);
ClassDB::bind_method(D_METHOD("get_to_cell_xform"), &GIProbeData::get_to_cell_xform);
-
- ClassDB::bind_method(D_METHOD("set_dynamic_data", "dynamic_data"), &GIProbeData::set_dynamic_data);
- ClassDB::bind_method(D_METHOD("get_dynamic_data"), &GIProbeData::get_dynamic_data);
+ ClassDB::bind_method(D_METHOD("get_octree_cells"), &GIProbeData::get_octree_cells);
+ ClassDB::bind_method(D_METHOD("get_data_cells"), &GIProbeData::get_data_cells);
+ ClassDB::bind_method(D_METHOD("get_level_counts"), &GIProbeData::get_level_counts);
ClassDB::bind_method(D_METHOD("set_dynamic_range", "dynamic_range"), &GIProbeData::set_dynamic_range);
ClassDB::bind_method(D_METHOD("get_dynamic_range"), &GIProbeData::get_dynamic_range);
@@ -178,28 +250,50 @@ void GIProbeData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_propagation", "propagation"), &GIProbeData::set_propagation);
ClassDB::bind_method(D_METHOD("get_propagation"), &GIProbeData::get_propagation);
+ ClassDB::bind_method(D_METHOD("set_anisotropy_strength", "strength"), &GIProbeData::set_anisotropy_strength);
+ ClassDB::bind_method(D_METHOD("get_anisotropy_strength"), &GIProbeData::get_anisotropy_strength);
+
+ ClassDB::bind_method(D_METHOD("set_ao", "ao"), &GIProbeData::set_ao);
+ ClassDB::bind_method(D_METHOD("get_ao"), &GIProbeData::get_ao);
+
+ ClassDB::bind_method(D_METHOD("set_ao_size", "strength"), &GIProbeData::set_ao_size);
+ ClassDB::bind_method(D_METHOD("get_ao_size"), &GIProbeData::get_ao_size);
+
ClassDB::bind_method(D_METHOD("set_interior", "interior"), &GIProbeData::set_interior);
ClassDB::bind_method(D_METHOD("is_interior"), &GIProbeData::is_interior);
- ClassDB::bind_method(D_METHOD("set_compress", "compress"), &GIProbeData::set_compress);
- ClassDB::bind_method(D_METHOD("is_compressed"), &GIProbeData::is_compressed);
+ ClassDB::bind_method(D_METHOD("set_use_two_bounces", "enable"), &GIProbeData::set_use_two_bounces);
+ ClassDB::bind_method(D_METHOD("is_using_two_bounces"), &GIProbeData::is_using_two_bounces);
+
+ ClassDB::bind_method(D_METHOD("_set_data", "data"), &GIProbeData::_set_data);
+ ClassDB::bind_method(D_METHOD("_get_data"), &GIProbeData::_get_data);
- ADD_PROPERTY(PropertyInfo(Variant::AABB, "bounds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bounds", "get_bounds");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_size", "get_cell_size");
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "to_cell_xform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_to_cell_xform", "get_to_cell_xform");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "dynamic_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_dynamic_data", "get_dynamic_data");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "dynamic_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_dynamic_range", "get_dynamic_range");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_energy", "get_energy");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bias", "get_bias");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_bias", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_normal_bias", "get_normal_bias");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "propagation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_propagation", "get_propagation");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_interior", "is_interior");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_compress", "is_compressed");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "dynamic_range", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_dynamic_range", "get_dynamic_range");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_energy", "get_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_bias", "get_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_bias", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_normal_bias", "get_normal_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_propagation", "get_propagation");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "anisotropy_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_anisotropy_strength", "get_anisotropy_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ao", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao", "get_ao");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ao_size", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao_size", "get_ao_size");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_two_bounces"), "set_use_two_bounces", "is_using_two_bounces");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior");
}
GIProbeData::GIProbeData() {
+ ao = 0.0;
+ ao_size = 0.5;
+ dynamic_range = 4;
+ energy = 1.0;
+ bias = 1.5;
+ normal_bias = 0.0;
+ propagation = 0.7;
+ anisotropy_strength = 0.5;
+ interior = false;
+
probe = VS::get_singleton()->gi_probe_create();
}
@@ -251,89 +345,6 @@ Vector3 GIProbe::get_extents() const {
return extents;
}
-void GIProbe::set_dynamic_range(int p_dynamic_range) {
-
- dynamic_range = p_dynamic_range;
-}
-int GIProbe::get_dynamic_range() const {
-
- return dynamic_range;
-}
-
-void GIProbe::set_energy(float p_energy) {
-
- energy = p_energy;
- if (probe_data.is_valid()) {
- probe_data->set_energy(energy);
- }
-}
-float GIProbe::get_energy() const {
-
- return energy;
-}
-
-void GIProbe::set_bias(float p_bias) {
-
- bias = p_bias;
- if (probe_data.is_valid()) {
- probe_data->set_bias(bias);
- }
-}
-float GIProbe::get_bias() const {
-
- return bias;
-}
-
-void GIProbe::set_normal_bias(float p_normal_bias) {
-
- normal_bias = p_normal_bias;
- if (probe_data.is_valid()) {
- probe_data->set_normal_bias(normal_bias);
- }
-}
-float GIProbe::get_normal_bias() const {
-
- return normal_bias;
-}
-
-void GIProbe::set_propagation(float p_propagation) {
-
- propagation = p_propagation;
- if (probe_data.is_valid()) {
- probe_data->set_propagation(propagation);
- }
-}
-float GIProbe::get_propagation() const {
-
- return propagation;
-}
-
-void GIProbe::set_interior(bool p_enable) {
-
- interior = p_enable;
- if (probe_data.is_valid()) {
- probe_data->set_interior(p_enable);
- }
-}
-
-bool GIProbe::is_interior() const {
-
- return interior;
-}
-
-void GIProbe::set_compress(bool p_enable) {
-
- compress = p_enable;
- if (probe_data.is_valid()) {
- probe_data->set_compress(p_enable);
- }
-}
-
-bool GIProbe::is_compressed() const {
-
- return compress;
-}
-
void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) {
MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node);
@@ -395,11 +406,36 @@ GIProbe::BakeBeginFunc GIProbe::bake_begin_function = NULL;
GIProbe::BakeStepFunc GIProbe::bake_step_function = NULL;
GIProbe::BakeEndFunc GIProbe::bake_end_function = NULL;
+Vector3i GIProbe::get_estimated_cell_size() const {
+ static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 };
+ int cell_subdiv = subdiv_value[subdiv];
+ int axis_cell_size[3];
+ AABB bounds = AABB(-extents, extents * 2.0);
+ int longest_axis = bounds.get_longest_axis_index();
+ axis_cell_size[longest_axis] = 1 << cell_subdiv;
+
+ for (int i = 0; i < 3; i++) {
+
+ if (i == longest_axis)
+ continue;
+
+ axis_cell_size[i] = axis_cell_size[longest_axis];
+ float axis_size = bounds.size[longest_axis];
+
+ //shrink until fit subdiv
+ while (axis_size / 2.0 >= bounds.size[i]) {
+ axis_size /= 2.0;
+ axis_cell_size[i] >>= 1;
+ }
+ }
+
+ return Vector3i(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]);
+}
void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
- static const int subdiv_value[SUBDIV_MAX] = { 7, 8, 9, 10 };
+ static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 };
- VoxelLightBaker baker;
+ Voxelizer baker;
baker.begin_bake(subdiv_value[subdiv], AABB(-extents, extents * 2.0));
@@ -431,8 +467,6 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
//create the data for visual server
- PoolVector<int> data = baker.create_gi_probe_data();
-
if (p_create_visual_debug) {
MultiMeshInstance *mmi = memnew(MultiMeshInstance);
mmi->set_multimesh(baker.create_debug_multimesh());
@@ -454,24 +488,25 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
if (probe_data.is_null())
probe_data.instance();
- probe_data->set_bounds(AABB(-extents, extents * 2.0));
- probe_data->set_cell_size(baker.get_cell_size());
- probe_data->set_dynamic_data(data);
- probe_data->set_dynamic_range(dynamic_range);
- probe_data->set_energy(energy);
- probe_data->set_bias(bias);
- probe_data->set_normal_bias(normal_bias);
- probe_data->set_propagation(propagation);
- probe_data->set_interior(interior);
- probe_data->set_compress(compress);
- probe_data->set_to_cell_xform(baker.get_to_cell_space_xform());
+ if (bake_step_function) {
+ bake_step_function(pmc++, RTR("Generating Distance Field"));
+ }
+
+ PoolVector<uint8_t> df = baker.get_sdf_3d_image();
+
+ probe_data->allocate(baker.get_to_cell_space_xform(), AABB(-extents, extents * 2.0), baker.get_giprobe_octree_size(), baker.get_giprobe_octree_cells(), baker.get_giprobe_data_cells(), df, baker.get_giprobe_level_cell_count());
set_probe_data(probe_data);
+#ifdef TOOLS_ENABLED
+ probe_data->set_edited(true); //so it gets saved
+#endif
}
if (bake_end_function) {
bake_end_function();
}
+
+ _change_notify(); //bake property may have changed
}
void GIProbe::_debug_bake() {
@@ -508,40 +543,12 @@ void GIProbe::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GIProbe::set_extents);
ClassDB::bind_method(D_METHOD("get_extents"), &GIProbe::get_extents);
- ClassDB::bind_method(D_METHOD("set_dynamic_range", "max"), &GIProbe::set_dynamic_range);
- ClassDB::bind_method(D_METHOD("get_dynamic_range"), &GIProbe::get_dynamic_range);
-
- ClassDB::bind_method(D_METHOD("set_energy", "max"), &GIProbe::set_energy);
- ClassDB::bind_method(D_METHOD("get_energy"), &GIProbe::get_energy);
-
- ClassDB::bind_method(D_METHOD("set_bias", "max"), &GIProbe::set_bias);
- ClassDB::bind_method(D_METHOD("get_bias"), &GIProbe::get_bias);
-
- ClassDB::bind_method(D_METHOD("set_normal_bias", "max"), &GIProbe::set_normal_bias);
- ClassDB::bind_method(D_METHOD("get_normal_bias"), &GIProbe::get_normal_bias);
-
- ClassDB::bind_method(D_METHOD("set_propagation", "max"), &GIProbe::set_propagation);
- ClassDB::bind_method(D_METHOD("get_propagation"), &GIProbe::get_propagation);
-
- ClassDB::bind_method(D_METHOD("set_interior", "enable"), &GIProbe::set_interior);
- ClassDB::bind_method(D_METHOD("is_interior"), &GIProbe::is_interior);
-
- ClassDB::bind_method(D_METHOD("set_compress", "enable"), &GIProbe::set_compress);
- ClassDB::bind_method(D_METHOD("is_compressed"), &GIProbe::is_compressed);
-
ClassDB::bind_method(D_METHOD("bake", "from_node", "create_visual_debug"), &GIProbe::bake, DEFVAL(Variant()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("debug_bake"), &GIProbe::_debug_bake);
ClassDB::set_method_flags(get_class_static(), _scs_create("debug_bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdiv", PROPERTY_HINT_ENUM, "64,128,256,512"), "set_subdiv", "get_subdiv");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "dynamic_range", PROPERTY_HINT_RANGE, "1,16,1"), "set_dynamic_range", "get_dynamic_range");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_propagation", "get_propagation");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,4,0.001"), "set_bias", "get_bias");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_bias", PROPERTY_HINT_RANGE, "0,4,0.001"), "set_normal_bias", "get_normal_bias");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compress"), "set_compress", "is_compressed");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "GIProbeData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_probe_data", "get_probe_data");
BIND_ENUM_CONSTANT(SUBDIV_64);
@@ -554,14 +561,7 @@ void GIProbe::_bind_methods() {
GIProbe::GIProbe() {
subdiv = SUBDIV_128;
- dynamic_range = 4;
- energy = 1.0;
- bias = 1.5;
- normal_bias = 0.0;
- propagation = 0.7;
extents = Vector3(10, 10, 10);
- interior = false;
- compress = false;
gi_probe = VS::get_singleton()->gi_probe_create();
set_disable_scale(true);
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index 7c58f862e4..60aa1d952c 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -40,42 +40,67 @@ class GIProbeData : public Resource {
RID probe;
+ void _set_data(const Dictionary &p_data);
+ Dictionary _get_data() const;
+
+ Transform to_cell_xform;
+ AABB bounds;
+ Vector3 octree_size;
+
+ float dynamic_range;
+ float energy;
+ float bias;
+ float normal_bias;
+ float propagation;
+ float anisotropy_strength;
+ float ao;
+ float ao_size;
+ bool interior;
+ bool use_two_bounces;
+
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const;
public:
- void set_bounds(const AABB &p_bounds);
+ void allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const PoolVector<uint8_t> &p_octree_cells, const PoolVector<uint8_t> &p_data_cells, const PoolVector<uint8_t> &p_distance_field, const PoolVector<int> &p_level_counts);
AABB get_bounds() const;
+ Vector3 get_octree_size() const;
+ PoolVector<uint8_t> get_octree_cells() const;
+ PoolVector<uint8_t> get_data_cells() const;
+ PoolVector<uint8_t> get_distance_field() const;
+ PoolVector<int> get_level_counts() const;
+ Transform get_to_cell_xform() const;
- void set_cell_size(float p_size);
- float get_cell_size() const;
+ void set_dynamic_range(float p_range);
+ float get_dynamic_range() const;
- void set_to_cell_xform(const Transform &p_xform);
- Transform get_to_cell_xform() const;
+ void set_propagation(float p_propagation);
+ float get_propagation() const;
- void set_dynamic_data(const PoolVector<int> &p_data);
- PoolVector<int> get_dynamic_data() const;
+ void set_anisotropy_strength(float p_anisotropy_strength);
+ float get_anisotropy_strength() const;
- void set_dynamic_range(int p_range);
- int get_dynamic_range() const;
+ void set_ao(float p_ao);
+ float get_ao() const;
- void set_propagation(float p_range);
- float get_propagation() const;
+ void set_ao_size(float p_ao_size);
+ float get_ao_size() const;
- void set_energy(float p_range);
+ void set_energy(float p_energy);
float get_energy() const;
- void set_bias(float p_range);
+ void set_bias(float p_bias);
float get_bias() const;
- void set_normal_bias(float p_range);
+ void set_normal_bias(float p_normal_bias);
float get_normal_bias() const;
void set_interior(bool p_enable);
bool is_interior() const;
- void set_compress(bool p_enable);
- bool is_compressed() const;
+ void set_use_two_bounces(bool p_enable);
+ bool is_using_two_bounces() const;
virtual RID get_rid() const;
@@ -107,13 +132,6 @@ private:
Subdiv subdiv;
Vector3 extents;
- int dynamic_range;
- float energy;
- float bias;
- float normal_bias;
- float propagation;
- bool interior;
- bool compress;
struct PlotMesh {
Ref<Material> override_material;
@@ -141,27 +159,7 @@ public:
void set_extents(const Vector3 &p_extents);
Vector3 get_extents() const;
-
- void set_dynamic_range(int p_dynamic_range);
- int get_dynamic_range() const;
-
- void set_energy(float p_energy);
- float get_energy() const;
-
- void set_bias(float p_bias);
- float get_bias() const;
-
- void set_normal_bias(float p_normal_bias);
- float get_normal_bias() const;
-
- void set_propagation(float p_propagation);
- float get_propagation() const;
-
- void set_interior(bool p_enable);
- bool is_interior() const;
-
- void set_compress(bool p_enable);
- bool is_compressed() const;
+ Vector3i get_estimated_cell_size() const;
void bake(Node *p_from_node = NULL, bool p_create_visual_debug = false);
diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp
index 0a1beaf3f4..afe60226b6 100644
--- a/scene/3d/immediate_geometry.cpp
+++ b/scene/3d/immediate_geometry.cpp
@@ -30,7 +30,7 @@
#include "immediate_geometry.h"
-void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive, const Ref<Texture> &p_texture) {
+void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture) {
VS::get_singleton()->immediate_begin(im, (VS::PrimitiveType)p_primitive, p_texture.is_valid() ? p_texture->get_rid() : RID());
if (p_texture.is_valid())
@@ -144,7 +144,7 @@ void ImmediateGeometry::add_sphere(int p_lats, int p_lons, float p_radius, bool
void ImmediateGeometry::_bind_methods() {
- ClassDB::bind_method(D_METHOD("begin", "primitive", "texture"), &ImmediateGeometry::begin, DEFVAL(Ref<Texture>()));
+ ClassDB::bind_method(D_METHOD("begin", "primitive", "texture"), &ImmediateGeometry::begin, DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("set_normal", "normal"), &ImmediateGeometry::set_normal);
ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &ImmediateGeometry::set_tangent);
ClassDB::bind_method(D_METHOD("set_color", "color"), &ImmediateGeometry::set_color);
diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h
index f45ebd6724..7f506ce9ef 100644
--- a/scene/3d/immediate_geometry.h
+++ b/scene/3d/immediate_geometry.h
@@ -41,7 +41,7 @@ class ImmediateGeometry : public GeometryInstance {
RID im;
//a list of textures drawn need to be kept, to avoid references
// in VisualServer from becoming invalid if the texture is no longer used
- List<Ref<Texture> > cached_textures;
+ List<Ref<Texture2D> > cached_textures;
bool empty;
AABB aabb;
@@ -49,7 +49,7 @@ protected:
static void _bind_methods();
public:
- void begin(Mesh::PrimitiveType p_primitive, const Ref<Texture> &p_texture = Ref<Texture>());
+ void begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture = Ref<Texture2D>());
void set_normal(const Vector3 &p_normal);
void set_tangent(const Plane &p_tangent);
void set_color(const Color &p_color);
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 593d0b95b7..8d3b9bbaf0 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -281,6 +281,7 @@ void Light::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_1_OFFSET);
BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_2_OFFSET);
BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_3_OFFSET);
+ BIND_ENUM_CONSTANT(PARAM_SHADOW_FADE_START);
BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS);
BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS);
BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS_SPLIT_SCALE);
@@ -325,8 +326,10 @@ Light::Light(VisualServer::LightType p_type) {
set_param(PARAM_SHADOW_SPLIT_1_OFFSET, 0.1);
set_param(PARAM_SHADOW_SPLIT_2_OFFSET, 0.2);
set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5);
+ set_param(PARAM_SHADOW_FADE_START, 0.8);
set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0);
set_param(PARAM_SHADOW_BIAS, 0.15);
+ set_param(PARAM_SHADOW_FADE_START, 1);
set_disable_scale(true);
}
@@ -393,6 +396,7 @@ void DirectionalLight::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_1", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_1_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_2", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_2_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_fade_start", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_FADE_START);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS);
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE);
@@ -413,6 +417,7 @@ DirectionalLight::DirectionalLight() :
set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8);
set_param(PARAM_SHADOW_BIAS, 0.1);
set_param(PARAM_SHADOW_MAX_DISTANCE, 100);
+ set_param(PARAM_SHADOW_FADE_START, 0.8);
set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25);
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE);
@@ -431,42 +436,24 @@ OmniLight::ShadowMode OmniLight::get_shadow_mode() const {
return shadow_mode;
}
-void OmniLight::set_shadow_detail(ShadowDetail p_detail) {
-
- shadow_detail = p_detail;
- VS::get_singleton()->light_omni_set_shadow_detail(light, VS::LightOmniShadowDetail(p_detail));
-}
-OmniLight::ShadowDetail OmniLight::get_shadow_detail() const {
-
- return shadow_detail;
-}
-
void OmniLight::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight::set_shadow_mode);
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &OmniLight::get_shadow_mode);
- ClassDB::bind_method(D_METHOD("set_shadow_detail", "detail"), &OmniLight::set_shadow_detail);
- ClassDB::bind_method(D_METHOD("get_shadow_detail"), &OmniLight::get_shadow_detail);
-
ADD_GROUP("Omni", "omni_");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "omni_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE);
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "omni_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION);
ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_mode", PROPERTY_HINT_ENUM, "Dual Paraboloid,Cube"), "set_shadow_mode", "get_shadow_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_detail", PROPERTY_HINT_ENUM, "Vertical,Horizontal"), "set_shadow_detail", "get_shadow_detail");
BIND_ENUM_CONSTANT(SHADOW_DUAL_PARABOLOID);
BIND_ENUM_CONSTANT(SHADOW_CUBE);
-
- BIND_ENUM_CONSTANT(SHADOW_DETAIL_VERTICAL);
- BIND_ENUM_CONSTANT(SHADOW_DETAIL_HORIZONTAL);
}
OmniLight::OmniLight() :
Light(VisualServer::LIGHT_OMNI) {
set_shadow_mode(SHADOW_CUBE);
- set_shadow_detail(SHADOW_DETAIL_HORIZONTAL);
}
String SpotLight::get_configuration_warning() const {
diff --git a/scene/3d/light.h b/scene/3d/light.h
index 272ee8d7a9..7287518ae9 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -54,6 +54,7 @@ public:
PARAM_SHADOW_SPLIT_1_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
PARAM_SHADOW_SPLIT_2_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET,
PARAM_SHADOW_SPLIT_3_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
+ PARAM_SHADOW_FADE_START = VS::LIGHT_PARAM_SHADOW_FADE_START,
PARAM_SHADOW_NORMAL_BIAS = VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS,
PARAM_SHADOW_BIAS = VS::LIGHT_PARAM_SHADOW_BIAS,
PARAM_SHADOW_BIAS_SPLIT_SCALE = VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
@@ -183,15 +184,8 @@ public:
SHADOW_CUBE,
};
- // omni light
- enum ShadowDetail {
- SHADOW_DETAIL_VERTICAL,
- SHADOW_DETAIL_HORIZONTAL
- };
-
private:
ShadowMode shadow_mode;
- ShadowDetail shadow_detail;
protected:
static void _bind_methods();
@@ -200,14 +194,10 @@ public:
void set_shadow_mode(ShadowMode p_mode);
ShadowMode get_shadow_mode() const;
- void set_shadow_detail(ShadowDetail p_detail);
- ShadowDetail get_shadow_detail() const;
-
OmniLight();
};
VARIANT_ENUM_CAST(OmniLight::ShadowMode)
-VARIANT_ENUM_CAST(OmniLight::ShadowDetail)
class SpotLight : public Light {
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
index e14fa9e9af..6d0216d99c 100644
--- a/scene/3d/mesh_instance.cpp
+++ b/scene/3d/mesh_instance.cpp
@@ -101,7 +101,7 @@ void MeshInstance::_get_property_list(List<PropertyInfo> *p_list) const {
if (mesh.is_valid()) {
for (int i = 0; i < mesh->get_surface_count(); i++) {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "material/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "material/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D"));
}
}
}
@@ -355,12 +355,12 @@ void MeshInstance::create_debug_tangents() {
if (lines.size()) {
- Ref<SpatialMaterial> sm;
+ Ref<StandardMaterial3D> sm;
sm.instance();
- sm->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- sm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- sm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ sm->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ sm->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+ sm->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
Ref<ArrayMesh> am;
am.instance();
@@ -409,8 +409,10 @@ void MeshInstance::_bind_methods() {
ClassDB::set_method_flags("MeshInstance", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
+ ADD_GROUP("Skeleton", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skin", PROPERTY_HINT_RESOURCE_TYPE, "Skin"), "set_skin", "get_skin");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton"), "set_skeleton_path", "get_skeleton_path");
+ ADD_GROUP("", "");
}
MeshInstance::MeshInstance() {
diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp
index 4a82fe0080..10b12f5c75 100644
--- a/scene/3d/navigation.cpp
+++ b/scene/3d/navigation.cpp
@@ -30,698 +30,76 @@
#include "navigation.h"
-#define USE_ENTRY_POINT
+#include "servers/navigation_server.h"
-void Navigation::_navmesh_link(int p_id) {
-
- ERR_FAIL_COND(!navmesh_map.has(p_id));
- NavMesh &nm = navmesh_map[p_id];
- ERR_FAIL_COND(nm.linked);
- ERR_FAIL_COND(nm.navmesh.is_null());
-
- PoolVector<Vector3> vertices = nm.navmesh->get_vertices();
- int len = vertices.size();
- if (len == 0)
- return;
-
- PoolVector<Vector3>::Read r = vertices.read();
-
- for (int i = 0; i < nm.navmesh->get_polygon_count(); i++) {
-
- //build
-
- List<Polygon>::Element *P = nm.polygons.push_back(Polygon());
- Polygon &p = P->get();
- p.owner = &nm;
-
- Vector<int> poly = nm.navmesh->get_polygon(i);
- int plen = poly.size();
- const int *indices = poly.ptr();
- bool valid = true;
- p.edges.resize(plen);
-
- Vector3 center;
- float sum = 0;
-
- for (int j = 0; j < plen; j++) {
-
- int idx = indices[j];
- if (idx < 0 || idx >= len) {
- valid = false;
- break;
- }
-
- Polygon::Edge e;
- Vector3 ep = nm.xform.xform(r[idx]);
- center += ep;
- e.point = _get_point(ep);
- p.edges.write[j] = e;
-
- if (j >= 2) {
- Vector3 epa = nm.xform.xform(r[indices[j - 2]]);
- Vector3 epb = nm.xform.xform(r[indices[j - 1]]);
-
- sum += up.dot((epb - epa).cross(ep - epa));
- }
- }
-
- p.clockwise = sum > 0;
-
- if (!valid) {
- nm.polygons.pop_back();
- ERR_CONTINUE(!valid);
- }
-
- p.center = center;
- if (plen != 0) {
- p.center /= plen;
- }
-
- //connect
-
- for (int j = 0; j < plen; j++) {
-
- int next = (j + 1) % plen;
- EdgeKey ek(p.edges[j].point, p.edges[next].point);
-
- Map<EdgeKey, Connection>::Element *C = connections.find(ek);
- if (!C) {
-
- Connection c;
- c.A = &p;
- c.A_edge = j;
- c.B = NULL;
- c.B_edge = -1;
- connections[ek] = c;
- } else {
-
- if (C->get().B != NULL) {
- ConnectionPending pending;
- pending.polygon = &p;
- pending.edge = j;
- p.edges.write[j].P = C->get().pending.push_back(pending);
- continue;
- }
-
- C->get().B = &p;
- C->get().B_edge = j;
- C->get().A->edges.write[C->get().A_edge].C = &p;
- C->get().A->edges.write[C->get().A_edge].C_edge = j;
- p.edges.write[j].C = C->get().A;
- p.edges.write[j].C_edge = C->get().A_edge;
- //connection successful.
- }
- }
- }
-
- nm.linked = true;
-}
-
-void Navigation::_navmesh_unlink(int p_id) {
-
- ERR_FAIL_COND(!navmesh_map.has(p_id));
- NavMesh &nm = navmesh_map[p_id];
- ERR_FAIL_COND(!nm.linked);
-
- for (List<Polygon>::Element *E = nm.polygons.front(); E; E = E->next()) {
-
- Polygon &p = E->get();
-
- int ec = p.edges.size();
- Polygon::Edge *edges = p.edges.ptrw();
-
- for (int i = 0; i < ec; i++) {
- int next = (i + 1) % ec;
-
- EdgeKey ek(edges[i].point, edges[next].point);
- Map<EdgeKey, Connection>::Element *C = connections.find(ek);
-
- ERR_CONTINUE(!C);
-
- if (edges[i].P) {
- C->get().pending.erase(edges[i].P);
- edges[i].P = NULL;
- } else if (C->get().B) {
- //disconnect
-
- C->get().B->edges.write[C->get().B_edge].C = NULL;
- C->get().B->edges.write[C->get().B_edge].C_edge = -1;
- C->get().A->edges.write[C->get().A_edge].C = NULL;
- C->get().A->edges.write[C->get().A_edge].C_edge = -1;
-
- if (C->get().A == &E->get()) {
-
- C->get().A = C->get().B;
- C->get().A_edge = C->get().B_edge;
- }
- C->get().B = NULL;
- C->get().B_edge = -1;
-
- if (C->get().pending.size()) {
- //reconnect if something is pending
- ConnectionPending cp = C->get().pending.front()->get();
- C->get().pending.pop_front();
-
- C->get().B = cp.polygon;
- C->get().B_edge = cp.edge;
- C->get().A->edges.write[C->get().A_edge].C = cp.polygon;
- C->get().A->edges.write[C->get().A_edge].C_edge = cp.edge;
- cp.polygon->edges.write[cp.edge].C = C->get().A;
- cp.polygon->edges.write[cp.edge].C_edge = C->get().A_edge;
- cp.polygon->edges.write[cp.edge].P = NULL;
- }
-
- } else {
- connections.erase(C);
- //erase
- }
- }
- }
-
- nm.polygons.clear();
-
- nm.linked = false;
-}
-
-int Navigation::navmesh_add(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner) {
-
- int id = last_id++;
- NavMesh nm;
- nm.linked = false;
- nm.navmesh = p_mesh;
- nm.xform = p_xform;
- nm.owner = p_owner;
- navmesh_map[id] = nm;
-
- _navmesh_link(id);
-
- return id;
-}
-
-void Navigation::navmesh_set_transform(int p_id, const Transform &p_xform) {
-
- ERR_FAIL_COND(!navmesh_map.has(p_id));
- NavMesh &nm = navmesh_map[p_id];
- if (nm.xform == p_xform)
- return; //bleh
- _navmesh_unlink(p_id);
- nm.xform = p_xform;
- _navmesh_link(p_id);
-}
-void Navigation::navmesh_remove(int p_id) {
+Vector<Vector3> Navigation::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) {
- ERR_FAIL_COND_MSG(!navmesh_map.has(p_id), "Trying to remove nonexisting navmesh with id: " + itos(p_id));
- _navmesh_unlink(p_id);
- navmesh_map.erase(p_id);
+ return NavigationServer::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
}
-void Navigation::_clip_path(Vector<Vector3> &path, Polygon *from_poly, const Vector3 &p_to_point, Polygon *p_to_poly) {
-
- Vector3 from = path[path.size() - 1];
-
- if (from.distance_to(p_to_point) < CMP_EPSILON)
- return;
- Plane cut_plane;
- cut_plane.normal = (from - p_to_point).cross(up);
- if (cut_plane.normal == Vector3())
- return;
- cut_plane.normal.normalize();
- cut_plane.d = cut_plane.normal.dot(from);
-
- while (from_poly != p_to_poly) {
-
- int pe = from_poly->prev_edge;
- Vector3 a = _get_vertex(from_poly->edges[pe].point);
- Vector3 b = _get_vertex(from_poly->edges[(pe + 1) % from_poly->edges.size()].point);
-
- from_poly = from_poly->edges[pe].C;
- ERR_FAIL_COND(!from_poly);
-
- if (a.distance_to(b) > CMP_EPSILON) {
+void Navigation::set_up_vector(const Vector3 &p_up) {
- Vector3 inters;
- if (cut_plane.intersects_segment(a, b, &inters)) {
- if (inters.distance_to(p_to_point) > CMP_EPSILON && inters.distance_to(path[path.size() - 1]) > CMP_EPSILON) {
- path.push_back(inters);
- }
- }
- }
- }
+ up = p_up;
+ NavigationServer::get_singleton()->map_set_up(map, up);
}
-Vector<Vector3> Navigation::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) {
-
- Polygon *begin_poly = NULL;
- Polygon *end_poly = NULL;
- Vector3 begin_point;
- Vector3 end_point;
- float begin_d = 1e20;
- float end_d = 1e20;
-
- for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- for (int i = 2; i < p.edges.size(); i++) {
-
- Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
- Vector3 spoint = f.get_closest_point_to(p_start);
- float dpoint = spoint.distance_to(p_start);
- if (dpoint < begin_d) {
- begin_d = dpoint;
- begin_poly = &p;
- begin_point = spoint;
- }
-
- spoint = f.get_closest_point_to(p_end);
- dpoint = spoint.distance_to(p_end);
- if (dpoint < end_d) {
- end_d = dpoint;
- end_poly = &p;
- end_point = spoint;
- }
- }
-
- p.prev_edge = -1;
- }
- }
-
- if (!begin_poly || !end_poly) {
-
- return Vector<Vector3>(); //no path
- }
-
- if (begin_poly == end_poly) {
-
- Vector<Vector3> path;
- path.resize(2);
- path.write[0] = begin_point;
- path.write[1] = end_point;
- return path;
- }
-
- bool found_route = false;
-
- List<Polygon *> open_list;
-
- for (int i = 0; i < begin_poly->edges.size(); i++) {
-
- if (begin_poly->edges[i].C) {
-
- begin_poly->edges[i].C->prev_edge = begin_poly->edges[i].C_edge;
-#ifdef USE_ENTRY_POINT
- Vector3 edge[2] = {
- _get_vertex(begin_poly->edges[i].point),
- _get_vertex(begin_poly->edges[(i + 1) % begin_poly->edges.size()].point)
- };
-
- Vector3 entry = Geometry::get_closest_point_to_segment(begin_poly->entry, edge);
- begin_poly->edges[i].C->distance = begin_point.distance_to(entry);
- begin_poly->edges[i].C->entry = entry;
-#else
- begin_poly->edges[i].C->distance = begin_poly->center.distance_to(begin_poly->edges[i].C->center);
-#endif
- open_list.push_back(begin_poly->edges[i].C);
- }
- }
-
- while (!found_route) {
-
- if (open_list.size() == 0) {
- break;
- }
- //check open list
-
- List<Polygon *>::Element *least_cost_poly = NULL;
- float least_cost = 1e30;
-
- //this could be faster (cache previous results)
- for (List<Polygon *>::Element *E = open_list.front(); E; E = E->next()) {
-
- Polygon *p = E->get();
-
- float cost = p->distance;
-#ifdef USE_ENTRY_POINT
- cost += p->entry.distance_to(end_point);
-#else
- cost += p->center.distance_to(end_point);
-#endif
- if (cost < least_cost) {
- least_cost_poly = E;
- least_cost = cost;
- }
- }
-
- Polygon *p = least_cost_poly->get();
- //open the neighbours for search
-
- if (p == end_poly) {
- //oh my reached end! stop algorithm
- found_route = true;
- break;
- }
-
- for (int i = 0; i < p->edges.size(); i++) {
-
- Polygon::Edge &e = p->edges.write[i];
-
- if (!e.C)
- continue;
-
-#ifdef USE_ENTRY_POINT
- Vector3 edge[2] = {
- _get_vertex(p->edges[i].point),
- _get_vertex(p->edges[(i + 1) % p->edges.size()].point)
- };
-
- Vector3 entry = Geometry::get_closest_point_to_segment(p->entry, edge);
- float distance = p->entry.distance_to(entry) + p->distance;
-#else
- float distance = p->center.distance_to(e.C->center) + p->distance;
-#endif
-
- if (e.C->prev_edge != -1) {
- //oh this was visited already, can we win the cost?
-
- if (e.C->distance > distance) {
-
- e.C->prev_edge = e.C_edge;
- e.C->distance = distance;
-#ifdef USE_ENTRY_POINT
- e.C->entry = entry;
-#endif
- }
- } else {
- //add to open neighbours
-
- e.C->prev_edge = e.C_edge;
- e.C->distance = distance;
-#ifdef USE_ENTRY_POINT
- e.C->entry = entry;
-#endif
- open_list.push_back(e.C);
- }
- }
-
- open_list.erase(least_cost_poly);
- }
-
- if (found_route) {
-
- Vector<Vector3> path;
-
- if (p_optimize) {
- //string pulling
-
- Polygon *apex_poly = end_poly;
- Vector3 apex_point = end_point;
- Vector3 portal_left = apex_point;
- Vector3 portal_right = apex_point;
- Polygon *left_poly = end_poly;
- Polygon *right_poly = end_poly;
- Polygon *p = end_poly;
- path.push_back(end_point);
-
- while (p) {
-
- Vector3 left;
- Vector3 right;
-
-#define CLOCK_TANGENT(m_a, m_b, m_c) (((m_a) - (m_c)).cross((m_a) - (m_b)))
-
- if (p == begin_poly) {
- left = begin_point;
- right = begin_point;
- } else {
- int prev = p->prev_edge;
- int prev_n = (p->prev_edge + 1) % p->edges.size();
- left = _get_vertex(p->edges[prev].point);
- right = _get_vertex(p->edges[prev_n].point);
-
- //if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){
- if (p->clockwise) {
- SWAP(left, right);
- }
- }
-
- bool skip = false;
-
- if (CLOCK_TANGENT(apex_point, portal_left, left).dot(up) >= 0) {
- //process
- if (portal_left == apex_point || CLOCK_TANGENT(apex_point, left, portal_right).dot(up) > 0) {
- left_poly = p;
- portal_left = left;
- } else {
-
- _clip_path(path, apex_poly, portal_right, right_poly);
-
- apex_point = portal_right;
- p = right_poly;
- left_poly = p;
- apex_poly = p;
- portal_left = apex_point;
- portal_right = apex_point;
- path.push_back(apex_point);
- skip = true;
- }
- }
-
- if (!skip && CLOCK_TANGENT(apex_point, portal_right, right).dot(up) <= 0) {
- //process
- if (portal_right == apex_point || CLOCK_TANGENT(apex_point, right, portal_left).dot(up) < 0) {
- right_poly = p;
- portal_right = right;
- } else {
-
- _clip_path(path, apex_poly, portal_left, left_poly);
-
- apex_point = portal_left;
- p = left_poly;
- right_poly = p;
- apex_poly = p;
- portal_right = apex_point;
- portal_left = apex_point;
- path.push_back(apex_point);
- }
- }
-
- if (p != begin_poly)
- p = p->edges[p->prev_edge].C;
- else
- p = NULL;
- }
-
- if (path[path.size() - 1] != begin_point)
- path.push_back(begin_point);
-
- path.invert();
-
- } else {
- //midpoints
- Polygon *p = end_poly;
-
- path.push_back(end_point);
- while (true) {
- int prev = p->prev_edge;
-#ifdef USE_ENTRY_POINT
- Vector3 point = p->entry;
-#else
- int prev_n = (p->prev_edge + 1) % p->edges.size();
- Vector3 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point)) * 0.5;
-#endif
- path.push_back(point);
- p = p->edges[prev].C;
- if (p == begin_poly)
- break;
- }
-
- path.push_back(begin_point);
-
- path.invert();
- }
-
- return path;
- }
+Vector3 Navigation::get_up_vector() const {
- return Vector<Vector3>();
+ return up;
}
-Vector3 Navigation::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool &p_use_collision) {
-
- bool use_collision = p_use_collision;
- Vector3 closest_point;
- float closest_point_d = 1e20;
-
- for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- for (int i = 2; i < p.edges.size(); i++) {
-
- Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
- Vector3 inters;
- if (f.intersects_segment(p_from, p_to, &inters)) {
-
- if (!use_collision) {
- closest_point = inters;
- use_collision = true;
- closest_point_d = p_from.distance_to(inters);
- } else if (closest_point_d > inters.distance_to(p_from)) {
-
- closest_point = inters;
- closest_point_d = p_from.distance_to(inters);
- }
- }
- }
-
- if (!use_collision) {
-
- for (int i = 0; i < p.edges.size(); i++) {
-
- Vector3 a, b;
-
- Geometry::get_closest_points_between_segments(p_from, p_to, _get_vertex(p.edges[i].point), _get_vertex(p.edges[(i + 1) % p.edges.size()].point), a, b);
-
- float d = a.distance_to(b);
- if (d < closest_point_d) {
-
- closest_point_d = d;
- closest_point = b;
- }
- }
- }
- }
- }
-
- return closest_point;
+void Navigation::set_cell_size(float p_cell_size) {
+ cell_size = p_cell_size;
+ NavigationServer::get_singleton()->map_set_cell_size(map, cell_size);
}
-Vector3 Navigation::get_closest_point(const Vector3 &p_point) {
-
- Vector3 closest_point;
- float closest_point_d = 1e20;
-
- for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
-
- Polygon &p = F->get();
- for (int i = 2; i < p.edges.size(); i++) {
-
- Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
- Vector3 inters = f.get_closest_point_to(p_point);
- float d = inters.distance_to(p_point);
- if (d < closest_point_d) {
- closest_point = inters;
- closest_point_d = d;
- }
- }
- }
- }
-
- return closest_point;
+void Navigation::set_edge_connection_margin(float p_edge_connection_margin) {
+ edge_connection_margin = p_edge_connection_margin;
+ NavigationServer::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
}
-Vector3 Navigation::get_closest_point_normal(const Vector3 &p_point) {
+void Navigation::_bind_methods() {
- Vector3 closest_point;
- Vector3 closest_normal;
- float closest_point_d = 1e20;
+ ClassDB::bind_method(D_METHOD("get_rid"), &Navigation::get_rid);
- for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
+ ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation::get_simple_path, DEFVAL(true));
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
+ ClassDB::bind_method(D_METHOD("set_up_vector", "up"), &Navigation::set_up_vector);
+ ClassDB::bind_method(D_METHOD("get_up_vector"), &Navigation::get_up_vector);
- Polygon &p = F->get();
- for (int i = 2; i < p.edges.size(); i++) {
+ ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation::set_cell_size);
+ ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation::get_cell_size);
- Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
- Vector3 inters = f.get_closest_point_to(p_point);
- float d = inters.distance_to(p_point);
- if (d < closest_point_d) {
- closest_point = inters;
- closest_point_d = d;
- closest_normal = f.get_plane().normal;
- }
- }
- }
- }
+ ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation::set_edge_connection_margin);
+ ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation::get_edge_connection_margin);
- return closest_normal;
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), "set_up_vector", "get_up_vector");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size"), "set_cell_size", "get_cell_size");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
}
-Object *Navigation::get_closest_point_owner(const Vector3 &p_point) {
-
- Vector3 closest_point;
- Object *owner = NULL;
- float closest_point_d = 1e20;
-
- for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
-
- if (!E->get().linked)
- continue;
- for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
+void Navigation::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ NavigationServer::get_singleton()->map_set_active(map, true);
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
- Polygon &p = F->get();
- for (int i = 2; i < p.edges.size(); i++) {
-
- Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
- Vector3 inters = f.get_closest_point_to(p_point);
- float d = inters.distance_to(p_point);
- if (d < closest_point_d) {
- closest_point = inters;
- closest_point_d = d;
- owner = E->get().owner;
- }
- }
- }
+ NavigationServer::get_singleton()->map_set_active(map, false);
+ } break;
}
-
- return owner;
-}
-
-void Navigation::set_up_vector(const Vector3 &p_up) {
-
- up = p_up;
-}
-
-Vector3 Navigation::get_up_vector() const {
-
- return up;
}
-void Navigation::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("navmesh_add", "mesh", "xform", "owner"), &Navigation::navmesh_add, DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("navmesh_set_transform", "id", "xform"), &Navigation::navmesh_set_transform);
- ClassDB::bind_method(D_METHOD("navmesh_remove", "id"), &Navigation::navmesh_remove);
+Navigation::Navigation() {
- ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation::get_simple_path, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "start", "end", "use_collision"), &Navigation::get_closest_point_to_segment, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation::get_closest_point);
- ClassDB::bind_method(D_METHOD("get_closest_point_normal", "to_point"), &Navigation::get_closest_point_normal);
- ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation::get_closest_point_owner);
+ map = NavigationServer::get_singleton()->map_create();
- ClassDB::bind_method(D_METHOD("set_up_vector", "up"), &Navigation::set_up_vector);
- ClassDB::bind_method(D_METHOD("get_up_vector"), &Navigation::get_up_vector);
+ set_cell_size(0.3);
+ set_edge_connection_margin(5.0); // Five meters, depends alot on the agents radius
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), "set_up_vector", "get_up_vector");
+ up = Vector3(0, 1, 0);
}
-Navigation::Navigation() {
-
- ERR_FAIL_COND(sizeof(Point) != 8);
- cell_size = 0.01; //one centimeter
- last_id = 1;
- up = Vector3(0, 1, 0);
+Navigation::~Navigation() {
+ NavigationServer::get_singleton()->free(map);
}
diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h
index 31dbc9d4b5..68e041ad73 100644
--- a/scene/3d/navigation.h
+++ b/scene/3d/navigation.h
@@ -31,154 +31,45 @@
#ifndef NAVIGATION_H
#define NAVIGATION_H
-#include "scene/3d/navigation_mesh.h"
+#include "scene/3d/navigation_mesh_instance.h"
#include "scene/3d/spatial.h"
class Navigation : public Spatial {
GDCLASS(Navigation, Spatial);
- union Point {
-
- struct {
- int64_t x : 21;
- int64_t y : 22;
- int64_t z : 21;
- };
-
- uint64_t key;
- bool operator<(const Point &p_key) const { return key < p_key.key; }
- };
-
- struct EdgeKey {
-
- Point a;
- Point b;
-
- bool operator<(const EdgeKey &p_key) const {
- return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key);
- };
-
- EdgeKey(const Point &p_a = Point(), const Point &p_b = Point()) :
- a(p_a),
- b(p_b) {
- if (a.key > b.key) {
- SWAP(a, b);
- }
- }
- };
-
- struct NavMesh;
- struct Polygon;
-
- struct ConnectionPending {
-
- Polygon *polygon;
- int edge;
- };
-
- struct Polygon {
-
- struct Edge {
- Point point;
- Polygon *C; //connection
- int C_edge;
- List<ConnectionPending>::Element *P;
- Edge() {
- C = NULL;
- C_edge = -1;
- P = NULL;
- }
- };
-
- Vector<Edge> edges;
-
- Vector3 center;
- Vector3 entry;
-
- float distance;
- int prev_edge;
- bool clockwise;
-
- NavMesh *owner;
- };
-
- struct Connection {
-
- Polygon *A;
- int A_edge;
- Polygon *B;
- int B_edge;
-
- List<ConnectionPending> pending;
-
- Connection() {
- A = NULL;
- B = NULL;
- A_edge = -1;
- B_edge = -1;
- }
- };
-
- Map<EdgeKey, Connection> connections;
-
- struct NavMesh {
-
- Object *owner;
- Transform xform;
- bool linked;
- Ref<NavigationMesh> navmesh;
- List<Polygon> polygons;
- };
-
- _FORCE_INLINE_ Point _get_point(const Vector3 &p_pos) const {
-
- int x = int(Math::floor(p_pos.x / cell_size));
- int y = int(Math::floor(p_pos.y / cell_size));
- int z = int(Math::floor(p_pos.z / cell_size));
-
- Point p;
- p.key = 0;
- p.x = x;
- p.y = y;
- p.z = z;
- return p;
- }
-
- _FORCE_INLINE_ Vector3 _get_vertex(const Point &p_point) const {
-
- return Vector3(p_point.x, p_point.y, p_point.z) * cell_size;
- }
-
- void _navmesh_link(int p_id);
- void _navmesh_unlink(int p_id);
-
- float cell_size;
- Map<int, NavMesh> navmesh_map;
- int last_id;
+ RID map;
Vector3 up;
- void _clip_path(Vector<Vector3> &path, Polygon *from_poly, const Vector3 &p_to_point, Polygon *p_to_poly);
+ real_t cell_size;
+ real_t edge_connection_margin;
protected:
static void _bind_methods();
+ void _notification(int p_what);
public:
+ RID get_rid() const {
+ return map;
+ }
+
void set_up_vector(const Vector3 &p_up);
Vector3 get_up_vector() const;
- //API should be as dynamic as possible
- int navmesh_add(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner = NULL);
- void navmesh_set_transform(int p_id, const Transform &p_xform);
- void navmesh_remove(int p_id);
+ void set_cell_size(float p_cell_size);
+ float get_cell_size() const {
+ return cell_size;
+ }
+
+ void set_edge_connection_margin(float p_edge_connection_margin);
+ float get_edge_connection_margin() const {
+ return edge_connection_margin;
+ }
Vector<Vector3> get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true);
- Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool &p_use_collision = false);
- Vector3 get_closest_point(const Vector3 &p_point);
- Vector3 get_closest_point_normal(const Vector3 &p_point);
- Object *get_closest_point_owner(const Vector3 &p_point);
Navigation();
+ ~Navigation();
};
#endif // NAVIGATION_H
diff --git a/scene/3d/navigation_agent.cpp b/scene/3d/navigation_agent.cpp
new file mode 100644
index 0000000000..29cdd6f204
--- /dev/null
+++ b/scene/3d/navigation_agent.cpp
@@ -0,0 +1,361 @@
+/*************************************************************************/
+/* navigation_agent.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "navigation_agent.h"
+
+#include "core/engine.h"
+#include "scene/3d/navigation.h"
+#include "servers/navigation_server.h"
+
+void NavigationAgent::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent::set_target_desired_distance);
+ ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent::get_target_desired_distance);
+
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent::get_radius);
+
+ ClassDB::bind_method(D_METHOD("set_agent_height_offset", "agent_height_offset"), &NavigationAgent::set_agent_height_offset);
+ ClassDB::bind_method(D_METHOD("get_agent_height_offset"), &NavigationAgent::get_agent_height_offset);
+
+ ClassDB::bind_method(D_METHOD("set_ignore_y", "ignore"), &NavigationAgent::set_ignore_y);
+ ClassDB::bind_method(D_METHOD("get_ignore_y"), &NavigationAgent::get_ignore_y);
+
+ ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent::set_navigation_node);
+ ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent::get_navigation_node);
+
+ ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent::set_neighbor_dist);
+ ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent::get_neighbor_dist);
+
+ ClassDB::bind_method(D_METHOD("set_max_neighbors", "max_neighbors"), &NavigationAgent::set_max_neighbors);
+ ClassDB::bind_method(D_METHOD("get_max_neighbors"), &NavigationAgent::get_max_neighbors);
+
+ ClassDB::bind_method(D_METHOD("set_time_horizon", "time_horizon"), &NavigationAgent::set_time_horizon);
+ ClassDB::bind_method(D_METHOD("get_time_horizon"), &NavigationAgent::get_time_horizon);
+
+ ClassDB::bind_method(D_METHOD("set_max_speed", "max_speed"), &NavigationAgent::set_max_speed);
+ ClassDB::bind_method(D_METHOD("get_max_speed"), &NavigationAgent::get_max_speed);
+
+ ClassDB::bind_method(D_METHOD("set_path_max_distance", "max_speed"), &NavigationAgent::set_path_max_distance);
+ ClassDB::bind_method(D_METHOD("get_path_max_distance"), &NavigationAgent::get_path_max_distance);
+
+ ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent::set_target_location);
+ ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent::get_target_location);
+ ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent::get_next_location);
+ ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent::distance_to_target);
+ ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent::set_velocity);
+ ClassDB::bind_method(D_METHOD("get_nav_path"), &NavigationAgent::get_nav_path);
+ ClassDB::bind_method(D_METHOD("get_nav_path_index"), &NavigationAgent::get_nav_path_index);
+ ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent::is_target_reached);
+ ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent::is_target_reachable);
+ ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent::is_navigation_finished);
+ ClassDB::bind_method(D_METHOD("get_final_location"), &NavigationAgent::get_final_location);
+
+ ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent::_avoidance_done);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01"), "set_target_desired_distance", "get_target_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,100,0.01"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01"), "set_agent_height_offset", "get_agent_height_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "neighbor_dist", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_neighbor_dist", "get_neighbor_dist");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_horizon", PROPERTY_HINT_RANGE, "0.01,100,0.01"), "set_time_horizon", "get_time_horizon");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_max_speed", "get_max_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1"), "set_path_max_distance", "get_path_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y");
+
+ ADD_SIGNAL(MethodInfo("path_changed"));
+ ADD_SIGNAL(MethodInfo("target_reached"));
+ ADD_SIGNAL(MethodInfo("navigation_finished"));
+ ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity")));
+}
+
+void NavigationAgent::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+
+ agent_parent = Object::cast_to<Spatial>(get_parent());
+
+ NavigationServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+
+ // Search the navigation node and set it
+ {
+ Navigation *nav = NULL;
+ Node *p = get_parent();
+ while (p != NULL) {
+ nav = Object::cast_to<Navigation>(p);
+ if (nav != NULL)
+ p = NULL;
+ else
+ p = p->get_parent();
+ }
+
+ set_navigation(nav);
+ }
+
+ set_physics_process_internal(true);
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ agent_parent = NULL;
+ set_navigation(NULL);
+ set_physics_process_internal(false);
+ } break;
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ if (agent_parent) {
+
+ NavigationServer::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().origin);
+ if (!target_reached) {
+ if (distance_to_target() < target_desired_distance) {
+ emit_signal("target_reached");
+ target_reached = true;
+ }
+ }
+ }
+ } break;
+ }
+}
+
+NavigationAgent::NavigationAgent() :
+ agent_parent(NULL),
+ navigation(NULL),
+ agent(RID()),
+ target_desired_distance(1.0),
+ navigation_height_offset(0.0),
+ path_max_distance(3.0),
+ velocity_submitted(false),
+ target_reached(false),
+ navigation_finished(true) {
+ agent = NavigationServer::get_singleton()->agent_create();
+ set_neighbor_dist(50.0);
+ set_max_neighbors(10);
+ set_time_horizon(5.0);
+ set_radius(1.0);
+ set_max_speed(10.0);
+ set_ignore_y(true);
+}
+
+NavigationAgent::~NavigationAgent() {
+ NavigationServer::get_singleton()->free(agent);
+ agent = RID(); // Pointless
+}
+
+void NavigationAgent::set_navigation(Navigation *p_nav) {
+ if (navigation == p_nav)
+ return; // Pointless
+
+ navigation = p_nav;
+ NavigationServer::get_singleton()->agent_set_map(agent, navigation == NULL ? RID() : navigation->get_rid());
+}
+
+void NavigationAgent::set_navigation_node(Node *p_nav) {
+ Navigation *nav = Object::cast_to<Navigation>(p_nav);
+ ERR_FAIL_COND(nav == NULL);
+ set_navigation(nav);
+}
+
+Node *NavigationAgent::get_navigation_node() const {
+ return Object::cast_to<Node>(navigation);
+}
+
+void NavigationAgent::set_target_desired_distance(real_t p_dd) {
+ target_desired_distance = p_dd;
+}
+
+void NavigationAgent::set_radius(real_t p_radius) {
+ radius = p_radius;
+ NavigationServer::get_singleton()->agent_set_radius(agent, radius);
+}
+
+void NavigationAgent::set_agent_height_offset(real_t p_hh) {
+ navigation_height_offset = p_hh;
+}
+
+void NavigationAgent::set_ignore_y(bool p_ignore_y) {
+ ignore_y = p_ignore_y;
+ NavigationServer::get_singleton()->agent_set_ignore_y(agent, ignore_y);
+}
+
+void NavigationAgent::set_neighbor_dist(real_t p_dist) {
+ neighbor_dist = p_dist;
+ NavigationServer::get_singleton()->agent_set_neighbor_dist(agent, neighbor_dist);
+}
+
+void NavigationAgent::set_max_neighbors(int p_count) {
+ max_neighbors = p_count;
+ NavigationServer::get_singleton()->agent_set_max_neighbors(agent, max_neighbors);
+}
+
+void NavigationAgent::set_time_horizon(real_t p_time) {
+ time_horizon = p_time;
+ NavigationServer::get_singleton()->agent_set_time_horizon(agent, time_horizon);
+}
+
+void NavigationAgent::set_max_speed(real_t p_max_speed) {
+ max_speed = p_max_speed;
+ NavigationServer::get_singleton()->agent_set_max_speed(agent, max_speed);
+}
+
+void NavigationAgent::set_path_max_distance(real_t p_pmd) {
+ path_max_distance = p_pmd;
+}
+
+real_t NavigationAgent::get_path_max_distance() {
+ return path_max_distance;
+}
+
+void NavigationAgent::set_target_location(Vector3 p_location) {
+ target_location = p_location;
+ navigation_path.clear();
+ target_reached = false;
+ navigation_finished = false;
+}
+
+Vector3 NavigationAgent::get_target_location() const {
+ return target_location;
+}
+
+Vector3 NavigationAgent::get_next_location() {
+ update_navigation();
+ if (navigation_path.size() == 0) {
+ ERR_FAIL_COND_V(agent_parent == NULL, Vector3());
+ return agent_parent->get_global_transform().origin;
+ } else {
+ return navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0);
+ }
+}
+
+real_t NavigationAgent::distance_to_target() const {
+ ERR_FAIL_COND_V(agent_parent == NULL, 0.0);
+ return agent_parent->get_global_transform().origin.distance_to(target_location);
+}
+
+bool NavigationAgent::is_target_reached() const {
+ return target_reached;
+}
+
+bool NavigationAgent::is_target_reachable() {
+ return target_desired_distance >= get_final_location().distance_to(target_location);
+}
+
+bool NavigationAgent::is_navigation_finished() {
+ update_navigation();
+ return navigation_finished;
+}
+
+Vector3 NavigationAgent::get_final_location() {
+ update_navigation();
+ if (navigation_path.size() == 0) {
+ return Vector3();
+ }
+ return navigation_path[navigation_path.size() - 1];
+}
+
+void NavigationAgent::set_velocity(Vector3 p_velocity) {
+ target_velocity = p_velocity;
+ NavigationServer::get_singleton()->agent_set_target_velocity(agent, target_velocity);
+ NavigationServer::get_singleton()->agent_set_velocity(agent, prev_safe_velocity);
+ velocity_submitted = true;
+}
+
+void NavigationAgent::_avoidance_done(Vector3 p_new_velocity) {
+ prev_safe_velocity = p_new_velocity;
+
+ if (!velocity_submitted) {
+ target_velocity = Vector3();
+ return;
+ }
+ velocity_submitted = false;
+
+ emit_signal("velocity_computed", p_new_velocity);
+}
+
+String NavigationAgent::get_configuration_warning() const {
+ if (!Object::cast_to<Spatial>(get_parent())) {
+ return TTR("The NavigationAgent can be used only under a spatial node.");
+ }
+
+ return String();
+}
+
+void NavigationAgent::update_navigation() {
+
+ if (agent_parent == NULL) return;
+ if (navigation == NULL) return;
+ if (update_frame_id == Engine::get_singleton()->get_physics_frames()) return;
+
+ update_frame_id = Engine::get_singleton()->get_physics_frames();
+
+ Vector3 o = agent_parent->get_global_transform().origin;
+
+ bool reload_path = false;
+
+ if (NavigationServer::get_singleton()->agent_is_map_changed(agent)) {
+ reload_path = true;
+ } else if (navigation_path.size() == 0) {
+ reload_path = true;
+ } else {
+ // Check if too far from the navigation path
+ if (nav_path_index > 0) {
+ Vector3 segment[2];
+ segment[0] = navigation_path[nav_path_index - 1];
+ segment[1] = navigation_path[nav_path_index];
+ segment[0].y -= navigation_height_offset;
+ segment[1].y -= navigation_height_offset;
+ Vector3 p = Geometry::get_closest_point_to_segment(o, segment);
+ if (o.distance_to(p) >= path_max_distance) {
+ // To faraway, reload path
+ reload_path = true;
+ }
+ }
+ }
+
+ if (reload_path) {
+ navigation_path = NavigationServer::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true);
+ navigation_finished = false;
+ nav_path_index = 0;
+ emit_signal("path_changed");
+ }
+
+ if (navigation_path.size() == 0)
+ return;
+
+ // Check if we can advance the navigation path
+ if (navigation_finished == false) {
+ // Advances to the next far away location.
+ while (o.distance_to(navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0)) < target_desired_distance) {
+ nav_path_index += 1;
+ if (nav_path_index == navigation_path.size()) {
+ nav_path_index -= 1;
+ navigation_finished = true;
+ emit_signal("navigation_finished");
+ break;
+ }
+ }
+ }
+}
diff --git a/scene/3d/navigation_agent.h b/scene/3d/navigation_agent.h
new file mode 100644
index 0000000000..200d5db475
--- /dev/null
+++ b/scene/3d/navigation_agent.h
@@ -0,0 +1,162 @@
+/*************************************************************************/
+/* navigation_agent.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef NAVIGATION_AGENT_H
+#define NAVIGATION_AGENT_H
+
+#include "core/vector.h"
+#include "scene/main/node.h"
+
+class Spatial;
+class Navigation;
+
+class NavigationAgent : public Node {
+ GDCLASS(NavigationAgent, Node);
+
+ Spatial *agent_parent;
+ Navigation *navigation;
+
+ RID agent;
+
+ real_t target_desired_distance;
+ real_t radius;
+ real_t navigation_height_offset;
+ bool ignore_y;
+ real_t neighbor_dist;
+ int max_neighbors;
+ real_t time_horizon;
+ real_t max_speed;
+
+ real_t path_max_distance;
+
+ Vector3 target_location;
+ Vector<Vector3> navigation_path;
+ int nav_path_index;
+ bool velocity_submitted;
+ Vector3 prev_safe_velocity;
+ /// The submitted target velocity
+ Vector3 target_velocity;
+ bool target_reached;
+ bool navigation_finished;
+ // No initialized on purpose
+ uint32_t update_frame_id;
+
+protected:
+ static void _bind_methods();
+ void _notification(int p_what);
+
+public:
+ NavigationAgent();
+ virtual ~NavigationAgent();
+
+ void set_navigation(Navigation *p_nav);
+ const Navigation *get_navigation() const {
+ return navigation;
+ }
+
+ void set_navigation_node(Node *p_nav);
+ Node *get_navigation_node() const;
+
+ RID get_rid() const {
+ return agent;
+ }
+
+ void set_target_desired_distance(real_t p_dd);
+ real_t get_target_desired_distance() const {
+ return target_desired_distance;
+ }
+
+ void set_radius(real_t p_radius);
+ real_t get_radius() const {
+ return radius;
+ }
+
+ void set_agent_height_offset(real_t p_hh);
+ real_t get_agent_height_offset() const {
+ return navigation_height_offset;
+ }
+
+ void set_ignore_y(bool p_ignore_y);
+ bool get_ignore_y() const {
+ return ignore_y;
+ }
+
+ void set_neighbor_dist(real_t p_dist);
+ real_t get_neighbor_dist() const {
+ return neighbor_dist;
+ }
+
+ void set_max_neighbors(int p_count);
+ int get_max_neighbors() const {
+ return max_neighbors;
+ }
+
+ void set_time_horizon(real_t p_time);
+ real_t get_time_horizon() const {
+ return time_horizon;
+ }
+
+ void set_max_speed(real_t p_max_speed);
+ real_t get_max_speed() const {
+ return max_speed;
+ }
+
+ void set_path_max_distance(real_t p_pmd);
+ real_t get_path_max_distance();
+
+ void set_target_location(Vector3 p_location);
+ Vector3 get_target_location() const;
+
+ Vector3 get_next_location();
+
+ Vector<Vector3> get_nav_path() const {
+ return navigation_path;
+ }
+
+ int get_nav_path_index() const {
+ return nav_path_index;
+ }
+
+ real_t distance_to_target() const;
+ bool is_target_reached() const;
+ bool is_target_reachable();
+ bool is_navigation_finished();
+ Vector3 get_final_location();
+
+ void set_velocity(Vector3 p_velocity);
+ void _avoidance_done(Vector3 p_new_velocity);
+
+ virtual String get_configuration_warning() const;
+
+private:
+ void update_navigation();
+};
+
+#endif
diff --git a/scene/3d/navigation_mesh_instance.cpp b/scene/3d/navigation_mesh_instance.cpp
new file mode 100644
index 0000000000..8f8574ba2d
--- /dev/null
+++ b/scene/3d/navigation_mesh_instance.cpp
@@ -0,0 +1,258 @@
+/*************************************************************************/
+/* navigation_mesh_instance.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "navigation_mesh_instance.h"
+#include "core/os/thread.h"
+#include "mesh_instance.h"
+#include "navigation.h"
+#include "servers/navigation_server.h"
+
+void NavigationMeshInstance::set_enabled(bool p_enabled) {
+
+ if (enabled == p_enabled)
+ return;
+ enabled = p_enabled;
+
+ if (!is_inside_tree())
+ return;
+
+ if (!enabled) {
+
+ NavigationServer::get_singleton()->region_set_map(region, RID());
+ } else {
+
+ if (navigation) {
+
+ NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid());
+ }
+ }
+
+ if (debug_view) {
+ MeshInstance *dm = Object::cast_to<MeshInstance>(debug_view);
+ if (is_enabled()) {
+ dm->set_material_override(get_tree()->get_debug_navigation_material());
+ } else {
+ dm->set_material_override(get_tree()->get_debug_navigation_disabled_material());
+ }
+ }
+
+ update_gizmo();
+}
+
+bool NavigationMeshInstance::is_enabled() const {
+
+ return enabled;
+}
+
+/////////////////////////////
+
+void NavigationMeshInstance::_notification(int p_what) {
+
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+
+ Spatial *c = this;
+ while (c) {
+
+ navigation = Object::cast_to<Navigation>(c);
+ if (navigation) {
+
+ if (enabled) {
+
+ NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid());
+ }
+ break;
+ }
+
+ c = c->get_parent_spatial();
+ }
+
+ if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
+
+ MeshInstance *dm = memnew(MeshInstance);
+ dm->set_mesh(navmesh->get_debug_mesh());
+ if (is_enabled()) {
+ dm->set_material_override(get_tree()->get_debug_navigation_material());
+ } else {
+ dm->set_material_override(get_tree()->get_debug_navigation_disabled_material());
+ }
+ add_child(dm);
+ debug_view = dm;
+ }
+
+ } break;
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+
+ NavigationServer::get_singleton()->region_set_transform(region, get_global_transform());
+
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+
+ if (navigation) {
+
+ NavigationServer::get_singleton()->region_set_map(region, RID());
+ }
+
+ if (debug_view) {
+ debug_view->queue_delete();
+ debug_view = NULL;
+ }
+ navigation = NULL;
+ } break;
+ }
+}
+
+void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh) {
+
+ if (p_navmesh == navmesh)
+ return;
+
+ if (navmesh.is_valid()) {
+ navmesh->remove_change_receptor(this);
+ }
+
+ navmesh = p_navmesh;
+
+ if (navmesh.is_valid()) {
+ navmesh->add_change_receptor(this);
+ }
+
+ NavigationServer::get_singleton()->region_set_navmesh(region, p_navmesh);
+
+ if (debug_view && navmesh.is_valid()) {
+ Object::cast_to<MeshInstance>(debug_view)->set_mesh(navmesh->get_debug_mesh());
+ }
+
+ emit_signal("navigation_mesh_changed");
+
+ update_gizmo();
+ update_configuration_warning();
+}
+
+Ref<NavigationMesh> NavigationMeshInstance::get_navigation_mesh() const {
+
+ return navmesh;
+}
+
+struct BakeThreadsArgs {
+ NavigationMeshInstance *nav_mesh_instance;
+};
+
+void _bake_navigation_mesh(void *p_user_data) {
+ BakeThreadsArgs *args = static_cast<BakeThreadsArgs *>(p_user_data);
+
+ if (args->nav_mesh_instance->get_navigation_mesh().is_valid()) {
+ Ref<NavigationMesh> nav_mesh = args->nav_mesh_instance->get_navigation_mesh()->duplicate();
+
+ NavigationServer::get_singleton()->region_bake_navmesh(nav_mesh, args->nav_mesh_instance);
+ args->nav_mesh_instance->call_deferred("_bake_finished", nav_mesh);
+ memdelete(args);
+ } else {
+
+ ERR_PRINT("Can't bake the navigation mesh if the `NavigationMesh` resource doesn't exist");
+ args->nav_mesh_instance->call_deferred("_bake_finished", Ref<NavigationMesh>());
+ memdelete(args);
+ }
+}
+
+void NavigationMeshInstance::bake_navigation_mesh() {
+ ERR_FAIL_COND(bake_thread != NULL);
+
+ BakeThreadsArgs *args = memnew(BakeThreadsArgs);
+ args->nav_mesh_instance = this;
+
+ bake_thread = Thread::create(_bake_navigation_mesh, args);
+ ERR_FAIL_COND(bake_thread == NULL);
+}
+
+void NavigationMeshInstance::_bake_finished(Ref<NavigationMesh> p_nav_mesh) {
+ set_navigation_mesh(p_nav_mesh);
+ bake_thread = NULL;
+}
+
+String NavigationMeshInstance::get_configuration_warning() const {
+
+ if (!is_visible_in_tree() || !is_inside_tree())
+ return String();
+
+ if (!navmesh.is_valid()) {
+ return TTR("A NavigationMesh resource must be set or created for this node to work.");
+ }
+ const Spatial *c = this;
+ while (c) {
+
+ if (Object::cast_to<Navigation>(c))
+ return String();
+
+ c = Object::cast_to<Spatial>(c->get_parent());
+ }
+
+ return TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data.");
+}
+
+void NavigationMeshInstance::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationMeshInstance::set_navigation_mesh);
+ ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationMeshInstance::get_navigation_mesh);
+
+ ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationMeshInstance::set_enabled);
+ ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationMeshInstance::is_enabled);
+
+ ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationMeshInstance::bake_navigation_mesh);
+ ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationMeshInstance::_bake_finished);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
+
+ ADD_SIGNAL(MethodInfo("navigation_mesh_changed"));
+ ADD_SIGNAL(MethodInfo("bake_finished"));
+}
+
+void NavigationMeshInstance::_changed_callback(Object *p_changed, const char *p_prop) {
+ update_gizmo();
+ update_configuration_warning();
+}
+
+NavigationMeshInstance::NavigationMeshInstance() {
+
+ enabled = true;
+ set_notify_transform(true);
+ region = NavigationServer::get_singleton()->region_create();
+
+ navigation = NULL;
+ debug_view = NULL;
+ bake_thread = NULL;
+}
+
+NavigationMeshInstance::~NavigationMeshInstance() {
+ if (navmesh.is_valid())
+ navmesh->remove_change_receptor(this);
+ NavigationServer::get_singleton()->free(region);
+}
diff --git a/scene/3d/navigation_mesh_instance.h b/scene/3d/navigation_mesh_instance.h
new file mode 100644
index 0000000000..1135bf47d2
--- /dev/null
+++ b/scene/3d/navigation_mesh_instance.h
@@ -0,0 +1,75 @@
+/*************************************************************************/
+/* navigation_mesh_instance.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef NAVIGATION_MESH_INSTANCE_H
+#define NAVIGATION_MESH_INSTANCE_H
+
+#include "scene/3d/spatial.h"
+#include "scene/resources/mesh.h"
+#include "scene/resources/navigation_mesh.h"
+
+class Navigation;
+
+class NavigationMeshInstance : public Spatial {
+
+ GDCLASS(NavigationMeshInstance, Spatial);
+
+ bool enabled;
+ RID region;
+ Ref<NavigationMesh> navmesh;
+
+ Navigation *navigation;
+ Node *debug_view;
+ Thread *bake_thread;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+ void _changed_callback(Object *p_changed, const char *p_prop);
+
+public:
+ void set_enabled(bool p_enabled);
+ bool is_enabled() const;
+
+ void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh);
+ Ref<NavigationMesh> get_navigation_mesh() const;
+
+ /// Bakes the navigation mesh in a dedicated thread; once done, automatically
+ /// sets the new navigation mesh and emits a signal
+ void bake_navigation_mesh();
+ void _bake_finished(Ref<NavigationMesh> p_nav_mesh);
+
+ String get_configuration_warning() const;
+
+ NavigationMeshInstance();
+ ~NavigationMeshInstance();
+};
+
+#endif // NAVIGATION_MESH_INSTANCE_H
diff --git a/scene/3d/navigation_obstacle.cpp b/scene/3d/navigation_obstacle.cpp
new file mode 100644
index 0000000000..befc41eee5
--- /dev/null
+++ b/scene/3d/navigation_obstacle.cpp
@@ -0,0 +1,163 @@
+/*************************************************************************/
+/* navigation_obstacle.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "navigation_obstacle.h"
+
+#include "scene/3d/collision_shape.h"
+#include "scene/3d/navigation.h"
+#include "scene/3d/physics_body.h"
+#include "servers/navigation_server.h"
+
+void NavigationObstacle::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle::set_navigation_node);
+ ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle::get_navigation_node);
+}
+
+void NavigationObstacle::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+
+ update_agent_shape();
+
+ // Search the navigation node and set it
+ {
+ Navigation *nav = NULL;
+ Node *p = get_parent();
+ while (p != NULL) {
+ nav = Object::cast_to<Navigation>(p);
+ if (nav != NULL)
+ p = NULL;
+ else
+ p = p->get_parent();
+ }
+
+ set_navigation(nav);
+ }
+
+ set_physics_process_internal(true);
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ set_navigation(NULL);
+ set_physics_process_internal(false);
+ } break;
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ Spatial *spatial = Object::cast_to<Spatial>(get_parent());
+ if (spatial) {
+ NavigationServer::get_singleton()->agent_set_position(agent, spatial->get_global_transform().origin);
+ }
+
+ PhysicsBody *rigid = Object::cast_to<PhysicsBody>(get_parent());
+ if (rigid) {
+
+ Vector3 v = rigid->get_linear_velocity();
+ NavigationServer::get_singleton()->agent_set_velocity(agent, v);
+ NavigationServer::get_singleton()->agent_set_target_velocity(agent, v);
+ }
+
+ } break;
+ }
+}
+
+NavigationObstacle::NavigationObstacle() :
+ navigation(NULL),
+ agent(RID()) {
+ agent = NavigationServer::get_singleton()->agent_create();
+}
+
+NavigationObstacle::~NavigationObstacle() {
+ NavigationServer::get_singleton()->free(agent);
+ agent = RID(); // Pointless
+}
+
+void NavigationObstacle::set_navigation(Navigation *p_nav) {
+ if (navigation == p_nav)
+ return; // Pointless
+
+ navigation = p_nav;
+ NavigationServer::get_singleton()->agent_set_map(agent, navigation == NULL ? RID() : navigation->get_rid());
+}
+
+void NavigationObstacle::set_navigation_node(Node *p_nav) {
+ Navigation *nav = Object::cast_to<Navigation>(p_nav);
+ ERR_FAIL_COND(nav == NULL);
+ set_navigation(nav);
+}
+
+Node *NavigationObstacle::get_navigation_node() const {
+ return Object::cast_to<Node>(navigation);
+}
+
+String NavigationObstacle::get_configuration_warning() const {
+ if (!Object::cast_to<Spatial>(get_parent())) {
+
+ return TTR("The NavigationObstacle only serves to provide collision avoidance to a spatial object.");
+ }
+
+ return String();
+}
+
+void NavigationObstacle::update_agent_shape() {
+ Node *node = get_parent();
+
+ // Estimate the radius of this physics body
+ real_t radius = 0.0;
+ for (int i(0); i < node->get_child_count(); i++) {
+ // For each collision shape
+ CollisionShape *cs = Object::cast_to<CollisionShape>(node->get_child(i));
+ if (cs) {
+ // Take the distance between the Body center to the shape center
+ real_t r = cs->get_transform().origin.length();
+ if (cs->get_shape().is_valid()) {
+ // and add the enclosing shape radius
+ r += cs->get_shape()->get_enclosing_radius();
+ }
+ Vector3 s = cs->get_global_transform().basis.get_scale();
+ r *= MAX(s.x, MAX(s.y, s.z));
+ // Takes the biggest radius
+ radius = MAX(radius, r);
+ }
+ }
+ Spatial *spa = Object::cast_to<Spatial>(node);
+ if (spa) {
+ Vector3 s = spa->get_global_transform().basis.get_scale();
+ radius *= MAX(s.x, MAX(s.y, s.z));
+ }
+
+ if (radius == 0.0)
+ radius = 1.0; // Never a 0 radius
+
+ // Initialize the Agent as an object
+ NavigationServer::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
+ NavigationServer::get_singleton()->agent_set_max_neighbors(agent, 0);
+ NavigationServer::get_singleton()->agent_set_time_horizon(agent, 0.0);
+ NavigationServer::get_singleton()->agent_set_radius(agent, radius);
+ NavigationServer::get_singleton()->agent_set_max_speed(agent, 0.0);
+}
diff --git a/scene/3d/navigation_obstacle.h b/scene/3d/navigation_obstacle.h
new file mode 100644
index 0000000000..7257a43150
--- /dev/null
+++ b/scene/3d/navigation_obstacle.h
@@ -0,0 +1,71 @@
+/*************************************************************************/
+/* navigation_obstacle.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef NAVIGATION_OBSTACLE_H
+#define NAVIGATION_OBSTACLE_H
+
+#include "scene/main/node.h"
+
+class Navigation;
+
+class NavigationObstacle : public Node {
+ GDCLASS(NavigationObstacle, Node);
+
+ Navigation *navigation;
+
+ RID agent;
+
+protected:
+ static void _bind_methods();
+ void _notification(int p_what);
+
+public:
+ NavigationObstacle();
+ virtual ~NavigationObstacle();
+
+ void set_navigation(Navigation *p_nav);
+ const Navigation *get_navigation() const {
+ return navigation;
+ }
+
+ void set_navigation_node(Node *p_nav);
+ Node *get_navigation_node() const;
+
+ RID get_rid() const {
+ return agent;
+ }
+
+ virtual String get_configuration_warning() const;
+
+private:
+ void update_agent_shape();
+};
+
+#endif
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index add563d991..9fe626474e 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -254,16 +254,16 @@ String Particles::get_configuration_warning() const {
meshes_found = true;
for (int j = 0; j < draw_passes[i]->get_surface_count(); j++) {
anim_material_found = Object::cast_to<ShaderMaterial>(draw_passes[i]->surface_get_material(j).ptr()) != NULL;
- SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(draw_passes[i]->surface_get_material(j).ptr());
- anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);
+ StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(draw_passes[i]->surface_get_material(j).ptr());
+ anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
}
if (anim_material_found) break;
}
}
anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL;
- SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_material_override().ptr());
- anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);
+ StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_material_override().ptr());
+ anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
if (!meshes_found) {
if (warnings != String())
@@ -282,7 +282,7 @@ String Particles::get_configuration_warning() const {
process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) {
if (warnings != String())
warnings += "\n";
- warnings += "- " + TTR("Particles animation requires the usage of a SpatialMaterial whose Billboard Mode is set to \"Particle Billboard\".");
+ warnings += "- " + TTR("Particles animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\".");
}
}
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index caeae90238..9848125d0f 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -36,15 +36,14 @@
#include "core/method_bind_ext.gen.inc"
#include "core/object.h"
#include "core/rid.h"
+#include "scene/3d/collision_shape.h"
#include "scene/scene_string_names.h"
+#include "servers/navigation_server.h"
#ifdef TOOLS_ENABLED
#include "editor/plugins/spatial_editor_plugin.h"
#endif
-void PhysicsBody::_notification(int p_what) {
-}
-
Vector3 PhysicsBody::get_linear_velocity() const {
return Vector3();
@@ -179,64 +178,6 @@ PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) :
collision_mask = 1;
}
-#ifndef DISABLE_DEPRECATED
-void StaticBody::set_friction(real_t p_friction) {
-
- if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that
- return;
- }
-
- WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
-
- ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1.");
-
- if (physics_material_override.is_null()) {
- physics_material_override.instance();
- set_physics_material_override(physics_material_override);
- }
- physics_material_override->set_friction(p_friction);
-}
-
-real_t StaticBody::get_friction() const {
-
- WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
-
- if (physics_material_override.is_null()) {
- return 1;
- }
-
- return physics_material_override->get_friction();
-}
-
-void StaticBody::set_bounce(real_t p_bounce) {
-
- if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that
- return;
- }
-
- WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
-
- ERR_FAIL_COND_MSG(p_bounce < 0 || p_bounce > 1, "Bounce must be between 0 and 1.");
-
- if (physics_material_override.is_null()) {
- physics_material_override.instance();
- set_physics_material_override(physics_material_override);
- }
- physics_material_override->set_bounce(p_bounce);
-}
-
-real_t StaticBody::get_bounce() const {
-
- WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
-
- if (physics_material_override.is_null()) {
- return 0;
- }
-
- return physics_material_override->get_bounce();
-}
-#endif
-
void StaticBody::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
if (physics_material_override.is_valid()) {
if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
@@ -283,14 +224,6 @@ void StaticBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody::get_constant_linear_velocity);
ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody::get_constant_angular_velocity);
-#ifndef DISABLE_DEPRECATED
- ClassDB::bind_method(D_METHOD("set_friction", "friction"), &StaticBody::set_friction);
- ClassDB::bind_method(D_METHOD("get_friction"), &StaticBody::get_friction);
-
- ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &StaticBody::set_bounce);
- ClassDB::bind_method(D_METHOD("get_bounce"), &StaticBody::get_bounce);
-#endif // DISABLE_DEPRECATED
-
ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody::set_physics_material_override);
ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody::get_physics_material_override);
@@ -300,10 +233,6 @@ void StaticBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody::add_collision_exception_with);
ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody::remove_collision_exception_with);
-#ifndef DISABLE_DEPRECATED
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce");
-#endif // DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity");
@@ -619,60 +548,6 @@ real_t RigidBody::get_weight() const {
return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8));
}
-#ifndef DISABLE_DEPRECATED
-void RigidBody::set_friction(real_t p_friction) {
-
- if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that
- return;
- }
-
- WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
-
- ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
-
- if (physics_material_override.is_null()) {
- physics_material_override.instance();
- set_physics_material_override(physics_material_override);
- }
- physics_material_override->set_friction(p_friction);
-}
-real_t RigidBody::get_friction() const {
-
- WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
-
- if (physics_material_override.is_null()) {
- return 1;
- }
-
- return physics_material_override->get_friction();
-}
-
-void RigidBody::set_bounce(real_t p_bounce) {
-
- if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that
- return;
- }
-
- WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
-
- ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
-
- if (physics_material_override.is_null()) {
- physics_material_override.instance();
- set_physics_material_override(physics_material_override);
- }
- physics_material_override->set_bounce(p_bounce);
-}
-real_t RigidBody::get_bounce() const {
- WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
- if (physics_material_override.is_null()) {
- return 0;
- }
-
- return physics_material_override->get_bounce();
-}
-#endif // DISABLE_DEPRECATED
-
void RigidBody::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
if (physics_material_override.is_valid()) {
if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
@@ -936,14 +811,6 @@ void RigidBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody::set_weight);
ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody::get_weight);
-#ifndef DISABLE_DEPRECATED
- ClassDB::bind_method(D_METHOD("set_friction", "friction"), &RigidBody::set_friction);
- ClassDB::bind_method(D_METHOD("get_friction"), &RigidBody::get_friction);
-
- ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &RigidBody::set_bounce);
- ClassDB::bind_method(D_METHOD("get_bounce"), &RigidBody::get_bounce);
-#endif // DISABLE_DEPRECATED
-
ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody::set_physics_material_override);
ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody::get_physics_material_override);
@@ -1006,10 +873,6 @@ void RigidBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight");
-#ifndef DISABLE_DEPRECATED
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce");
-#endif // DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator");
@@ -1104,6 +967,14 @@ Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_inf
return Ref<KinematicCollision>();
}
+Vector3 KinematicBody::get_linear_velocity() const {
+ return linear_velocity;
+}
+
+Vector3 KinematicBody::get_angular_velocity() const {
+ return angular_velocity;
+}
+
bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
Transform gt = get_global_transform();
@@ -1399,6 +1270,8 @@ void KinematicBody::_notification(int p_what) {
void KinematicBody::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody::_direct_state_changed);
+
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
@@ -1427,6 +1300,17 @@ void KinematicBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
+void KinematicBody::_direct_state_changed(Object *p_state) {
+#ifdef DEBUG_ENABLED
+ PhysicsDirectBodyState *state = Object::cast_to<PhysicsDirectBodyState>(p_state);
+#else
+ PhysicsDirectBodyState *state = (PhysicsDirectBodyState *)p_state; //trust it
+#endif
+
+ linear_velocity = state->get_linear_velocity();
+ angular_velocity = state->get_angular_velocity();
+}
+
KinematicBody::KinematicBody() :
PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) {
@@ -1435,6 +1319,8 @@ KinematicBody::KinematicBody() :
on_floor = false;
on_ceiling = false;
on_wall = false;
+
+ PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
}
KinematicBody::~KinematicBody() {
@@ -1471,7 +1357,7 @@ Object *KinematicCollision::get_local_shape() const {
Object *KinematicCollision::get_collider() const {
- if (collision.collider) {
+ if (collision.collider.is_valid()) {
return ObjectDB::get_instance(collision.collider);
}
@@ -1535,7 +1421,7 @@ void KinematicCollision::_bind_methods() {
}
KinematicCollision::KinematicCollision() {
- collision.collider = 0;
+
collision.collider_shape = 0;
collision.local_shape = 0;
owner = NULL;
@@ -1562,6 +1448,24 @@ void PhysicalBone::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse)
PhysicsServer::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
}
+void PhysicalBone::reset_physics_simulation_state() {
+ if (simulate_physics) {
+ _start_physics_simulation();
+ } else {
+ _stop_physics_simulation();
+ }
+}
+
+void PhysicalBone::reset_to_rest_position() {
+ if (parent_skeleton) {
+ if (-1 == bone_id) {
+ set_global_transform(parent_skeleton->get_global_transform() * body_offset);
+ } else {
+ set_global_transform(parent_skeleton->get_global_transform() * parent_skeleton->get_bone_global_pose(bone_id) * body_offset);
+ }
+ }
+}
+
bool PhysicalBone::PinJointData::_set(const StringName &p_name, const Variant &p_value, RID j) {
if (JointData::_set(p_name, p_value, j)) {
return true;
@@ -2167,7 +2071,7 @@ void PhysicalBone::_notification(int p_what) {
parent_skeleton = find_skeleton_parent(get_parent());
update_bone_id();
reset_to_rest_position();
- _reset_physics_simulation_state();
+ reset_physics_simulation_state();
if (!joint.is_valid() && joint_data) {
_reload_joint();
}
@@ -2238,8 +2142,6 @@ void PhysicalBone::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone::set_body_offset);
ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone::get_body_offset);
- ClassDB::bind_method(D_METHOD("is_static_body"), &PhysicalBone::is_static_body);
-
ClassDB::bind_method(D_METHOD("get_simulate_physics"), &PhysicalBone::get_simulate_physics);
ClassDB::bind_method(D_METHOD("is_simulating_physics"), &PhysicalBone::is_simulating_physics);
@@ -2508,26 +2410,13 @@ const Transform &PhysicalBone::get_joint_offset() const {
return joint_offset;
}
-void PhysicalBone::set_static_body(bool p_static) {
-
- static_body = p_static;
-
- set_as_toplevel(!static_body);
-
- _reset_physics_simulation_state();
-}
-
-bool PhysicalBone::is_static_body() {
- return static_body;
-}
-
void PhysicalBone::set_simulate_physics(bool p_simulate) {
if (simulate_physics == p_simulate) {
return;
}
simulate_physics = p_simulate;
- _reset_physics_simulation_state();
+ reset_physics_simulation_state();
}
bool PhysicalBone::get_simulate_physics() {
@@ -2535,7 +2424,7 @@ bool PhysicalBone::get_simulate_physics() {
}
bool PhysicalBone::is_simulating_physics() {
- return _internal_simulate_physics && !_internal_static_body;
+ return _internal_simulate_physics;
}
void PhysicalBone::set_bone_name(const String &p_name) {
@@ -2618,8 +2507,6 @@ PhysicalBone::PhysicalBone() :
#endif
joint_data(NULL),
parent_skeleton(NULL),
- static_body(false),
- _internal_static_body(false),
simulate_physics(false),
_internal_simulate_physics(false),
bone_id(-1),
@@ -2629,8 +2516,7 @@ PhysicalBone::PhysicalBone() :
friction(1),
gravity_scale(1) {
- set_static_body(static_body);
- _reset_physics_simulation_state();
+ reset_physics_simulation_state();
}
PhysicalBone::~PhysicalBone() {
@@ -2657,8 +2543,7 @@ void PhysicalBone::update_bone_id() {
parent_skeleton->bind_physical_bone_to_bone(bone_id, this);
_fix_joint_offset();
- _internal_static_body = !static_body; // Force staticness reset
- _reset_staticness_state();
+ reset_physics_simulation_state();
}
}
@@ -2680,49 +2565,6 @@ void PhysicalBone::update_offset() {
#endif
}
-void PhysicalBone::reset_to_rest_position() {
- if (parent_skeleton) {
- if (-1 == bone_id) {
- set_global_transform(parent_skeleton->get_global_transform() * body_offset);
- } else {
- set_global_transform(parent_skeleton->get_global_transform() * parent_skeleton->get_bone_global_pose(bone_id) * body_offset);
- }
- }
-}
-
-void PhysicalBone::_reset_physics_simulation_state() {
- if (simulate_physics && !static_body) {
- _start_physics_simulation();
- } else {
- _stop_physics_simulation();
- }
-
- _reset_staticness_state();
-}
-
-void PhysicalBone::_reset_staticness_state() {
-
- if (parent_skeleton && -1 != bone_id) {
- if (static_body && simulate_physics) { // With this check I'm sure the position of this body is updated only when it's necessary
-
- if (_internal_static_body) {
- return;
- }
-
- parent_skeleton->bind_child_node_to_bone(bone_id, this);
- _internal_static_body = true;
- } else {
-
- if (!_internal_static_body) {
- return;
- }
-
- parent_skeleton->unbind_child_node_from_bone(bone_id, this);
- _internal_static_body = false;
- }
- }
-}
-
void PhysicalBone::_start_physics_simulation() {
if (_internal_simulate_physics || !parent_skeleton) {
return;
@@ -2732,17 +2574,27 @@ void PhysicalBone::_start_physics_simulation() {
PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer());
PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask());
PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
+ set_as_toplevel(true);
_internal_simulate_physics = true;
}
void PhysicalBone::_stop_physics_simulation() {
- if (!_internal_simulate_physics || !parent_skeleton) {
+ if (!parent_skeleton) {
return;
}
- PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_STATIC);
- PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), 0);
- PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), 0);
- PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
- parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false);
- _internal_simulate_physics = false;
+ if (parent_skeleton->get_animate_physical_bones()) {
+ PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_KINEMATIC);
+ PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer());
+ PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask());
+ } else {
+ PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_STATIC);
+ PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), 0);
+ PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), 0);
+ }
+ if (_internal_simulate_physics) {
+ PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
+ parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false);
+ set_as_toplevel(false);
+ _internal_simulate_physics = false;
+ }
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 05bcbe22f0..5362baf8ee 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -49,7 +49,6 @@ class PhysicsBody : public CollisionObject {
protected:
static void _bind_methods();
- void _notification(int p_what);
PhysicsBody(PhysicsServer::BodyMode p_mode);
public:
@@ -89,14 +88,6 @@ protected:
static void _bind_methods();
public:
-#ifndef DISABLE_DEPRECATED
- void set_friction(real_t p_friction);
- real_t get_friction() const;
-
- void set_bounce(real_t p_bounce);
- real_t get_bounce() const;
-#endif
-
void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
Ref<PhysicsMaterial> get_physics_material_override() const;
@@ -205,14 +196,6 @@ public:
void set_weight(real_t p_weight);
real_t get_weight() const;
-#ifndef DISABLE_DEPRECATED
- void set_friction(real_t p_friction);
- real_t get_friction() const;
-
- void set_bounce(real_t p_bounce);
- real_t get_bounce() const;
-#endif
-
void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
Ref<PhysicsMaterial> get_physics_material_override() const;
@@ -296,6 +279,9 @@ public:
};
private:
+ Vector3 linear_velocity;
+ Vector3 angular_velocity;
+
uint16_t locked_axis;
float margin;
@@ -319,7 +305,12 @@ protected:
void _notification(int p_what);
static void _bind_methods();
+ virtual void _direct_state_changed(Object *p_state);
+
public:
+ virtual Vector3 get_linear_velocity() const;
+ virtual Vector3 get_angular_velocity() const;
+
bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia);
@@ -562,8 +553,6 @@ private:
Skeleton *parent_skeleton;
Transform body_offset;
Transform body_offset_inverse;
- bool static_body;
- bool _internal_static_body;
bool simulate_physics;
bool _internal_simulate_physics;
int bone_id;
@@ -613,9 +602,6 @@ public:
void set_body_offset(const Transform &p_offset);
const Transform &get_body_offset() const;
- void set_static_body(bool p_static);
- bool is_static_body();
-
void set_simulate_physics(bool p_simulate);
bool get_simulate_physics();
bool is_simulating_physics();
@@ -641,16 +627,15 @@ public:
void apply_central_impulse(const Vector3 &p_impulse);
void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
+ void reset_physics_simulation_state();
+ void reset_to_rest_position();
+
PhysicalBone();
~PhysicalBone();
private:
void update_bone_id();
void update_offset();
- void reset_to_rest_position();
-
- void _reset_physics_simulation_state();
- void _reset_staticness_state();
void _start_physics_simulation();
void _stop_physics_simulation();
diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp
index fbe3cd7a3e..be1426f13c 100644
--- a/scene/3d/ray_cast.cpp
+++ b/scene/3d/ray_cast.cpp
@@ -80,7 +80,7 @@ bool RayCast::is_colliding() const {
}
Object *RayCast::get_collider() const {
- if (against == 0)
+ if (against.is_null())
return NULL;
return ObjectDB::get_instance(against);
@@ -186,7 +186,7 @@ void RayCast::_notification(int p_what) {
_update_raycast_state();
if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) {
if (debug_material.is_valid()) {
- Ref<SpatialMaterial> line_material = static_cast<Ref<SpatialMaterial> >(debug_material);
+ Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D> >(debug_material);
line_material->set_albedo(collided ? Color(1.0, 0, 0) : Color(1.0, 0.8, 0.6));
}
}
@@ -219,7 +219,7 @@ void RayCast::_update_raycast_state() {
against_shape = rr.shape;
} else {
collided = false;
- against = 0;
+ against = ObjectID();
against_shape = 0;
}
}
@@ -333,11 +333,10 @@ void RayCast::_bind_methods() {
void RayCast::_create_debug_shape() {
if (!debug_material.is_valid()) {
- debug_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ debug_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
- Ref<SpatialMaterial> line_material = static_cast<Ref<SpatialMaterial> >(debug_material);
- line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- line_material->set_line_width(3.0);
+ Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D> >(debug_material);
+ line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
line_material->set_albedo(Color(1.0, 0.8, 0.6));
}
@@ -363,8 +362,7 @@ void RayCast::_update_debug_shape() {
return;
Ref<ArrayMesh> mesh = mi->get_mesh();
- if (mesh->get_surface_count() > 0)
- mesh->surface_remove(0);
+ mesh->clear_surfaces();
Array a;
a.resize(Mesh::ARRAY_MAX);
@@ -395,7 +393,7 @@ void RayCast::_clear_debug_shape() {
RayCast::RayCast() {
enabled = false;
- against = 0;
+
collided = false;
against_shape = 0;
collision_mask = 1;
diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp
index 983af7a9ec..9ef43647ba 100644
--- a/scene/3d/remote_transform.cpp
+++ b/scene/3d/remote_transform.cpp
@@ -31,7 +31,7 @@
#include "remote_transform.h"
void RemoteTransform::_update_cache() {
- cache = 0;
+ cache = ObjectID();
if (has_node(remote_node)) {
Node *node = get_node(remote_node);
if (!node || this == node || node->is_a_parent_of(this) || this->is_a_parent_of(node)) {
@@ -47,7 +47,7 @@ void RemoteTransform::_update_remote() {
if (!is_inside_tree())
return;
- if (!cache)
+ if (cache.is_null())
return;
Spatial *n = Object::cast_to<Spatial>(ObjectDB::get_instance(cache));
@@ -114,7 +114,7 @@ void RemoteTransform::_notification(int p_what) {
if (!is_inside_tree())
break;
- if (cache) {
+ if (cache.is_valid()) {
_update_remote();
}
@@ -219,6 +219,5 @@ RemoteTransform::RemoteTransform() {
update_remote_rotation = true;
update_remote_scale = true;
- cache = 0;
set_notify_transform(true);
}
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index 5edce284b5..aa5c439f8a 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -32,6 +32,7 @@
#include "core/message_queue.h"
+#include "core/engine.h"
#include "core/project_settings.h"
#include "scene/3d/physics_body.h"
#include "scene/resources/surface_tool.h"
@@ -137,7 +138,7 @@ bool Skeleton::_get(const StringName &p_path, Variant &r_ret) const {
else if (what == "bound_children") {
Array children;
- for (const List<uint32_t>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) {
+ for (const List<ObjectID>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) {
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
@@ -181,7 +182,7 @@ void Skeleton::_update_process_order() {
if (bonesptr[i].parent >= len) {
//validate this just in case
- ERR_PRINTS("Bone " + itos(i) + " has invalid parent: " + itos(bonesptr[i].parent));
+ ERR_PRINT("Bone " + itos(i) + " has invalid parent: " + itos(bonesptr[i].parent));
bonesptr[i].parent = -1;
}
order[i] = i;
@@ -301,7 +302,7 @@ void Skeleton::_notification(int p_what) {
b.global_pose_override_amount = 0.0;
}
- for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
+ for (List<ObjectID>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
@@ -332,6 +333,27 @@ void Skeleton::_notification(int p_what) {
dirty = false;
} break;
+
+#ifndef _3D_DISABLED
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ // This is active only if the skeleton animates the physical bones
+ // and the state of the bone is not active.
+ if (animate_physical_bones) {
+ for (int i = 0; i < bones.size(); i += 1) {
+ if (bones[i].physical_bone) {
+ if (bones[i].physical_bone->is_simulating_physics() == false) {
+ bones[i].physical_bone->reset_to_rest_position();
+ }
+ }
+ }
+ }
+ } break;
+ case NOTIFICATION_READY: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ set_physics_process_internal(true);
+ }
+ } break;
+#endif
}
}
@@ -483,9 +505,9 @@ void Skeleton::bind_child_node_to_bone(int p_bone, Node *p_node) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_INDEX(p_bone, bones.size());
- uint32_t id = p_node->get_instance_id();
+ ObjectID id = p_node->get_instance_id();
- for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
+ for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
if (E->get() == id)
return; // already here
@@ -498,14 +520,14 @@ void Skeleton::unbind_child_node_from_bone(int p_bone, Node *p_node) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_INDEX(p_bone, bones.size());
- uint32_t id = p_node->get_instance_id();
+ ObjectID id = p_node->get_instance_id();
bones.write[p_bone].nodes_bound.erase(id);
}
void Skeleton::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const {
ERR_FAIL_INDEX(p_bone, bones.size());
- for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
+ for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
@@ -584,6 +606,27 @@ void Skeleton::localize_rests() {
#ifndef _3D_DISABLED
+void Skeleton::set_animate_physical_bones(bool p_animate) {
+ animate_physical_bones = p_animate;
+
+ if (Engine::get_singleton()->is_editor_hint() == false) {
+ bool sim = false;
+ for (int i = 0; i < bones.size(); i += 1) {
+ if (bones[i].physical_bone) {
+ bones[i].physical_bone->reset_physics_simulation_state();
+ if (bones[i].physical_bone->is_simulating_physics()) {
+ sim = true;
+ }
+ }
+ }
+ set_physics_process_internal(sim == false && p_animate);
+ }
+}
+
+bool Skeleton::get_animate_physical_bones() const {
+ return animate_physical_bones;
+}
+
void Skeleton::bind_physical_bone_to_bone(int p_bone, PhysicalBone *p_physical_bone) {
ERR_FAIL_INDEX(p_bone, bones.size());
ERR_FAIL_COND(bones[p_bone].physical_bone);
@@ -653,12 +696,14 @@ void _pb_stop_simulation(Node *p_node) {
PhysicalBone *pb = Object::cast_to<PhysicalBone>(p_node);
if (pb) {
pb->set_simulate_physics(false);
- pb->set_static_body(false);
}
}
void Skeleton::physical_bones_stop_simulation() {
_pb_stop_simulation(this);
+ if (Engine::get_singleton()->is_editor_hint() == false && animate_physical_bones) {
+ set_physics_process_internal(true);
+ }
}
void _pb_start_simulation(const Skeleton *p_skeleton, Node *p_node, const Vector<int> &p_sim_bones) {
@@ -669,24 +714,17 @@ void _pb_start_simulation(const Skeleton *p_skeleton, Node *p_node, const Vector
PhysicalBone *pb = Object::cast_to<PhysicalBone>(p_node);
if (pb) {
- bool sim = false;
for (int i = p_sim_bones.size() - 1; 0 <= i; --i) {
if (p_sim_bones[i] == pb->get_bone_id() || p_skeleton->is_bone_parent_of(pb->get_bone_id(), p_sim_bones[i])) {
- sim = true;
+ pb->set_simulate_physics(true);
break;
}
}
-
- pb->set_simulate_physics(true);
- if (sim) {
- pb->set_static_body(false);
- } else {
- pb->set_static_body(true);
- }
}
}
void Skeleton::physical_bones_start_simulation_on(const Array &p_bones) {
+ set_physics_process_internal(false);
Vector<int> sim_bones;
if (p_bones.size() <= 0) {
@@ -792,7 +830,9 @@ Ref<SkinReference> Skeleton::register_skin(const Ref<Skin> &p_skin) {
skin_bindings.insert(skin_ref.operator->());
skin->connect("changed", skin_ref.operator->(), "_skin_changed");
- _make_dirty();
+
+ _make_dirty(); //skin needs to be updated, so update skeleton
+
return skin_ref;
}
@@ -836,11 +876,15 @@ void Skeleton::_bind_methods() {
#ifndef _3D_DISABLED
+ ClassDB::bind_method(D_METHOD("set_animate_physical_bones"), &Skeleton::set_animate_physical_bones);
+ ClassDB::bind_method(D_METHOD("get_animate_physical_bones"), &Skeleton::get_animate_physical_bones);
+
ClassDB::bind_method(D_METHOD("physical_bones_stop_simulation"), &Skeleton::physical_bones_stop_simulation);
ClassDB::bind_method(D_METHOD("physical_bones_start_simulation", "bones"), &Skeleton::physical_bones_start_simulation_on, DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("physical_bones_add_collision_exception", "exception"), &Skeleton::physical_bones_add_collision_exception);
ClassDB::bind_method(D_METHOD("physical_bones_remove_collision_exception", "exception"), &Skeleton::physical_bones_remove_collision_exception);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones");
#endif // _3D_DISABLED
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
@@ -848,6 +892,7 @@ void Skeleton::_bind_methods() {
Skeleton::Skeleton() {
+ animate_physical_bones = true;
dirty = false;
process_order_dirty = true;
}
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 056f70e22b..b42c2112e3 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -99,7 +99,7 @@ private:
PhysicalBone *cache_parent_physical_bone;
#endif // _3D_DISABLED
- List<uint32_t> nodes_bound;
+ List<ObjectID> nodes_bound;
Bone() {
parent = -1;
@@ -115,6 +115,7 @@ private:
}
};
+ bool animate_physical_bones;
Vector<Bone> bones;
Vector<int> process_order;
bool process_order_dirty;
@@ -199,6 +200,9 @@ public:
#ifndef _3D_DISABLED
// Physical bone API
+ void set_animate_physical_bones(bool p_animate);
+ bool get_animate_physical_bones() const;
+
void bind_physical_bone_to_bone(int p_bone, PhysicalBone *p_physical_bone);
void unbind_physical_bone_from_bone(int p_bone);
diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp
index ef13985bf4..931e786455 100644
--- a/scene/3d/soft_body.cpp
+++ b/scene/3d/soft_body.cpp
@@ -47,7 +47,10 @@ void SoftBodyVisualServerHandler::prepare(RID p_mesh, int p_surface) {
mesh = p_mesh;
surface = p_surface;
-
+#ifndef _MSC_VER
+#warning Softbody is not working, needs to be redone considering that these functions no longer exist
+#endif
+#if 0
const uint32_t surface_format = VS::get_singleton()->mesh_surface_get_format(mesh, surface);
const int surface_vertex_len = VS::get_singleton()->mesh_surface_get_array_len(mesh, p_surface);
const int surface_index_len = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, p_surface);
@@ -57,6 +60,7 @@ void SoftBodyVisualServerHandler::prepare(RID p_mesh, int p_surface) {
stride = VS::get_singleton()->mesh_surface_make_offsets_from_format(surface_format, surface_vertex_len, surface_index_len, surface_offsets);
offset_vertices = surface_offsets[VS::ARRAY_VERTEX];
offset_normal = surface_offsets[VS::ARRAY_NORMAL];
+#endif
}
void SoftBodyVisualServerHandler::clear() {
@@ -247,7 +251,7 @@ bool SoftBody::_get_property_pinned_points(int p_item, const String &p_what, Var
}
void SoftBody::_changed_callback(Object *p_changed, const char *p_prop) {
- update_physics_server();
+ prepare_physics_server();
_reset_points_offsets();
#ifdef TOOLS_ENABLED
if (p_changed == this) {
@@ -267,7 +271,7 @@ void SoftBody::_notification(int p_what) {
RID space = get_world()->get_space();
PhysicsServer::get_singleton()->soft_body_set_space(physics_rid, space);
- update_physics_server();
+ prepare_physics_server();
} break;
case NOTIFICATION_READY: {
if (!parent_collision_ignore.is_empty())
@@ -290,21 +294,6 @@ void SoftBody::_notification(int p_what) {
set_notify_transform(true);
} break;
- case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
- if (!simulation_started)
- return;
-
- _update_cache_pin_points_datas();
- // Submit bone attachment
- const int pinned_points_indices_size = pinned_points.size();
- PoolVector<PinnedPoint>::Read r = pinned_points.read();
- for (int i = 0; i < pinned_points_indices_size; ++i) {
- if (r[i].spatial_attachment) {
- PhysicsServer::get_singleton()->soft_body_move_point(physics_rid, r[i].point_index, r[i].spatial_attachment->get_global_transform().xform(r[i].offset));
- }
- }
- } break;
case NOTIFICATION_VISIBILITY_CHANGED: {
_update_pickable();
@@ -421,6 +410,21 @@ String SoftBody::get_configuration_warning() const {
return warning;
}
+void SoftBody::_update_physics_server() {
+ if (!simulation_started)
+ return;
+
+ _update_cache_pin_points_datas();
+ // Submit bone attachment
+ const int pinned_points_indices_size = pinned_points.size();
+ PoolVector<PinnedPoint>::Read r = pinned_points.read();
+ for (int i = 0; i < pinned_points_indices_size; ++i) {
+ if (r[i].spatial_attachment) {
+ PhysicsServer::get_singleton()->soft_body_move_point(physics_rid, r[i].point_index, r[i].spatial_attachment->get_global_transform().xform(r[i].offset));
+ }
+ }
+}
+
void SoftBody::_draw_soft_mesh() {
if (get_mesh().is_null())
return;
@@ -435,6 +439,8 @@ void SoftBody::_draw_soft_mesh() {
call_deferred("set_transform", Transform());
}
+ _update_physics_server();
+
visual_server_handler.open();
PhysicsServer::get_singleton()->soft_body_update_visual_server(physics_rid, &visual_server_handler);
visual_server_handler.close();
@@ -442,7 +448,7 @@ void SoftBody::_draw_soft_mesh() {
visual_server_handler.commit_changes();
}
-void SoftBody::update_physics_server() {
+void SoftBody::prepare_physics_server() {
if (Engine::get_singleton()->is_editor_hint()) {
@@ -483,14 +489,15 @@ void SoftBody::become_mesh_owner() {
// Get current mesh array and create new mesh array with necessary flag for softbody
Array surface_arrays = mesh->surface_get_arrays(0);
Array surface_blend_arrays = mesh->surface_get_blend_shape_arrays(0);
+ Dictionary surface_lods = mesh->surface_get_lods(0);
uint32_t surface_format = mesh->surface_get_format(0);
- surface_format &= ~(Mesh::ARRAY_COMPRESS_VERTEX | Mesh::ARRAY_COMPRESS_NORMAL);
+ surface_format &= ~(Mesh::ARRAY_COMPRESS_NORMAL);
surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE;
Ref<ArrayMesh> soft_mesh;
soft_mesh.instance();
- soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_format);
+ soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_lods, surface_format);
soft_mesh->surface_set_material(0, mesh->surface_get_material(0));
set_mesh(soft_mesh);
@@ -706,8 +713,6 @@ SoftBody::SoftBody() :
ray_pickable(true) {
PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
- //set_notify_transform(true);
- set_physics_process_internal(true);
}
SoftBody::~SoftBody() {
diff --git a/scene/3d/soft_body.h b/scene/3d/soft_body.h
index 629c2e42a5..800db12594 100644
--- a/scene/3d/soft_body.h
+++ b/scene/3d/soft_body.h
@@ -116,10 +116,11 @@ protected:
virtual String get_configuration_warning() const;
protected:
+ void _update_physics_server();
void _draw_soft_mesh();
public:
- void update_physics_server();
+ void prepare_physics_server();
void become_mesh_owner();
void set_collision_mask(uint32_t p_mask);
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index a4c81b864d..04f00a527e 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -286,14 +286,14 @@ SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const {
return alpha_cut;
}
-void SpriteBase3D::set_billboard_mode(SpatialMaterial::BillboardMode p_mode) {
+void SpriteBase3D::set_billboard_mode(StandardMaterial3D::BillboardMode p_mode) {
ERR_FAIL_INDEX(p_mode, 3);
billboard_mode = p_mode;
_queue_update();
}
-SpatialMaterial::BillboardMode SpriteBase3D::get_billboard_mode() const {
+StandardMaterial3D::BillboardMode SpriteBase3D::get_billboard_mode() const {
return billboard_mode;
}
@@ -377,7 +377,7 @@ SpriteBase3D::SpriteBase3D() {
flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED;
alpha_cut = ALPHA_CUT_DISABLED;
- billboard_mode = SpatialMaterial::BILLBOARD_DISABLED;
+ billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
axis = Vector3::AXIS_Z;
pixel_size = 0.01;
modulate = Color(1, 1, 1, 1);
@@ -480,10 +480,10 @@ void Sprite3D::_draw() {
tangent = Plane(1, 0, 0, 1);
}
- RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == SpatialMaterial::BILLBOARD_ENABLED, get_billboard_mode() == SpatialMaterial::BILLBOARD_FIXED_Y);
+ RID mat = StandardMaterial3D::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y);
VS::get_singleton()->immediate_set_material(immediate, mat);
- VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid());
+ VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLES, texture->get_rid());
int x_axis = ((axis + 1) % 3);
int y_axis = ((axis + 2) % 3);
@@ -504,15 +504,18 @@ void Sprite3D::_draw() {
AABB aabb;
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < 6; i++) {
+
+ static const int index[6] = { 0, 1, 2, 0, 2, 3 };
+
VS::get_singleton()->immediate_normal(immediate, normal);
VS::get_singleton()->immediate_tangent(immediate, tangent);
VS::get_singleton()->immediate_color(immediate, color);
VS::get_singleton()->immediate_uv(immediate, uvs[i]);
Vector3 vtx;
- vtx[x_axis] = vertices[i][0];
- vtx[y_axis] = vertices[i][1];
+ vtx[x_axis] = vertices[index[i]][0];
+ vtx[y_axis] = vertices[index[i]][1];
VS::get_singleton()->immediate_vertex(immediate, vtx);
if (i == 0) {
aabb.position = vtx;
@@ -525,7 +528,7 @@ void Sprite3D::_draw() {
VS::get_singleton()->immediate_end(immediate);
}
-void Sprite3D::set_texture(const Ref<Texture> &p_texture) {
+void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
if (p_texture == texture)
return;
@@ -534,13 +537,12 @@ void Sprite3D::set_texture(const Ref<Texture> &p_texture) {
}
texture = p_texture;
if (texture.is_valid()) {
- texture->set_flags(texture->get_flags()); //remove repeat from texture, it looks bad in sprites
texture->connect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_queue_update);
}
_queue_update();
}
-Ref<Texture> Sprite3D::get_texture() const {
+Ref<Texture2D> Sprite3D::get_texture() const {
return texture;
}
@@ -691,7 +693,7 @@ void Sprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hframes", "hframes"), &Sprite3D::set_hframes);
ClassDB::bind_method(D_METHOD("get_hframes"), &Sprite3D::get_hframes);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_GROUP("Animation", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
@@ -731,7 +733,7 @@ void AnimatedSprite3D::_draw() {
return;
}
- Ref<Texture> texture = frames->get_frame(animation, frame);
+ Ref<Texture2D> texture = frames->get_frame(animation, frame);
if (!texture.is_valid())
return; //no texuture no life
Vector2 tsize = texture->get_size();
@@ -808,11 +810,11 @@ void AnimatedSprite3D::_draw() {
tangent = Plane(1, 0, 0, -1);
}
- RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == SpatialMaterial::BILLBOARD_ENABLED, get_billboard_mode() == SpatialMaterial::BILLBOARD_FIXED_Y);
+ RID mat = StandardMaterial3D::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y);
VS::get_singleton()->immediate_set_material(immediate, mat);
- VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid());
+ VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLES, texture->get_rid());
int x_axis = ((axis + 1) % 3);
int y_axis = ((axis + 2) % 3);
@@ -833,15 +835,21 @@ void AnimatedSprite3D::_draw() {
AABB aabb;
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < 6; i++) {
+
+ static const int indices[6] = {
+ 0, 1, 2,
+ 0, 2, 3
+ };
+
VS::get_singleton()->immediate_normal(immediate, normal);
VS::get_singleton()->immediate_tangent(immediate, tangent);
VS::get_singleton()->immediate_color(immediate, color);
VS::get_singleton()->immediate_uv(immediate, uvs[i]);
Vector3 vtx;
- vtx[x_axis] = vertices[i][0];
- vtx[y_axis] = vertices[i][1];
+ vtx[x_axis] = vertices[indices[i]][0];
+ vtx[y_axis] = vertices[indices[i]][1];
VS::get_singleton()->immediate_vertex(immediate, vtx);
if (i == 0) {
aabb.position = vtx;
@@ -1003,7 +1011,7 @@ Rect2 AnimatedSprite3D::get_item_rect() const {
return Rect2(0, 0, 1, 1);
}
- Ref<Texture> t;
+ Ref<Texture2D> t;
if (animation)
t = frames->get_frame(animation, frame);
if (t.is_null())
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index ddbade147c..9c31a667b5 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -80,7 +80,7 @@ private:
bool flags[FLAG_MAX];
AlphaCutMode alpha_cut;
- SpatialMaterial::BillboardMode billboard_mode;
+ StandardMaterial3D::BillboardMode billboard_mode;
bool pending_update;
void _im_update();
@@ -131,8 +131,8 @@ public:
void set_alpha_cut_mode(AlphaCutMode p_mode);
AlphaCutMode get_alpha_cut_mode() const;
- void set_billboard_mode(SpatialMaterial::BillboardMode p_mode);
- SpatialMaterial::BillboardMode get_billboard_mode() const;
+ void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode);
+ StandardMaterial3D::BillboardMode get_billboard_mode() const;
virtual Rect2 get_item_rect() const = 0;
@@ -147,7 +147,7 @@ public:
class Sprite3D : public SpriteBase3D {
GDCLASS(Sprite3D, SpriteBase3D);
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
bool region;
Rect2 region_rect;
@@ -164,8 +164,8 @@ protected:
virtual void _validate_property(PropertyInfo &property) const;
public:
- void set_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture() const;
void set_region(bool p_region);
bool is_region() const;
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index 92b17d5056..52e50aa84e 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -364,9 +364,8 @@ VehicleWheel::VehicleWheel() {
steers = false;
engine_traction = false;
-
m_steering = real_t(0.);
- //m_engineForce = real_t(0.);
+ m_engineForce = real_t(0.);
m_rotation = real_t(0.);
m_deltaRotation = real_t(0.);
m_brake = real_t(0.);
diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp
index 4574dfac5f..5a332fe0f9 100644
--- a/scene/3d/visual_instance.cpp
+++ b/scene/3d/visual_instance.cpp
@@ -294,10 +294,11 @@ void GeometryInstance::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_aabb"), &GeometryInstance::get_aabb);
ADD_GROUP("Geometry", "");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial"), "set_material_override", "get_material_override");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D"), "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.01"), "set_extra_cull_margin", "get_extra_cull_margin");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_in_baked_light"), "set_flag", "get_flag", FLAG_USE_BAKED_LIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_dynamic_gi"), "set_flag", "get_flag", FLAG_USE_DYNAMIC_GI);
ADD_GROUP("LOD", "lod_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_min_distance", PROPERTY_HINT_RANGE, "0,32768,0.01"), "set_lod_min_distance", "get_lod_min_distance");
@@ -313,6 +314,7 @@ void GeometryInstance::_bind_methods() {
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_SHADOWS_ONLY);
BIND_ENUM_CONSTANT(FLAG_USE_BAKED_LIGHT);
+ BIND_ENUM_CONSTANT(FLAG_USE_DYNAMIC_GI);
BIND_ENUM_CONSTANT(FLAG_DRAW_NEXT_FRAME_IF_VISIBLE);
BIND_ENUM_CONSTANT(FLAG_MAX);
}
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index f115748952..c1d6c2b015 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -87,6 +87,7 @@ class GeometryInstance : public VisualInstance {
public:
enum Flags {
FLAG_USE_BAKED_LIGHT = VS::INSTANCE_FLAG_USE_BAKED_LIGHT,
+ FLAG_USE_DYNAMIC_GI = VS::INSTANCE_FLAG_USE_DYNAMIC_GI,
FLAG_DRAW_NEXT_FRAME_IF_VISIBLE = VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE,
FLAG_MAX = VS::INSTANCE_FLAG_MAX,
};
diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp
deleted file mode 100644
index c1ec59d49f..0000000000
--- a/scene/3d/voxel_light_baker.cpp
+++ /dev/null
@@ -1,2486 +0,0 @@
-/*************************************************************************/
-/* voxel_light_baker.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "voxel_light_baker.h"
-
-#include "core/os/os.h"
-#include "core/os/threaded_array_processor.h"
-
-#include <stdlib.h>
-
-#define FINDMINMAX(x0, x1, x2, min, max) \
- min = max = x0; \
- if (x1 < min) min = x1; \
- if (x1 > max) max = x1; \
- if (x2 < min) min = x2; \
- if (x2 > max) max = x2;
-
-static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
- int q;
- Vector3 vmin, vmax;
- for (q = 0; q <= 2; q++) {
- if (normal[q] > 0.0f) {
- vmin[q] = -maxbox[q];
- vmax[q] = maxbox[q];
- } else {
- vmin[q] = maxbox[q];
- vmax[q] = -maxbox[q];
- }
- }
- if (normal.dot(vmin) + d > 0.0f) return false;
- if (normal.dot(vmax) + d >= 0.0f) return true;
-
- return false;
-}
-
-/*======================== X-tests ========================*/
-#define AXISTEST_X01(a, b, fa, fb) \
- p0 = a * v0.y - b * v0.z; \
- p2 = a * v2.y - b * v2.z; \
- if (p0 < p2) { \
- min = p0; \
- max = p2; \
- } else { \
- min = p2; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_X2(a, b, fa, fb) \
- p0 = a * v0.y - b * v0.z; \
- p1 = a * v1.y - b * v1.z; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-/*======================== Y-tests ========================*/
-#define AXISTEST_Y02(a, b, fa, fb) \
- p0 = -a * v0.x + b * v0.z; \
- p2 = -a * v2.x + b * v2.z; \
- if (p0 < p2) { \
- min = p0; \
- max = p2; \
- } else { \
- min = p2; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_Y1(a, b, fa, fb) \
- p0 = -a * v0.x + b * v0.z; \
- p1 = -a * v1.x + b * v1.z; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-/*======================== Z-tests ========================*/
-
-#define AXISTEST_Z12(a, b, fa, fb) \
- p1 = a * v1.x - b * v1.y; \
- p2 = a * v2.x - b * v2.y; \
- if (p2 < p1) { \
- min = p2; \
- max = p1; \
- } else { \
- min = p1; \
- max = p2; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_Z0(a, b, fa, fb) \
- p0 = a * v0.x - b * v0.y; \
- p1 = a * v1.x - b * v1.y; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
- if (min > rad || max < -rad) return false;
-
-static bool fast_tri_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) {
-
- /* use separating axis theorem to test overlap between triangle and box */
- /* need to test for overlap in these directions: */
- /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
- /* we do not even need to test these) */
- /* 2) normal of the triangle */
- /* 3) crossproduct(edge from tri, {x,y,z}-directin) */
- /* this gives 3x3=9 more tests */
- Vector3 v0, v1, v2;
- float min, max, d, p0, p1, p2, rad, fex, fey, fez;
- Vector3 normal, e0, e1, e2;
-
- /* This is the fastest branch on Sun */
- /* move everything so that the boxcenter is in (0,0,0) */
-
- v0 = triverts[0] - boxcenter;
- v1 = triverts[1] - boxcenter;
- v2 = triverts[2] - boxcenter;
-
- /* compute triangle edges */
- e0 = v1 - v0; /* tri edge 0 */
- e1 = v2 - v1; /* tri edge 1 */
- e2 = v0 - v2; /* tri edge 2 */
-
- /* Bullet 3: */
- /* test the 9 tests first (this was faster) */
- fex = Math::abs(e0.x);
- fey = Math::abs(e0.y);
- fez = Math::abs(e0.z);
- AXISTEST_X01(e0.z, e0.y, fez, fey);
- AXISTEST_Y02(e0.z, e0.x, fez, fex);
- AXISTEST_Z12(e0.y, e0.x, fey, fex);
-
- fex = Math::abs(e1.x);
- fey = Math::abs(e1.y);
- fez = Math::abs(e1.z);
- AXISTEST_X01(e1.z, e1.y, fez, fey);
- AXISTEST_Y02(e1.z, e1.x, fez, fex);
- AXISTEST_Z0(e1.y, e1.x, fey, fex);
-
- fex = Math::abs(e2.x);
- fey = Math::abs(e2.y);
- fez = Math::abs(e2.z);
- AXISTEST_X2(e2.z, e2.y, fez, fey);
- AXISTEST_Y1(e2.z, e2.x, fez, fex);
- AXISTEST_Z12(e2.y, e2.x, fey, fex);
-
- /* Bullet 1: */
- /* first test overlap in the {x,y,z}-directions */
- /* find min, max of the triangle each direction, and test for overlap in */
- /* that direction -- this is equivalent to testing a minimal AABB around */
- /* the triangle against the AABB */
-
- /* test in X-direction */
- FINDMINMAX(v0.x, v1.x, v2.x, min, max);
- if (min > boxhalfsize.x || max < -boxhalfsize.x) return false;
-
- /* test in Y-direction */
- FINDMINMAX(v0.y, v1.y, v2.y, min, max);
- if (min > boxhalfsize.y || max < -boxhalfsize.y) return false;
-
- /* test in Z-direction */
- FINDMINMAX(v0.z, v1.z, v2.z, min, max);
- if (min > boxhalfsize.z || max < -boxhalfsize.z) return false;
-
- /* Bullet 2: */
- /* test if the box intersects the plane of the triangle */
- /* compute plane equation of triangle: normal*x+d=0 */
- normal = e0.cross(e1);
- d = -normal.dot(v0); /* plane eq: normal.x+d=0 */
- return planeBoxOverlap(normal, d, boxhalfsize); /* if true, box and triangle overlaps */
-}
-
-static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3 *p_vtx, const Vector2 *p_uv, const Vector3 *p_normal, Vector2 &r_uv, Vector3 &r_normal) {
-
- if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2) {
- r_uv = p_uv[0];
- r_normal = p_normal[0];
- return;
- }
- if (p_pos.distance_squared_to(p_vtx[1]) < CMP_EPSILON2) {
- r_uv = p_uv[1];
- r_normal = p_normal[1];
- return;
- }
- if (p_pos.distance_squared_to(p_vtx[2]) < CMP_EPSILON2) {
- r_uv = p_uv[2];
- r_normal = p_normal[2];
- return;
- }
-
- Vector3 v0 = p_vtx[1] - p_vtx[0];
- Vector3 v1 = p_vtx[2] - p_vtx[0];
- Vector3 v2 = p_pos - p_vtx[0];
-
- float d00 = v0.dot(v0);
- float d01 = v0.dot(v1);
- float d11 = v1.dot(v1);
- float d20 = v2.dot(v0);
- float d21 = v2.dot(v1);
- float denom = (d00 * d11 - d01 * d01);
- if (denom == 0) {
- r_uv = p_uv[0];
- r_normal = p_normal[0];
- return;
- }
- float v = (d11 * d20 - d01 * d21) / denom;
- float w = (d00 * d21 - d01 * d20) / denom;
- float u = 1.0f - v - w;
-
- r_uv = p_uv[0] * u + p_uv[1] * v + p_uv[2] * w;
- r_normal = (p_normal[0] * u + p_normal[1] * v + p_normal[2] * w).normalized();
-}
-
-void VoxelLightBaker::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb) {
-
- if (p_level == cell_subdiv - 1) {
- //plot the face by guessing its albedo and emission value
-
- //find best axis to map to, for scanning values
- int closest_axis = 0;
- float closest_dot = 0;
-
- Plane plane = Plane(p_vtx[0], p_vtx[1], p_vtx[2]);
- Vector3 normal = plane.normal;
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 axis;
- axis[i] = 1.0;
- float dot = ABS(normal.dot(axis));
- if (i == 0 || dot > closest_dot) {
- closest_axis = i;
- closest_dot = dot;
- }
- }
-
- Vector3 axis;
- axis[closest_axis] = 1.0;
- Vector3 t1;
- t1[(closest_axis + 1) % 3] = 1.0;
- Vector3 t2;
- t2[(closest_axis + 2) % 3] = 1.0;
-
- t1 *= p_aabb.size[(closest_axis + 1) % 3] / float(color_scan_cell_width);
- t2 *= p_aabb.size[(closest_axis + 2) % 3] / float(color_scan_cell_width);
-
- Color albedo_accum;
- Color emission_accum;
- Vector3 normal_accum;
-
- float alpha = 0.0;
-
- //map to a grid average in the best axis for this face
- for (int i = 0; i < color_scan_cell_width; i++) {
-
- Vector3 ofs_i = float(i) * t1;
-
- for (int j = 0; j < color_scan_cell_width; j++) {
-
- Vector3 ofs_j = float(j) * t2;
-
- Vector3 from = p_aabb.position + ofs_i + ofs_j;
- Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis];
- Vector3 half = (to - from) * 0.5;
-
- //is in this cell?
- if (!fast_tri_box_overlap(from + half, half, p_vtx)) {
- continue; //face does not span this cell
- }
-
- //go from -size to +size*2 to avoid skipping collisions
- Vector3 ray_from = from + (t1 + t2) * 0.5 - axis * p_aabb.size[closest_axis];
- Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis] * 2;
-
- if (normal.dot(ray_from - ray_to) < 0) {
- SWAP(ray_from, ray_to);
- }
-
- Vector3 intersection;
-
- if (!plane.intersects_segment(ray_from, ray_to, &intersection)) {
- if (ABS(plane.distance_to(ray_from)) < ABS(plane.distance_to(ray_to))) {
- intersection = plane.project(ray_from);
- } else {
-
- intersection = plane.project(ray_to);
- }
- }
-
- intersection = Face3(p_vtx[0], p_vtx[1], p_vtx[2]).get_closest_point_to(intersection);
-
- Vector2 uv;
- Vector3 lnormal;
- get_uv_and_normal(intersection, p_vtx, p_uv, p_normal, uv, lnormal);
- if (lnormal == Vector3()) //just in case normal as nor provided
- lnormal = normal;
-
- int uv_x = CLAMP(int(Math::fposmod(uv.x, 1.0f) * bake_texture_size), 0, bake_texture_size - 1);
- int uv_y = CLAMP(int(Math::fposmod(uv.y, 1.0f) * bake_texture_size), 0, bake_texture_size - 1);
-
- int ofs = uv_y * bake_texture_size + uv_x;
- albedo_accum.r += p_material.albedo[ofs].r;
- albedo_accum.g += p_material.albedo[ofs].g;
- albedo_accum.b += p_material.albedo[ofs].b;
- albedo_accum.a += p_material.albedo[ofs].a;
-
- emission_accum.r += p_material.emission[ofs].r;
- emission_accum.g += p_material.emission[ofs].g;
- emission_accum.b += p_material.emission[ofs].b;
-
- normal_accum += lnormal;
-
- alpha += 1.0;
- }
- }
-
- if (alpha == 0) {
- //could not in any way get texture information.. so use closest point to center
-
- Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]);
- Vector3 inters = f.get_closest_point_to(p_aabb.position + p_aabb.size * 0.5);
-
- Vector3 lnormal;
- Vector2 uv;
- get_uv_and_normal(inters, p_vtx, p_uv, p_normal, uv, normal);
- if (lnormal == Vector3()) //just in case normal as nor provided
- lnormal = normal;
-
- int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
- int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
-
- int ofs = uv_y * bake_texture_size + uv_x;
-
- alpha = 1.0 / (color_scan_cell_width * color_scan_cell_width);
-
- albedo_accum.r = p_material.albedo[ofs].r * alpha;
- albedo_accum.g = p_material.albedo[ofs].g * alpha;
- albedo_accum.b = p_material.albedo[ofs].b * alpha;
- albedo_accum.a = p_material.albedo[ofs].a * alpha;
-
- emission_accum.r = p_material.emission[ofs].r * alpha;
- emission_accum.g = p_material.emission[ofs].g * alpha;
- emission_accum.b = p_material.emission[ofs].b * alpha;
-
- normal_accum = lnormal * alpha;
-
- } else {
-
- float accdiv = 1.0 / (color_scan_cell_width * color_scan_cell_width);
- alpha *= accdiv;
-
- albedo_accum.r *= accdiv;
- albedo_accum.g *= accdiv;
- albedo_accum.b *= accdiv;
- albedo_accum.a *= accdiv;
-
- emission_accum.r *= accdiv;
- emission_accum.g *= accdiv;
- emission_accum.b *= accdiv;
-
- normal_accum *= accdiv;
- }
-
- //put this temporarily here, corrected in a later step
- bake_cells.write[p_idx].albedo[0] += albedo_accum.r;
- bake_cells.write[p_idx].albedo[1] += albedo_accum.g;
- bake_cells.write[p_idx].albedo[2] += albedo_accum.b;
- bake_cells.write[p_idx].emission[0] += emission_accum.r;
- bake_cells.write[p_idx].emission[1] += emission_accum.g;
- bake_cells.write[p_idx].emission[2] += emission_accum.b;
- bake_cells.write[p_idx].normal[0] += normal_accum.x;
- bake_cells.write[p_idx].normal[1] += normal_accum.y;
- bake_cells.write[p_idx].normal[2] += normal_accum.z;
- bake_cells.write[p_idx].alpha += alpha;
-
- } else {
- //go down
-
- int half = (1 << (cell_subdiv - 1)) >> (p_level + 1);
- for (int i = 0; i < 8; i++) {
-
- AABB aabb = p_aabb;
- aabb.size *= 0.5;
-
- int nx = p_x;
- int ny = p_y;
- int nz = p_z;
-
- if (i & 1) {
- aabb.position.x += aabb.size.x;
- nx += half;
- }
- if (i & 2) {
- aabb.position.y += aabb.size.y;
- ny += half;
- }
- if (i & 4) {
- aabb.position.z += aabb.size.z;
- nz += half;
- }
- //make sure to not plot beyond limits
- if (nx < 0 || nx >= axis_cell_size[0] || ny < 0 || ny >= axis_cell_size[1] || nz < 0 || nz >= axis_cell_size[2])
- continue;
-
- {
- AABB test_aabb = aabb;
- //test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
- Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test
-
- if (!fast_tri_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) {
- //if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
- //does not fit in child, go on
- continue;
- }
- }
-
- if (bake_cells[p_idx].children[i] == CHILD_EMPTY) {
- //sub cell must be created
-
- uint32_t child_idx = bake_cells.size();
- bake_cells.write[p_idx].children[i] = child_idx;
- bake_cells.resize(bake_cells.size() + 1);
- bake_cells.write[child_idx].level = p_level + 1;
- }
-
- _plot_face(bake_cells[p_idx].children[i], p_level + 1, nx, ny, nz, p_vtx, p_normal, p_uv, p_material, aabb);
- }
- }
-}
-
-Vector<Color> VoxelLightBaker::_get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add) {
-
- Vector<Color> ret;
-
- if (p_image.is_null() || p_image->empty()) {
-
- ret.resize(bake_texture_size * bake_texture_size);
- for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
- ret.write[i] = p_color_add;
- }
-
- return ret;
- }
- p_image = p_image->duplicate();
-
- if (p_image->is_compressed()) {
- p_image->decompress();
- }
- p_image->convert(Image::FORMAT_RGBA8);
- p_image->resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC);
-
- PoolVector<uint8_t>::Read r = p_image->get_data().read();
- ret.resize(bake_texture_size * bake_texture_size);
-
- for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
- Color c;
- c.r = (r[i * 4 + 0] / 255.0) * p_color_mul.r + p_color_add.r;
- c.g = (r[i * 4 + 1] / 255.0) * p_color_mul.g + p_color_add.g;
- c.b = (r[i * 4 + 2] / 255.0) * p_color_mul.b + p_color_add.b;
-
- c.a = r[i * 4 + 3] / 255.0;
-
- ret.write[i] = c;
- }
-
- return ret;
-}
-
-VoxelLightBaker::MaterialCache VoxelLightBaker::_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<SpatialMaterial> mat = p_material;
-
- Ref<Material> material = mat; //hack for now
-
- if (material_cache.has(material)) {
- return material_cache[material];
- }
-
- MaterialCache mc;
-
- if (mat.is_valid()) {
-
- Ref<Texture> albedo_tex = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
-
- Ref<Image> img_albedo;
- if (albedo_tex.is_valid()) {
-
- img_albedo = albedo_tex->get_data();
- mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), Color(0, 0, 0)); // albedo texture, color is multiplicative
- } else {
- mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive
- }
-
- Ref<Texture> emission_tex = mat->get_texture(SpatialMaterial::TEXTURE_EMISSION);
-
- Color emission_col = mat->get_emission();
- float emission_energy = mat->get_emission_energy();
-
- Ref<Image> img_emission;
-
- if (emission_tex.is_valid()) {
-
- img_emission = emission_tex->get_data();
- }
-
- if (mat->get_emission_operator() == SpatialMaterial::EMISSION_OP_ADD) {
- mc.emission = _get_bake_texture(img_emission, Color(1, 1, 1) * emission_energy, emission_col * emission_energy);
- } else {
- mc.emission = _get_bake_texture(img_emission, emission_col * emission_energy, Color(0, 0, 0));
- }
-
- } else {
- Ref<Image> empty;
-
- mc.albedo = _get_bake_texture(empty, Color(0, 0, 0), Color(1, 1, 1));
- mc.emission = _get_bake_texture(empty, Color(0, 0, 0), Color(0, 0, 0));
- }
-
- material_cache[p_material] = mc;
- return mc;
-}
-
-void VoxelLightBaker::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) {
-
- for (int i = 0; i < p_mesh->get_surface_count(); i++) {
-
- if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
- continue; //only triangles
-
- Ref<Material> src_material;
-
- if (p_override_material.is_valid()) {
- src_material = p_override_material;
- } else if (i < p_materials.size() && p_materials[i].is_valid()) {
- src_material = p_materials[i];
- } else {
- src_material = p_mesh->surface_get_material(i);
- }
- MaterialCache material = _get_material_cache(src_material);
-
- Array a = p_mesh->surface_get_arrays(i);
-
- PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
- PoolVector<Vector3>::Read vr = vertices.read();
- PoolVector<Vector2> uv = a[Mesh::ARRAY_TEX_UV];
- PoolVector<Vector2>::Read uvr;
- PoolVector<Vector3> normals = a[Mesh::ARRAY_NORMAL];
- PoolVector<Vector3>::Read nr;
- PoolVector<int> index = a[Mesh::ARRAY_INDEX];
-
- bool read_uv = false;
- bool read_normals = false;
-
- if (uv.size()) {
-
- uvr = uv.read();
- read_uv = true;
- }
-
- if (normals.size()) {
- read_normals = true;
- nr = normals.read();
- }
-
- if (index.size()) {
-
- int facecount = index.size() / 3;
- PoolVector<int>::Read ir = index.read();
-
- for (int j = 0; j < facecount; j++) {
-
- Vector3 vtxs[3];
- Vector2 uvs[3];
- Vector3 normal[3];
-
- for (int k = 0; k < 3; k++) {
- vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]);
- }
-
- if (read_uv) {
- for (int k = 0; k < 3; k++) {
- uvs[k] = uvr[ir[j * 3 + k]];
- }
- }
-
- if (read_normals) {
- for (int k = 0; k < 3; k++) {
- normal[k] = nr[ir[j * 3 + k]];
- }
- }
-
- //test against original bounds
- if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs))
- continue;
- //plot
- _plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds);
- }
-
- } else {
-
- int facecount = vertices.size() / 3;
-
- for (int j = 0; j < facecount; j++) {
-
- Vector3 vtxs[3];
- Vector2 uvs[3];
- Vector3 normal[3];
-
- for (int k = 0; k < 3; k++) {
- vtxs[k] = p_xform.xform(vr[j * 3 + k]);
- }
-
- if (read_uv) {
- for (int k = 0; k < 3; k++) {
- uvs[k] = uvr[j * 3 + k];
- }
- }
-
- if (read_normals) {
- for (int k = 0; k < 3; k++) {
- normal[k] = nr[j * 3 + k];
- }
- }
-
- //test against original bounds
- if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs))
- continue;
- //plot face
- _plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds);
- }
- }
- }
-
- max_original_cells = bake_cells.size();
-}
-
-void VoxelLightBaker::_init_light_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, uint32_t p_parent) {
-
- bake_light.write[p_idx].x = p_x;
- bake_light.write[p_idx].y = p_y;
- bake_light.write[p_idx].z = p_z;
-
- if (p_level == cell_subdiv - 1) {
-
- bake_light.write[p_idx].next_leaf = first_leaf;
- first_leaf = p_idx;
- } else {
-
- //go down
- int half = (1 << (cell_subdiv - 1)) >> (p_level + 1);
- for (int i = 0; i < 8; i++) {
-
- uint32_t child = bake_cells[p_idx].children[i];
-
- if (child == CHILD_EMPTY)
- continue;
-
- int nx = p_x;
- int ny = p_y;
- int nz = p_z;
-
- if (i & 1)
- nx += half;
- if (i & 2)
- ny += half;
- if (i & 4)
- nz += half;
-
- _init_light_plot(child, p_level + 1, nx, ny, nz, p_idx);
- }
- }
-}
-
-void VoxelLightBaker::begin_bake_light(BakeQuality p_quality, BakeMode p_bake_mode, float p_propagation, float p_energy) {
- _check_init_light();
- propagation = p_propagation;
- bake_quality = p_quality;
- bake_mode = p_bake_mode;
- energy = p_energy;
-}
-
-void VoxelLightBaker::_check_init_light() {
- if (bake_light.size() == 0) {
-
- direct_lights_baked = false;
- leaf_voxel_count = 0;
- _fixup_plot(0, 0); //pre fixup, so normal, albedo, emission, etc. work for lighting.
- bake_light.resize(bake_cells.size());
- print_line("bake light size: " + itos(bake_light.size()));
- //zeromem(bake_light.ptrw(), bake_light.size() * sizeof(Light));
- first_leaf = -1;
- _init_light_plot(0, 0, 0, 0, 0, CHILD_EMPTY);
- }
-}
-
-static float _get_normal_advance(const Vector3 &p_normal) {
-
- Vector3 normal = p_normal;
- Vector3 unorm = normal.abs();
-
- if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) {
- // x code
- unorm = normal.x > 0.0 ? Vector3(1.0, 0.0, 0.0) : Vector3(-1.0, 0.0, 0.0);
- } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) {
- // y code
- unorm = normal.y > 0.0 ? Vector3(0.0, 1.0, 0.0) : Vector3(0.0, -1.0, 0.0);
- } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) {
- // z code
- unorm = normal.z > 0.0 ? Vector3(0.0, 0.0, 1.0) : Vector3(0.0, 0.0, -1.0);
- } else {
- // oh-no we messed up code
- // has to be
- unorm = Vector3(1.0, 0.0, 0.0);
- }
-
- return 1.0 / normal.dot(unorm);
-}
-
-static const Vector3 aniso_normal[6] = {
- Vector3(-1, 0, 0),
- Vector3(1, 0, 0),
- Vector3(0, -1, 0),
- Vector3(0, 1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, 1)
-};
-
-uint32_t VoxelLightBaker::_find_cell_at_pos(const Cell *cells, int x, int y, int z) {
-
- uint32_t cell = 0;
-
- int ofs_x = 0;
- int ofs_y = 0;
- int ofs_z = 0;
- int size = 1 << (cell_subdiv - 1);
- int half = size / 2;
-
- if (x < 0 || x >= size)
- return -1;
- if (y < 0 || y >= size)
- return -1;
- if (z < 0 || z >= size)
- return -1;
-
- for (int i = 0; i < cell_subdiv - 1; i++) {
-
- const Cell *bc = &cells[cell];
-
- int child = 0;
- if (x >= ofs_x + half) {
- child |= 1;
- ofs_x += half;
- }
- if (y >= ofs_y + half) {
- child |= 2;
- ofs_y += half;
- }
- if (z >= ofs_z + half) {
- child |= 4;
- ofs_z += half;
- }
-
- cell = bc->children[child];
- if (cell == CHILD_EMPTY)
- return CHILD_EMPTY;
-
- half >>= 1;
- }
-
- return cell;
-}
-void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_energy, bool p_direct) {
-
- _check_init_light();
-
- float max_len = Vector3(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]).length() * 1.1;
-
- if (p_direct)
- direct_lights_baked = true;
-
- Vector3 light_axis = p_direction;
- Plane clip[3];
- int clip_planes = 0;
-
- Light *light_data = bake_light.ptrw();
- const Cell *cells = bake_cells.ptr();
-
- for (int i = 0; i < 3; i++) {
-
- if (Math::is_zero_approx(light_axis[i]))
- continue;
- clip[clip_planes].normal[i] = 1.0;
-
- if (light_axis[i] < 0) {
-
- clip[clip_planes].d = axis_cell_size[i] + 1;
- } else {
- clip[clip_planes].d -= 1.0;
- }
-
- clip_planes++;
- }
-
- float distance_adv = _get_normal_advance(light_axis);
-
- int success_count = 0;
-
- Vector3 light_energy = Vector3(p_color.r, p_color.g, p_color.b) * p_energy * p_indirect_energy;
-
- int idx = first_leaf;
- while (idx >= 0) {
-
- Light *light = &light_data[idx];
-
- Vector3 to(light->x + 0.5, light->y + 0.5, light->z + 0.5);
- to += -light_axis.sign() * 0.47; //make it more likely to receive a ray
-
- Vector3 from = to - max_len * light_axis;
-
- for (int j = 0; j < clip_planes; j++) {
-
- clip[j].intersects_segment(from, to, &from);
- }
-
- float distance = (to - from).length();
- distance += distance_adv - Math::fmod(distance, distance_adv); //make it reach the center of the box always
- from = to - light_axis * distance;
-
- uint32_t result = 0xFFFFFFFF;
-
- while (distance > -distance_adv) { //use this to avoid precision errors
-
- result = _find_cell_at_pos(cells, int(floor(from.x)), int(floor(from.y)), int(floor(from.z)));
- if (result != 0xFFFFFFFF) {
- break;
- }
-
- from += light_axis * distance_adv;
- distance -= distance_adv;
- }
-
- if (result == (uint32_t)idx) {
- //cell hit itself! hooray!
-
- Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]);
- if (normal == Vector3()) {
- for (int i = 0; i < 6; i++) {
- light->accum[i][0] += light_energy.x * cells[idx].albedo[0];
- light->accum[i][1] += light_energy.y * cells[idx].albedo[1];
- light->accum[i][2] += light_energy.z * cells[idx].albedo[2];
- }
-
- } else {
-
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-normal));
- light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * s;
- light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * s;
- light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * s;
- }
- }
-
- if (p_direct) {
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
- light->direct_accum[i][0] += light_energy.x * s;
- light->direct_accum[i][1] += light_energy.y * s;
- light->direct_accum[i][2] += light_energy.z * s;
- }
- }
- success_count++;
- }
-
- idx = light_data[idx].next_leaf;
- }
-}
-
-void VoxelLightBaker::plot_light_omni(const Vector3 &p_pos, const Color &p_color, float p_energy, float p_indirect_energy, float p_radius, float p_attenutation, bool p_direct) {
-
- _check_init_light();
-
- if (p_direct)
- direct_lights_baked = true;
-
- Plane clip[3];
- int clip_planes = 0;
-
- // uint64_t us = OS::get_singleton()->get_ticks_usec();
-
- Vector3 light_pos = to_cell_space.xform(p_pos) + Vector3(0.5, 0.5, 0.5);
- //Vector3 spot_axis = -light_cache.transform.basis.get_axis(2).normalized();
-
- float local_radius = to_cell_space.basis.xform(Vector3(0, 0, 1)).length() * p_radius;
-
- Light *light_data = bake_light.ptrw();
- const Cell *cells = bake_cells.ptr();
- Vector3 light_energy = Vector3(p_color.r, p_color.g, p_color.b) * p_energy * p_indirect_energy;
-
- int idx = first_leaf;
- while (idx >= 0) {
-
- Light *light = &light_data[idx];
-
- Vector3 to(light->x + 0.5, light->y + 0.5, light->z + 0.5);
- to += (light_pos - to).sign() * 0.47; //make it more likely to receive a ray
-
- Vector3 light_axis = (to - light_pos).normalized();
- float distance_adv = _get_normal_advance(light_axis);
-
- Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]);
-
- if (normal != Vector3() && normal.dot(-light_axis) < 0.001) {
- idx = light_data[idx].next_leaf;
- continue;
- }
-
- float att = 1.0;
- {
- float d = light_pos.distance_to(to);
- if (d + distance_adv > local_radius) {
- idx = light_data[idx].next_leaf;
- continue; // too far away
- }
-
- float dt = CLAMP((d + distance_adv) / local_radius, 0, 1);
- att *= powf(1.0 - dt, p_attenutation);
- }
-
- clip_planes = 0;
-
- for (int c = 0; c < 3; c++) {
-
- if (Math::is_zero_approx(light_axis[c]))
- continue;
- clip[clip_planes].normal[c] = 1.0;
-
- if (light_axis[c] < 0) {
-
- clip[clip_planes].d = (1 << (cell_subdiv - 1)) + 1;
- } else {
- clip[clip_planes].d -= 1.0;
- }
-
- clip_planes++;
- }
-
- Vector3 from = light_pos;
-
- for (int j = 0; j < clip_planes; j++) {
-
- clip[j].intersects_segment(from, to, &from);
- }
-
- float distance = (to - from).length();
-
- distance -= Math::fmod(distance, distance_adv); //make it reach the center of the box always, but this tame make it closer
- from = to - light_axis * distance;
- to += (light_pos - to).sign() * 0.47; //make it more likely to receive a ray
-
- uint32_t result = 0xFFFFFFFF;
-
- while (distance > -distance_adv) { //use this to avoid precision errors
-
- result = _find_cell_at_pos(cells, int(floor(from.x)), int(floor(from.y)), int(floor(from.z)));
- if (result != 0xFFFFFFFF) {
- break;
- }
-
- from += light_axis * distance_adv;
- distance -= distance_adv;
- }
-
- if (result == (uint32_t)idx) {
- //cell hit itself! hooray!
-
- if (normal == Vector3()) {
- for (int i = 0; i < 6; i++) {
- light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * att;
- light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * att;
- light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * att;
- }
-
- } else {
-
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-normal));
- light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * s * att;
- light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * s * att;
- light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * s * att;
- }
- }
-
- if (p_direct) {
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
- light->direct_accum[i][0] += light_energy.x * s * att;
- light->direct_accum[i][1] += light_energy.y * s * att;
- light->direct_accum[i][2] += light_energy.z * s * att;
- }
- }
- }
-
- idx = light_data[idx].next_leaf;
- }
-}
-
-void VoxelLightBaker::plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axis, const Color &p_color, float p_energy, float p_indirect_energy, float p_radius, float p_attenutation, float p_spot_angle, float p_spot_attenuation, bool p_direct) {
-
- _check_init_light();
-
- if (p_direct)
- direct_lights_baked = true;
-
- Plane clip[3];
- int clip_planes = 0;
-
- // uint64_t us = OS::get_singleton()->get_ticks_usec();
-
- Vector3 light_pos = to_cell_space.xform(p_pos) + Vector3(0.5, 0.5, 0.5);
- Vector3 spot_axis = to_cell_space.basis.xform(p_axis).normalized();
-
- float local_radius = to_cell_space.basis.xform(Vector3(0, 0, 1)).length() * p_radius;
-
- Light *light_data = bake_light.ptrw();
- const Cell *cells = bake_cells.ptr();
- Vector3 light_energy = Vector3(p_color.r, p_color.g, p_color.b) * p_energy * p_indirect_energy;
-
- int idx = first_leaf;
- while (idx >= 0) {
-
- Light *light = &light_data[idx];
-
- Vector3 to(light->x + 0.5, light->y + 0.5, light->z + 0.5);
-
- Vector3 light_axis = (to - light_pos).normalized();
- float distance_adv = _get_normal_advance(light_axis);
-
- Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]);
-
- if (normal != Vector3() && normal.dot(-light_axis) < 0.001) {
- idx = light_data[idx].next_leaf;
- continue;
- }
-
- float angle = Math::rad2deg(Math::acos(light_axis.dot(-spot_axis)));
- if (angle > p_spot_angle) {
- idx = light_data[idx].next_leaf;
- continue; // too far away
- }
-
- float att = Math::pow(1.0f - angle / p_spot_angle, p_spot_attenuation);
-
- {
- float d = light_pos.distance_to(to);
- if (d + distance_adv > local_radius) {
- idx = light_data[idx].next_leaf;
- continue; // too far away
- }
-
- float dt = CLAMP((d + distance_adv) / local_radius, 0, 1);
- att *= powf(1.0 - dt, p_attenutation);
- }
-
- clip_planes = 0;
-
- for (int c = 0; c < 3; c++) {
-
- if (Math::is_zero_approx(light_axis[c]))
- continue;
- clip[clip_planes].normal[c] = 1.0;
-
- if (light_axis[c] < 0) {
-
- clip[clip_planes].d = (1 << (cell_subdiv - 1)) + 1;
- } else {
- clip[clip_planes].d -= 1.0;
- }
-
- clip_planes++;
- }
-
- Vector3 from = light_pos;
-
- for (int j = 0; j < clip_planes; j++) {
-
- clip[j].intersects_segment(from, to, &from);
- }
-
- float distance = (to - from).length();
-
- distance -= Math::fmod(distance, distance_adv); //make it reach the center of the box always, but this tame make it closer
- from = to - light_axis * distance;
-
- uint32_t result = 0xFFFFFFFF;
-
- while (distance > -distance_adv) { //use this to avoid precision errors
-
- result = _find_cell_at_pos(cells, int(floor(from.x)), int(floor(from.y)), int(floor(from.z)));
- if (result != 0xFFFFFFFF) {
- break;
- }
-
- from += light_axis * distance_adv;
- distance -= distance_adv;
- }
-
- if (result == (uint32_t)idx) {
- //cell hit itself! hooray!
-
- if (normal == Vector3()) {
- for (int i = 0; i < 6; i++) {
- light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * att;
- light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * att;
- light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * att;
- }
-
- } else {
-
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-normal));
- light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * s * att;
- light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * s * att;
- light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * s * att;
- }
- }
-
- if (p_direct) {
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
- light->direct_accum[i][0] += light_energy.x * s * att;
- light->direct_accum[i][1] += light_energy.y * s * att;
- light->direct_accum[i][2] += light_energy.z * s * att;
- }
- }
- }
-
- idx = light_data[idx].next_leaf;
- }
-}
-
-void VoxelLightBaker::_fixup_plot(int p_idx, int p_level) {
-
- if (p_level == cell_subdiv - 1) {
-
- leaf_voxel_count++;
- float alpha = bake_cells[p_idx].alpha;
-
- bake_cells.write[p_idx].albedo[0] /= alpha;
- bake_cells.write[p_idx].albedo[1] /= alpha;
- bake_cells.write[p_idx].albedo[2] /= alpha;
-
- //transfer emission to light
- bake_cells.write[p_idx].emission[0] /= alpha;
- bake_cells.write[p_idx].emission[1] /= alpha;
- bake_cells.write[p_idx].emission[2] /= alpha;
-
- bake_cells.write[p_idx].normal[0] /= alpha;
- bake_cells.write[p_idx].normal[1] /= alpha;
- bake_cells.write[p_idx].normal[2] /= alpha;
-
- Vector3 n(bake_cells[p_idx].normal[0], bake_cells[p_idx].normal[1], bake_cells[p_idx].normal[2]);
- if (n.length() < 0.01) {
- //too much fight over normal, zero it
- bake_cells.write[p_idx].normal[0] = 0;
- bake_cells.write[p_idx].normal[1] = 0;
- bake_cells.write[p_idx].normal[2] = 0;
- } else {
- n.normalize();
- bake_cells.write[p_idx].normal[0] = n.x;
- bake_cells.write[p_idx].normal[1] = n.y;
- bake_cells.write[p_idx].normal[2] = n.z;
- }
-
- bake_cells.write[p_idx].alpha = 1.0;
-
- /*if (bake_light.size()) {
- for(int i=0;i<6;i++) {
-
- }
- }*/
-
- } else {
-
- //go down
-
- bake_cells.write[p_idx].emission[0] = 0;
- bake_cells.write[p_idx].emission[1] = 0;
- bake_cells.write[p_idx].emission[2] = 0;
- bake_cells.write[p_idx].normal[0] = 0;
- bake_cells.write[p_idx].normal[1] = 0;
- bake_cells.write[p_idx].normal[2] = 0;
- bake_cells.write[p_idx].albedo[0] = 0;
- bake_cells.write[p_idx].albedo[1] = 0;
- bake_cells.write[p_idx].albedo[2] = 0;
- if (bake_light.size()) {
- for (int j = 0; j < 6; j++) {
- bake_light.write[p_idx].accum[j][0] = 0;
- bake_light.write[p_idx].accum[j][1] = 0;
- bake_light.write[p_idx].accum[j][2] = 0;
- }
- }
-
- float alpha_average = 0;
- int children_found = 0;
-
- for (int i = 0; i < 8; i++) {
-
- uint32_t child = bake_cells[p_idx].children[i];
-
- if (child == CHILD_EMPTY)
- continue;
-
- _fixup_plot(child, p_level + 1);
- alpha_average += bake_cells[child].alpha;
-
- if (bake_light.size() > 0) {
- for (int j = 0; j < 6; j++) {
- bake_light.write[p_idx].accum[j][0] += bake_light[child].accum[j][0];
- bake_light.write[p_idx].accum[j][1] += bake_light[child].accum[j][1];
- bake_light.write[p_idx].accum[j][2] += bake_light[child].accum[j][2];
- }
- bake_cells.write[p_idx].emission[0] += bake_cells[child].emission[0];
- bake_cells.write[p_idx].emission[1] += bake_cells[child].emission[1];
- bake_cells.write[p_idx].emission[2] += bake_cells[child].emission[2];
- }
-
- children_found++;
- }
-
- bake_cells.write[p_idx].alpha = alpha_average / 8.0;
- if (bake_light.size() && children_found) {
- float divisor = Math::lerp(8, children_found, propagation);
- for (int j = 0; j < 6; j++) {
- bake_light.write[p_idx].accum[j][0] /= divisor;
- bake_light.write[p_idx].accum[j][1] /= divisor;
- bake_light.write[p_idx].accum[j][2] /= divisor;
- }
- bake_cells.write[p_idx].emission[0] /= divisor;
- bake_cells.write[p_idx].emission[1] /= divisor;
- bake_cells.write[p_idx].emission[2] /= divisor;
- }
- }
-}
-
-//make sure any cell (save for the root) has an empty cell previous to it, so it can be interpolated into
-
-void VoxelLightBaker::_plot_triangle(Vector2 *vertices, Vector3 *positions, Vector3 *normals, LightMap *pixels, int width, int height) {
-
- int x[3];
- int y[3];
-
- for (int j = 0; j < 3; j++) {
-
- x[j] = vertices[j].x * width;
- y[j] = vertices[j].y * height;
- //x[j] = CLAMP(x[j], 0, bt.width - 1);
- //y[j] = CLAMP(y[j], 0, bt.height - 1);
- }
-
- // sort the points vertically
- if (y[1] > y[2]) {
- SWAP(x[1], x[2]);
- SWAP(y[1], y[2]);
- SWAP(positions[1], positions[2]);
- SWAP(normals[1], normals[2]);
- }
- if (y[0] > y[1]) {
- SWAP(x[0], x[1]);
- SWAP(y[0], y[1]);
- SWAP(positions[0], positions[1]);
- SWAP(normals[0], normals[1]);
- }
- if (y[1] > y[2]) {
- SWAP(x[1], x[2]);
- SWAP(y[1], y[2]);
- SWAP(positions[1], positions[2]);
- SWAP(normals[1], normals[2]);
- }
-
- double dx_far = double(x[2] - x[0]) / (y[2] - y[0] + 1);
- double dx_upper = double(x[1] - x[0]) / (y[1] - y[0] + 1);
- double dx_low = double(x[2] - x[1]) / (y[2] - y[1] + 1);
- double xf = x[0];
- double xt = x[0] + dx_upper; // if y[0] == y[1], special case
- for (int yi = y[0]; yi <= (y[2] > height - 1 ? height - 1 : y[2]); yi++) {
- if (yi >= 0) {
- for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) {
- //pixels[int(x + y * width)] = color;
-
- Vector2 v0 = Vector2(x[1] - x[0], y[1] - y[0]);
- Vector2 v1 = Vector2(x[2] - x[0], y[2] - y[0]);
- //vertices[2] - vertices[0];
- Vector2 v2 = Vector2(xi - x[0], yi - y[0]);
- float d00 = v0.dot(v0);
- float d01 = v0.dot(v1);
- float d11 = v1.dot(v1);
- float d20 = v2.dot(v0);
- float d21 = v2.dot(v1);
- float denom = (d00 * d11 - d01 * d01);
- Vector3 pos;
- Vector3 normal;
- if (denom == 0) {
- pos = positions[0];
- normal = normals[0];
- } else {
- float v = (d11 * d20 - d01 * d21) / denom;
- float w = (d00 * d21 - d01 * d20) / denom;
- float u = 1.0f - v - w;
- pos = positions[0] * u + positions[1] * v + positions[2] * w;
- normal = normals[0] * u + normals[1] * v + normals[2] * w;
- }
-
- int ofs = yi * width + xi;
- pixels[ofs].normal = normal;
- pixels[ofs].pos = pos;
- }
-
- for (int xi = (xf < width ? int(xf) : width - 1); xi >= (xt > 0 ? xt : 0); xi--) {
- //pixels[int(x + y * width)] = color;
- Vector2 v0 = Vector2(x[1] - x[0], y[1] - y[0]);
- Vector2 v1 = Vector2(x[2] - x[0], y[2] - y[0]);
- //vertices[2] - vertices[0];
- Vector2 v2 = Vector2(xi - x[0], yi - y[0]);
- float d00 = v0.dot(v0);
- float d01 = v0.dot(v1);
- float d11 = v1.dot(v1);
- float d20 = v2.dot(v0);
- float d21 = v2.dot(v1);
- float denom = (d00 * d11 - d01 * d01);
- Vector3 pos;
- Vector3 normal;
- if (denom == 0) {
- pos = positions[0];
- normal = normals[0];
- } else {
- float v = (d11 * d20 - d01 * d21) / denom;
- float w = (d00 * d21 - d01 * d20) / denom;
- float u = 1.0f - v - w;
- pos = positions[0] * u + positions[1] * v + positions[2] * w;
- normal = normals[0] * u + normals[1] * v + normals[2] * w;
- }
-
- int ofs = yi * width + xi;
- pixels[ofs].normal = normal;
- pixels[ofs].pos = pos;
- }
- }
- xf += dx_far;
- if (yi < y[1])
- xt += dx_upper;
- else
- xt += dx_low;
- }
-}
-
-void VoxelLightBaker::_sample_baked_octree_filtered_and_anisotropic(const Vector3 &p_posf, const Vector3 &p_direction, float p_level, Vector3 &r_color, float &r_alpha) {
-
- int size = 1 << (cell_subdiv - 1);
-
- int clamp_v = size - 1;
- //first of all, clamp
- Vector3 pos;
- pos.x = CLAMP(p_posf.x, 0, clamp_v);
- pos.y = CLAMP(p_posf.y, 0, clamp_v);
- pos.z = CLAMP(p_posf.z, 0, clamp_v);
-
- float level = (cell_subdiv - 1) - p_level;
-
- int target_level;
- float level_filter;
- if (level <= 0.0) {
- level_filter = 0;
- target_level = 0;
- } else {
- target_level = Math::ceil(level);
- level_filter = target_level - level;
- }
-
- const Cell *cells = bake_cells.ptr();
- const Light *light = bake_light.ptr();
-
- Vector3 color[2][8];
- float alpha[2][8];
- zeromem(alpha, sizeof(float) * 2 * 8);
-
- //find cell at given level first
-
- for (int c = 0; c < 2; c++) {
-
- int current_level = MAX(0, target_level - c);
- int level_cell_size = (1 << (cell_subdiv - 1)) >> current_level;
-
- for (int n = 0; n < 8; n++) {
-
- int x = int(pos.x);
- int y = int(pos.y);
- int z = int(pos.z);
-
- if (n & 1)
- x += level_cell_size;
- if (n & 2)
- y += level_cell_size;
- if (n & 4)
- z += level_cell_size;
-
- int ofs_x = 0;
- int ofs_y = 0;
- int ofs_z = 0;
-
- x = CLAMP(x, 0, clamp_v);
- y = CLAMP(y, 0, clamp_v);
- z = CLAMP(z, 0, clamp_v);
-
- int half = size / 2;
- uint32_t cell = 0;
- for (int i = 0; i < current_level; i++) {
-
- const Cell *bc = &cells[cell];
-
- int child = 0;
- if (x >= ofs_x + half) {
- child |= 1;
- ofs_x += half;
- }
- if (y >= ofs_y + half) {
- child |= 2;
- ofs_y += half;
- }
- if (z >= ofs_z + half) {
- child |= 4;
- ofs_z += half;
- }
-
- cell = bc->children[child];
- if (cell == CHILD_EMPTY)
- break;
-
- half >>= 1;
- }
-
- if (cell == CHILD_EMPTY) {
- alpha[c][n] = 0;
- } else {
- alpha[c][n] = cells[cell].alpha;
-
- for (int i = 0; i < 6; i++) {
- //anisotropic read light
- float amount = p_direction.dot(aniso_normal[i]);
- if (amount < 0)
- amount = 0;
- color[c][n].x += light[cell].accum[i][0] * amount;
- color[c][n].y += light[cell].accum[i][1] * amount;
- color[c][n].z += light[cell].accum[i][2] * amount;
- }
-
- color[c][n].x += cells[cell].emission[0];
- color[c][n].y += cells[cell].emission[1];
- color[c][n].z += cells[cell].emission[2];
- }
- }
- }
-
- float target_level_size = size >> target_level;
- Vector3 pos_fract[2];
-
- pos_fract[0].x = Math::fmod(pos.x, target_level_size) / target_level_size;
- pos_fract[0].y = Math::fmod(pos.y, target_level_size) / target_level_size;
- pos_fract[0].z = Math::fmod(pos.z, target_level_size) / target_level_size;
-
- target_level_size = size >> MAX(0, target_level - 1);
-
- pos_fract[1].x = Math::fmod(pos.x, target_level_size) / target_level_size;
- pos_fract[1].y = Math::fmod(pos.y, target_level_size) / target_level_size;
- pos_fract[1].z = Math::fmod(pos.z, target_level_size) / target_level_size;
-
- float alpha_interp[2];
- Vector3 color_interp[2];
-
- for (int i = 0; i < 2; i++) {
-
- Vector3 color_x00 = color[i][0].linear_interpolate(color[i][1], pos_fract[i].x);
- Vector3 color_xy0 = color[i][2].linear_interpolate(color[i][3], pos_fract[i].x);
- Vector3 blend_z0 = color_x00.linear_interpolate(color_xy0, pos_fract[i].y);
-
- Vector3 color_x0z = color[i][4].linear_interpolate(color[i][5], pos_fract[i].x);
- Vector3 color_xyz = color[i][6].linear_interpolate(color[i][7], pos_fract[i].x);
- Vector3 blend_z1 = color_x0z.linear_interpolate(color_xyz, pos_fract[i].y);
-
- color_interp[i] = blend_z0.linear_interpolate(blend_z1, pos_fract[i].z);
-
- float alpha_x00 = Math::lerp(alpha[i][0], alpha[i][1], pos_fract[i].x);
- float alpha_xy0 = Math::lerp(alpha[i][2], alpha[i][3], pos_fract[i].x);
- float alpha_z0 = Math::lerp(alpha_x00, alpha_xy0, pos_fract[i].y);
-
- float alpha_x0z = Math::lerp(alpha[i][4], alpha[i][5], pos_fract[i].x);
- float alpha_xyz = Math::lerp(alpha[i][6], alpha[i][7], pos_fract[i].x);
- float alpha_z1 = Math::lerp(alpha_x0z, alpha_xyz, pos_fract[i].y);
-
- alpha_interp[i] = Math::lerp(alpha_z0, alpha_z1, pos_fract[i].z);
- }
-
- r_color = color_interp[0].linear_interpolate(color_interp[1], level_filter);
- r_alpha = Math::lerp(alpha_interp[0], alpha_interp[1], level_filter);
-}
-
-Vector3 VoxelLightBaker::_voxel_cone_trace(const Vector3 &p_pos, const Vector3 &p_normal, float p_aperture) {
-
- float bias = 2.5;
- float max_distance = (Vector3(1, 1, 1) * (1 << (cell_subdiv - 1))).length();
-
- float dist = bias;
- float alpha = 0.0;
- Vector3 color;
-
- Vector3 scolor;
- float salpha;
-
- while (dist < max_distance && alpha < 0.95) {
- float diameter = MAX(1.0, 2.0 * p_aperture * dist);
- _sample_baked_octree_filtered_and_anisotropic(p_pos + dist * p_normal, p_normal, log2(diameter), scolor, salpha);
- float a = (1.0 - alpha);
- color += scolor * a;
- alpha += a * salpha;
- dist += diameter * 0.5;
- }
-
- /*if (blend_ambient) {
- color.rgb = mix(ambient,color.rgb,min(1.0,alpha/0.95));
- }*/
-
- return color;
-}
-
-Vector3 VoxelLightBaker::_compute_pixel_light_at_pos(const Vector3 &p_pos, const Vector3 &p_normal) {
-
- //find arbitrary tangent and bitangent, then build a matrix
- Vector3 v0 = Math::abs(p_normal.z) < 0.999 ? Vector3(0, 0, 1) : Vector3(0, 1, 0);
- Vector3 tangent = v0.cross(p_normal).normalized();
- Vector3 bitangent = tangent.cross(p_normal).normalized();
- Basis normal_xform = Basis(tangent, bitangent, p_normal).transposed();
-
- const Vector3 *cone_dirs = NULL;
- const float *cone_weights = NULL;
- int cone_dir_count = 0;
- float cone_aperture = 0;
-
- switch (bake_quality) {
- case BAKE_QUALITY_LOW: {
- //default quality
- static const Vector3 dirs[4] = {
- Vector3(Math_SQRT12, 0, Math_SQRT12),
- Vector3(0, Math_SQRT12, Math_SQRT12),
- Vector3(-Math_SQRT12, 0, Math_SQRT12),
- Vector3(0, -Math_SQRT12, Math_SQRT12)
- };
-
- static const float weights[4] = { 0.25, 0.25, 0.25, 0.25 };
-
- cone_dirs = dirs;
- cone_dir_count = 4;
- cone_aperture = 1.0; // tan(angle) 90 degrees
- cone_weights = weights;
- } break;
- case BAKE_QUALITY_MEDIUM: {
- //default quality
- static const Vector3 dirs[6] = {
- Vector3(0, 0, 1),
- Vector3(0.866025, 0, 0.5),
- Vector3(0.267617, 0.823639, 0.5),
- Vector3(-0.700629, 0.509037, 0.5),
- Vector3(-0.700629, -0.509037, 0.5),
- Vector3(0.267617, -0.823639, 0.5)
- };
- static const float weights[6] = { 0.25f, 0.15f, 0.15f, 0.15f, 0.15f, 0.15f };
- //
- cone_dirs = dirs;
- cone_dir_count = 6;
- cone_aperture = 0.577; // tan(angle) 60 degrees
- cone_weights = weights;
- } break;
- case BAKE_QUALITY_HIGH: {
-
- //high qualily
- static const Vector3 dirs[10] = {
- Vector3(0.8781648411741658, 0.0, 0.478358141694643),
- Vector3(0.5369754325592234, 0.6794204427701518, 0.5000452447267606),
- Vector3(-0.19849436573466497, 0.8429904390140635, 0.49996710542041645),
- Vector3(-0.7856196499811189, 0.3639120321329737, 0.5003696617825604),
- Vector3(-0.7856196499811189, -0.3639120321329737, 0.5003696617825604),
- Vector3(-0.19849436573466497, -0.8429904390140635, 0.49996710542041645),
- Vector3(0.5369754325592234, -0.6794204427701518, 0.5000452447267606),
- Vector3(-0.4451656858129485, 0.0, 0.8954482185892644),
- Vector3(0.19124006749743122, 0.39355745585016605, 0.8991883926788214),
- Vector3(0.19124006749743122, -0.39355745585016605, 0.8991883926788214),
- };
- static const float weights[10] = { 0.08571f, 0.08571f, 0.08571f, 0.08571f, 0.08571f, 0.08571f, 0.08571f, 0.133333f, 0.133333f, 0.13333f };
- cone_dirs = dirs;
- cone_dir_count = 10;
- cone_aperture = 0.404; // tan(angle) 45 degrees
- cone_weights = weights;
- } break;
- }
-
- Vector3 accum;
-
- for (int i = 0; i < cone_dir_count; i++) {
- Vector3 dir = normal_xform.xform(cone_dirs[i]).normalized(); //normal may not completely correct when transformed to cell
- accum += _voxel_cone_trace(p_pos, dir, cone_aperture) * cone_weights[i];
- }
-
- return accum;
-}
-
-_ALWAYS_INLINE_ uint32_t xorshift32(uint32_t *state) {
- /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
- uint32_t x = *state;
- x ^= x << 13;
- x ^= x >> 17;
- x ^= x << 5;
- *state = x;
- return x;
-}
-
-Vector3 VoxelLightBaker::_compute_ray_trace_at_pos(const Vector3 &p_pos, const Vector3 &p_normal) {
-
- int samples_per_quality[3] = { 48, 128, 512 };
-
- int samples = samples_per_quality[bake_quality];
-
- //create a basis in Z
- Vector3 v0 = Math::abs(p_normal.z) < 0.999 ? Vector3(0, 0, 1) : Vector3(0, 1, 0);
- Vector3 tangent = v0.cross(p_normal).normalized();
- Vector3 bitangent = tangent.cross(p_normal).normalized();
- Basis normal_xform = Basis(tangent, bitangent, p_normal).transposed();
-
- float bias = 1.5;
- int max_level = cell_subdiv - 1;
- int size = 1 << max_level;
-
- Vector3 accum;
- float spread = Math::deg2rad(80.0);
-
- const Light *light = bake_light.ptr();
- const Cell *cells = bake_cells.ptr();
-
- uint32_t local_rng_state = rand(); //needs to be fixed again
-
- for (int i = 0; i < samples; i++) {
-
- float random_angle1 = (((xorshift32(&local_rng_state) % 65535) / 65535.0) * 2.0 - 1.0) * spread;
- Vector3 axis(0, sin(random_angle1), cos(random_angle1));
- float random_angle2 = ((xorshift32(&local_rng_state) % 65535) / 65535.0) * Math_PI * 2.0;
- Basis rot(Vector3(0, 0, 1), random_angle2);
- axis = rot.xform(axis);
-
- Vector3 direction = normal_xform.xform(axis).normalized();
-
- Vector3 advance = direction * _get_normal_advance(direction);
-
- Vector3 pos = p_pos /*+ Vector3(0.5, 0.5, 0.5)*/ + advance * bias;
-
- uint32_t cell = CHILD_EMPTY;
-
- while (cell == CHILD_EMPTY) {
-
- int x = int(pos.x);
- int y = int(pos.y);
- int z = int(pos.z);
-
- int ofs_x = 0;
- int ofs_y = 0;
- int ofs_z = 0;
- int half = size / 2;
-
- if (x < 0 || x >= size)
- break;
- if (y < 0 || y >= size)
- break;
- if (z < 0 || z >= size)
- break;
-
- //int level_limit = max_level;
-
- cell = 0; //start from root
- for (int j = 0; j < max_level; j++) {
-
- const Cell *bc = &cells[cell];
-
- int child = 0;
- if (x >= ofs_x + half) {
- child |= 1;
- ofs_x += half;
- }
- if (y >= ofs_y + half) {
- child |= 2;
- ofs_y += half;
- }
- if (z >= ofs_z + half) {
- child |= 4;
- ofs_z += half;
- }
-
- cell = bc->children[child];
- if (unlikely(cell == CHILD_EMPTY))
- break;
-
- half >>= 1;
- }
-
- pos += advance;
- }
-
- if (unlikely(cell != CHILD_EMPTY)) {
- for (int j = 0; j < 6; j++) {
- //anisotropic read light
- float amount = direction.dot(aniso_normal[j]);
- if (amount <= 0)
- continue;
- accum.x += light[cell].accum[j][0] * amount;
- accum.y += light[cell].accum[j][1] * amount;
- accum.z += light[cell].accum[j][2] * amount;
- }
- accum.x += cells[cell].emission[0];
- accum.y += cells[cell].emission[1];
- accum.z += cells[cell].emission[2];
- }
- }
-
- // Make sure we don't reset this thread's RNG state
-
- return accum / samples;
-}
-
-void VoxelLightBaker::_lightmap_bake_point(uint32_t p_x, LightMap *p_line) {
-
- LightMap *pixel = &p_line[p_x];
- if (pixel->pos == Vector3())
- return;
- switch (bake_mode) {
- case BAKE_MODE_CONE_TRACE: {
- pixel->light = _compute_pixel_light_at_pos(pixel->pos, pixel->normal) * energy;
- } break;
- case BAKE_MODE_RAY_TRACE: {
- pixel->light = _compute_ray_trace_at_pos(pixel->pos, pixel->normal) * energy;
- } break;
- }
-}
-
-Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, float default_texels_per_unit, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float), void *p_bake_time_ud) {
-
- //transfer light information to a lightmap
- Ref<Mesh> mesh = p_mesh;
-
- //step 1 - create lightmap
- int width;
- int height;
- Vector<LightMap> lightmap;
- Transform xform = to_cell_space * p_xform;
- if (mesh->get_lightmap_size_hint() == Size2()) {
- double area = 0;
- double uv_area = 0;
- for (int i = 0; i < mesh->get_surface_count(); i++) {
- Array arrays = mesh->surface_get_arrays(i);
- PoolVector<Vector3> vertices = arrays[Mesh::ARRAY_VERTEX];
- PoolVector<Vector2> uv2 = arrays[Mesh::ARRAY_TEX_UV2];
- PoolVector<int> indices = arrays[Mesh::ARRAY_INDEX];
-
- ERR_FAIL_COND_V(vertices.size() == 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(uv2.size() == 0, ERR_INVALID_PARAMETER);
-
- int vc = vertices.size();
- PoolVector<Vector3>::Read vr = vertices.read();
- PoolVector<Vector2>::Read u2r = uv2.read();
- PoolVector<int>::Read ir;
- int ic = 0;
-
- if (indices.size()) {
- ic = indices.size();
- ir = indices.read();
- }
-
- int faces = ic ? ic / 3 : vc / 3;
- for (int j = 0; j < faces; j++) {
- Vector3 vertex[3];
- Vector2 uv[3];
-
- for (int k = 0; k < 3; k++) {
- int idx = ic ? ir[j * 3 + k] : j * 3 + k;
- vertex[k] = xform.xform(vr[idx]);
- uv[k] = u2r[idx];
- }
-
- Vector3 p1 = vertex[0];
- Vector3 p2 = vertex[1];
- Vector3 p3 = vertex[2];
- double a = p1.distance_to(p2);
- double b = p2.distance_to(p3);
- double c = p3.distance_to(p1);
- double halfPerimeter = (a + b + c) / 2.0;
- area += sqrt(halfPerimeter * (halfPerimeter - a) * (halfPerimeter - b) * (halfPerimeter - c));
-
- Vector2 uv_p1 = uv[0];
- Vector2 uv_p2 = uv[1];
- Vector2 uv_p3 = uv[2];
- double uv_a = uv_p1.distance_to(uv_p2);
- double uv_b = uv_p2.distance_to(uv_p3);
- double uv_c = uv_p3.distance_to(uv_p1);
- double uv_halfPerimeter = (uv_a + uv_b + uv_c) / 2.0;
- uv_area += sqrt(uv_halfPerimeter * (uv_halfPerimeter - uv_a) * (uv_halfPerimeter - uv_b) * (uv_halfPerimeter - uv_c));
- }
- }
-
- if (uv_area < 0.0001f) {
- uv_area = 1.0;
- }
-
- int pixels = (ceil((1.0 / sqrt(uv_area)) * sqrt(area * default_texels_per_unit)));
- width = height = CLAMP(pixels, 2, 4096);
- } else {
- width = mesh->get_lightmap_size_hint().x;
- height = mesh->get_lightmap_size_hint().y;
- }
-
- lightmap.resize(width * height);
-
- //step 2 plot faces to lightmap
- for (int i = 0; i < mesh->get_surface_count(); i++) {
- Array arrays = mesh->surface_get_arrays(i);
- PoolVector<Vector3> vertices = arrays[Mesh::ARRAY_VERTEX];
- PoolVector<Vector3> normals = arrays[Mesh::ARRAY_NORMAL];
- PoolVector<Vector2> uv2 = arrays[Mesh::ARRAY_TEX_UV2];
- PoolVector<int> indices = arrays[Mesh::ARRAY_INDEX];
-
- ERR_FAIL_COND_V(vertices.size() == 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(normals.size() == 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(uv2.size() == 0, ERR_INVALID_PARAMETER);
-
- int vc = vertices.size();
- PoolVector<Vector3>::Read vr = vertices.read();
- PoolVector<Vector3>::Read nr = normals.read();
- PoolVector<Vector2>::Read u2r = uv2.read();
- PoolVector<int>::Read ir;
- int ic = 0;
-
- if (indices.size()) {
- ic = indices.size();
- ir = indices.read();
- }
-
- int faces = ic ? ic / 3 : vc / 3;
- for (int j = 0; j < faces; j++) {
- Vector3 vertex[3];
- Vector3 normal[3];
- Vector2 uv[3];
-
- for (int k = 0; k < 3; k++) {
- int idx = ic ? ir[j * 3 + k] : j * 3 + k;
- vertex[k] = xform.xform(vr[idx]);
- normal[k] = xform.basis.xform(nr[idx]).normalized();
- uv[k] = u2r[idx];
- }
-
- _plot_triangle(uv, vertex, normal, lightmap.ptrw(), width, height);
- }
- }
-
- //step 3 perform voxel cone trace on lightmap pixels
- {
- LightMap *lightmap_ptr = lightmap.ptrw();
- uint64_t begin_time = OS::get_singleton()->get_ticks_usec();
- volatile int lines = 0;
-
- // make sure our OS-level rng is seeded
-
- for (int i = 0; i < height; i++) {
-
- thread_process_array(width, this, &VoxelLightBaker::_lightmap_bake_point, &lightmap_ptr[i * width]);
-
- lines = MAX(lines, i); //for multithread
- if (p_bake_time_func) {
- uint64_t elapsed = OS::get_singleton()->get_ticks_usec() - begin_time;
- float elapsed_sec = double(elapsed) / 1000000.0;
- float remaining = lines < 1 ? 0 : (elapsed_sec / lines) * (height - lines - 1);
- if (p_bake_time_func(p_bake_time_ud, remaining, lines / float(height))) {
- return ERR_SKIP;
- }
- }
- }
-
- if (bake_mode == BAKE_MODE_RAY_TRACE) {
- //blur
- //gauss kernel, 7 step sigma 2
- static const float gauss_kernel[4] = { 0.214607f, 0.189879f, 0.131514f, 0.071303f };
- //horizontal pass
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- if (lightmap_ptr[i * width + j].normal == Vector3()) {
- continue; //empty
- }
- float gauss_sum = gauss_kernel[0];
- Vector3 accum = lightmap_ptr[i * width + j].light * gauss_kernel[0];
- for (int k = 1; k < 4; k++) {
- int new_x = j + k;
- if (new_x >= width || lightmap_ptr[i * width + new_x].normal == Vector3())
- break;
- gauss_sum += gauss_kernel[k];
- accum += lightmap_ptr[i * width + new_x].light * gauss_kernel[k];
- }
- for (int k = 1; k < 4; k++) {
- int new_x = j - k;
- if (new_x < 0 || lightmap_ptr[i * width + new_x].normal == Vector3())
- break;
- gauss_sum += gauss_kernel[k];
- accum += lightmap_ptr[i * width + new_x].light * gauss_kernel[k];
- }
-
- lightmap_ptr[i * width + j].pos = accum /= gauss_sum;
- }
- }
- //vertical pass
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- if (lightmap_ptr[i * width + j].normal == Vector3())
- continue; //empty, don't write over it anyway
- float gauss_sum = gauss_kernel[0];
- Vector3 accum = lightmap_ptr[i * width + j].pos * gauss_kernel[0];
- for (int k = 1; k < 4; k++) {
- int new_y = i + k;
- if (new_y >= height || lightmap_ptr[new_y * width + j].normal == Vector3())
- break;
- gauss_sum += gauss_kernel[k];
- accum += lightmap_ptr[new_y * width + j].pos * gauss_kernel[k];
- }
- for (int k = 1; k < 4; k++) {
- int new_y = i - k;
- if (new_y < 0 || lightmap_ptr[new_y * width + j].normal == Vector3())
- break;
- gauss_sum += gauss_kernel[k];
- accum += lightmap_ptr[new_y * width + j].pos * gauss_kernel[k];
- }
-
- lightmap_ptr[i * width + j].light = accum /= gauss_sum;
- }
- }
- }
-
- //add directional light (do this after blur)
- {
- const Cell *cells = bake_cells.ptr();
- const Light *light = bake_light.ptr();
-#ifdef _OPENMP
-#pragma omp parallel
-#endif
- for (int i = 0; i < height; i++) {
-#ifdef _OPENMP
-#pragma omp parallel for schedule(dynamic, 1)
-#endif
- for (int j = 0; j < width; j++) {
-
- //if (i == 125 && j == 280) {
-
- LightMap *pixel = &lightmap_ptr[i * width + j];
- if (pixel->pos == Vector3())
- continue; //unused, skipe
-
- int x = int(pixel->pos.x) - 1;
- int y = int(pixel->pos.y) - 1;
- int z = int(pixel->pos.z) - 1;
- Color accum;
- int size = 1 << (cell_subdiv - 1);
-
- int found = 0;
-
- for (int k = 0; k < 8; k++) {
-
- int ofs_x = x;
- int ofs_y = y;
- int ofs_z = z;
-
- if (k & 1)
- ofs_x++;
- if (k & 2)
- ofs_y++;
- if (k & 4)
- ofs_z++;
-
- if (x < 0 || x >= size)
- continue;
- if (y < 0 || y >= size)
- continue;
- if (z < 0 || z >= size)
- continue;
-
- uint32_t cell = _find_cell_at_pos(cells, ofs_x, ofs_y, ofs_z);
-
- if (cell == CHILD_EMPTY)
- continue;
- for (int l = 0; l < 6; l++) {
- float s = pixel->normal.dot(aniso_normal[l]);
- if (s < 0)
- s = 0;
- accum.r += light[cell].direct_accum[l][0] * s;
- accum.g += light[cell].direct_accum[l][1] * s;
- accum.b += light[cell].direct_accum[l][2] * s;
- }
- found++;
- }
- if (found) {
- accum /= found;
- pixel->light.x += accum.r;
- pixel->light.y += accum.g;
- pixel->light.z += accum.b;
- }
- }
- }
- }
-
- {
- //fill gaps with neighbour vertices to avoid filter fades to black on edges
-
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- if (lightmap_ptr[i * width + j].normal != Vector3()) {
- continue; //filled, skip
- }
-
- //this can't be made separatable..
-
- int closest_i = -1, closest_j = 1;
- float closest_dist = 1e20;
-
- const int margin = 3;
- for (int y = i - margin; y <= i + margin; y++) {
- for (int x = j - margin; x <= j + margin; x++) {
-
- if (x == j && y == i)
- continue;
- if (x < 0 || x >= width)
- continue;
- if (y < 0 || y >= height)
- continue;
- if (lightmap_ptr[y * width + x].normal == Vector3())
- continue; //also ensures that blitted stuff is not reused
-
- float dist = Vector2(i - y, j - x).length();
- if (dist > closest_dist)
- continue;
-
- closest_dist = dist;
- closest_i = y;
- closest_j = x;
- }
- }
-
- if (closest_i != -1) {
- lightmap_ptr[i * width + j].light = lightmap_ptr[closest_i * width + closest_j].light;
- }
- }
- }
- }
-
- {
- //fill the lightmap data
- r_lightmap.width = width;
- r_lightmap.height = height;
- r_lightmap.light.resize(lightmap.size() * 3);
- PoolVector<float>::Write w = r_lightmap.light.write();
- for (int i = 0; i < lightmap.size(); i++) {
- w[i * 3 + 0] = lightmap[i].light.x;
- w[i * 3 + 1] = lightmap[i].light.y;
- w[i * 3 + 2] = lightmap[i].light.z;
- }
- }
-
-#if 0 // Enable for debugging.
- {
- PoolVector<uint8_t> img;
- int ls = lightmap.size();
- img.resize(ls * 3);
- {
- PoolVector<uint8_t>::Write w = img.write();
- for (int i = 0; i < ls; i++) {
- w[i * 3 + 0] = CLAMP(lightmap_ptr[i].light.x * 255, 0, 255);
- w[i * 3 + 1] = CLAMP(lightmap_ptr[i].light.y * 255, 0, 255);
- w[i * 3 + 2] = CLAMP(lightmap_ptr[i].light.z * 255, 0, 255);
- //w[i * 3 + 0] = CLAMP(lightmap_ptr[i].normal.x * 255, 0, 255);
- //w[i * 3 + 1] = CLAMP(lightmap_ptr[i].normal.y * 255, 0, 255);
- //w[i * 3 + 2] = CLAMP(lightmap_ptr[i].normal.z * 255, 0, 255);
- //w[i * 3 + 0] = CLAMP(lightmap_ptr[i].pos.x / (1 << (cell_subdiv - 1)) * 255, 0, 255);
- //w[i * 3 + 1] = CLAMP(lightmap_ptr[i].pos.y / (1 << (cell_subdiv - 1)) * 255, 0, 255);
- //w[i * 3 + 2] = CLAMP(lightmap_ptr[i].pos.z / (1 << (cell_subdiv - 1)) * 255, 0, 255);
- }
- }
-
- Ref<Image> image;
- image.instance();
- image->create(width, height, false, Image::FORMAT_RGB8, img);
-
- String name = p_mesh->get_name();
- if (name == "") {
- name = "Mesh" + itos(p_mesh->get_instance_id());
- }
- image->save_png(name + ".png");
- }
-#endif
- }
-
- return OK;
-}
-
-void VoxelLightBaker::begin_bake(int p_subdiv, const AABB &p_bounds) {
-
- original_bounds = p_bounds;
- cell_subdiv = p_subdiv;
- bake_cells.resize(1);
- material_cache.clear();
-
- //find out the actual real bounds, power of 2, which gets the highest subdivision
- po2_bounds = p_bounds;
- int longest_axis = po2_bounds.get_longest_axis_index();
- axis_cell_size[longest_axis] = (1 << (cell_subdiv - 1));
- leaf_voxel_count = 0;
-
- for (int i = 0; i < 3; i++) {
-
- if (i == longest_axis)
- continue;
-
- axis_cell_size[i] = axis_cell_size[longest_axis];
- float axis_size = po2_bounds.size[longest_axis];
-
- //shrink until fit subdiv
- while (axis_size / 2.0 >= po2_bounds.size[i]) {
- axis_size /= 2.0;
- axis_cell_size[i] >>= 1;
- }
-
- po2_bounds.size[i] = po2_bounds.size[longest_axis];
- }
-
- Transform to_bounds;
- to_bounds.basis.scale(Vector3(po2_bounds.size[longest_axis], po2_bounds.size[longest_axis], po2_bounds.size[longest_axis]));
- to_bounds.origin = po2_bounds.position;
-
- Transform to_grid;
- to_grid.basis.scale(Vector3(axis_cell_size[longest_axis], axis_cell_size[longest_axis], axis_cell_size[longest_axis]));
-
- to_cell_space = to_grid * to_bounds.affine_inverse();
-
- cell_size = po2_bounds.size[longest_axis] / axis_cell_size[longest_axis];
-}
-
-void VoxelLightBaker::end_bake() {
- _fixup_plot(0, 0);
-}
-
-//create the data for visual server
-
-PoolVector<int> VoxelLightBaker::create_gi_probe_data() {
-
- PoolVector<int> data;
-
- data.resize(16 + (8 + 1 + 1 + 1 + 1) * bake_cells.size()); //4 for header, rest for rest.
-
- {
- PoolVector<int>::Write w = data.write();
-
- uint32_t *w32 = (uint32_t *)w.ptr();
-
- w32[0] = 0; //version
- w32[1] = cell_subdiv; //subdiv
- w32[2] = axis_cell_size[0];
- w32[3] = axis_cell_size[1];
- w32[4] = axis_cell_size[2];
- w32[5] = bake_cells.size();
- w32[6] = leaf_voxel_count;
-
- int ofs = 16;
-
- for (int i = 0; i < bake_cells.size(); i++) {
-
- for (int j = 0; j < 8; j++) {
- w32[ofs++] = bake_cells[i].children[j];
- }
-
- { //albedo
- uint32_t rgba = uint32_t(CLAMP(bake_cells[i].albedo[0] * 255.0, 0, 255)) << 16;
- rgba |= uint32_t(CLAMP(bake_cells[i].albedo[1] * 255.0, 0, 255)) << 8;
- rgba |= uint32_t(CLAMP(bake_cells[i].albedo[2] * 255.0, 0, 255)) << 0;
-
- w32[ofs++] = rgba;
- }
- { //emission
-
- Vector3 e(bake_cells[i].emission[0], bake_cells[i].emission[1], bake_cells[i].emission[2]);
- float l = e.length();
- if (l > 0) {
- e.normalize();
- l = CLAMP(l / 8.0, 0, 1.0);
- }
-
- uint32_t em = uint32_t(CLAMP(e[0] * 255, 0, 255)) << 24;
- em |= uint32_t(CLAMP(e[1] * 255, 0, 255)) << 16;
- em |= uint32_t(CLAMP(e[2] * 255, 0, 255)) << 8;
- em |= uint32_t(CLAMP(l * 255, 0, 255));
-
- w32[ofs++] = em;
- }
-
- //w32[ofs++]=bake_cells[i].used_sides;
- { //normal
-
- Vector3 n(bake_cells[i].normal[0], bake_cells[i].normal[1], bake_cells[i].normal[2]);
- n = n * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
- uint32_t norm = 0;
-
- norm |= uint32_t(CLAMP(n.x * 255.0, 0, 255)) << 16;
- norm |= uint32_t(CLAMP(n.y * 255.0, 0, 255)) << 8;
- norm |= uint32_t(CLAMP(n.z * 255.0, 0, 255)) << 0;
-
- w32[ofs++] = norm;
- }
-
- {
- uint16_t alpha = MIN(uint32_t(bake_cells[i].alpha * 65535.0), 65535);
- uint16_t level = bake_cells[i].level;
-
- w32[ofs++] = (uint32_t(level) << 16) | uint32_t(alpha);
- }
- }
- }
-
- return data;
-}
-
-void VoxelLightBaker::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, DebugMode p_mode) {
-
- if (p_level == cell_subdiv - 1) {
-
- Vector3 center = p_aabb.position + p_aabb.size * 0.5;
- Transform xform;
- xform.origin = center;
- xform.basis.scale(p_aabb.size * 0.5);
- p_multimesh->set_instance_transform(idx, xform);
- Color col;
- if (p_mode == DEBUG_ALBEDO) {
- col = Color(bake_cells[p_idx].albedo[0], bake_cells[p_idx].albedo[1], bake_cells[p_idx].albedo[2]);
- } else if (p_mode == DEBUG_LIGHT) {
- for (int i = 0; i < 6; i++) {
- col.r += bake_light[p_idx].accum[i][0];
- col.g += bake_light[p_idx].accum[i][1];
- col.b += bake_light[p_idx].accum[i][2];
- col.r += bake_light[p_idx].direct_accum[i][0];
- col.g += bake_light[p_idx].direct_accum[i][1];
- col.b += bake_light[p_idx].direct_accum[i][2];
- }
- }
- //Color col = Color(bake_cells[p_idx].emission[0], bake_cells[p_idx].emission[1], bake_cells[p_idx].emission[2]);
- p_multimesh->set_instance_color(idx, col);
-
- idx++;
-
- } else {
-
- for (int i = 0; i < 8; i++) {
-
- uint32_t child = bake_cells[p_idx].children[i];
-
- if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells)
- continue;
-
- AABB aabb = p_aabb;
- aabb.size *= 0.5;
-
- if (i & 1)
- aabb.position.x += aabb.size.x;
- if (i & 2)
- aabb.position.y += aabb.size.y;
- if (i & 4)
- aabb.position.z += aabb.size.z;
-
- _debug_mesh(bake_cells[p_idx].children[i], p_level + 1, aabb, p_multimesh, idx, p_mode);
- }
- }
-}
-
-Ref<MultiMesh> VoxelLightBaker::create_debug_multimesh(DebugMode p_mode) {
-
- Ref<MultiMesh> mm;
-
- ERR_FAIL_COND_V(p_mode == DEBUG_LIGHT && bake_light.size() == 0, mm);
- mm.instance();
-
- mm->set_transform_format(MultiMesh::TRANSFORM_3D);
- mm->set_color_format(MultiMesh::COLOR_8BIT);
- mm->set_instance_count(leaf_voxel_count);
-
- Ref<ArrayMesh> mesh;
- mesh.instance();
-
- {
- Array arr;
- arr.resize(Mesh::ARRAY_MAX);
-
- PoolVector<Vector3> vertices;
- PoolVector<Color> colors;
-#define ADD_VTX(m_idx) \
- ; \
- vertices.push_back(face_points[m_idx]); \
- colors.push_back(Color(1, 1, 1, 1));
-
- for (int i = 0; i < 6; i++) {
-
- Vector3 face_points[4];
-
- for (int j = 0; j < 4; j++) {
-
- float v[3];
- v[0] = 1.0;
- v[1] = 1 - 2 * ((j >> 1) & 1);
- v[2] = v[1] * (1 - 2 * (j & 1));
-
- for (int k = 0; k < 3; k++) {
-
- if (i < 3)
- face_points[j][(i + k) % 3] = v[k];
- else
- face_points[3 - j][(i + k) % 3] = -v[k];
- }
- }
-
- //tri 1
- ADD_VTX(0);
- ADD_VTX(1);
- ADD_VTX(2);
- //tri 2
- ADD_VTX(2);
- ADD_VTX(3);
- ADD_VTX(0);
- }
-
- arr[Mesh::ARRAY_VERTEX] = vertices;
- arr[Mesh::ARRAY_COLOR] = colors;
- mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr);
- }
-
- {
- Ref<SpatialMaterial> fsm;
- fsm.instance();
- 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);
- }
-
- mm->set_mesh(mesh);
-
- int idx = 0;
- _debug_mesh(0, 0, po2_bounds, mm, idx, p_mode);
-
- return mm;
-}
-
-struct VoxelLightBakerOctree {
-
- enum {
- CHILD_EMPTY = 0xFFFFFFFF
- };
-
- uint16_t light[6][3]; //anisotropic light
- float alpha;
- uint32_t children[8];
-};
-
-PoolVector<uint8_t> VoxelLightBaker::create_capture_octree(int p_subdiv) {
-
- p_subdiv = MIN(p_subdiv, cell_subdiv); // use the smaller one
-
- Vector<uint32_t> remap;
- int bc = bake_cells.size();
- remap.resize(bc);
- Vector<uint32_t> demap;
-
- int new_size = 0;
- for (int i = 0; i < bc; i++) {
- uint32_t c = CHILD_EMPTY;
- if (bake_cells[i].level < p_subdiv) {
- c = new_size;
- new_size++;
- demap.push_back(i);
- }
- remap.write[i] = c;
- }
-
- Vector<VoxelLightBakerOctree> octree;
- octree.resize(new_size);
-
- for (int i = 0; i < new_size; i++) {
- octree.write[i].alpha = bake_cells[demap[i]].alpha;
- for (int j = 0; j < 6; j++) {
- for (int k = 0; k < 3; k++) {
- float l = bake_light[demap[i]].accum[j][k]; //add anisotropic light
- l += bake_cells[demap[i]].emission[k]; //add emission
- octree.write[i].light[j][k] = CLAMP(l * 1024, 0, 65535); //give two more bits to octree
- }
- }
-
- for (int j = 0; j < 8; j++) {
- uint32_t child = bake_cells[demap[i]].children[j];
- octree.write[i].children[j] = child == CHILD_EMPTY ? CHILD_EMPTY : remap[child];
- }
- }
-
- PoolVector<uint8_t> ret;
- int ret_bytes = octree.size() * sizeof(VoxelLightBakerOctree);
- ret.resize(ret_bytes);
- {
- PoolVector<uint8_t>::Write w = ret.write();
- copymem(w.ptr(), octree.ptr(), ret_bytes);
- }
-
- return ret;
-}
-
-float VoxelLightBaker::get_cell_size() const {
- return cell_size;
-}
-
-Transform VoxelLightBaker::get_to_cell_space_xform() const {
- return to_cell_space;
-}
-VoxelLightBaker::VoxelLightBaker() {
- color_scan_cell_width = 4;
- bake_texture_size = 128;
- propagation = 0.85;
- energy = 1.0;
-}
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
new file mode 100644
index 0000000000..7cf26ab974
--- /dev/null
+++ b/scene/3d/voxelizer.cpp
@@ -0,0 +1,1224 @@
+/*************************************************************************/
+/* voxelizer.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "voxelizer.h"
+#include "core/os/os.h"
+#include "core/os/threaded_array_processor.h"
+
+#include <stdlib.h>
+
+#define FINDMINMAX(x0, x1, x2, min, max) \
+ min = max = x0; \
+ if (x1 < min) min = x1; \
+ if (x1 > max) max = x1; \
+ if (x2 < min) min = x2; \
+ if (x2 > max) max = x2;
+
+static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
+ int q;
+ Vector3 vmin, vmax;
+ for (q = 0; q <= 2; q++) {
+ if (normal[q] > 0.0f) {
+ vmin[q] = -maxbox[q];
+ vmax[q] = maxbox[q];
+ } else {
+ vmin[q] = maxbox[q];
+ vmax[q] = -maxbox[q];
+ }
+ }
+ if (normal.dot(vmin) + d > 0.0f) return false;
+ if (normal.dot(vmax) + d >= 0.0f) return true;
+
+ return false;
+}
+
+/*======================== X-tests ========================*/
+#define AXISTEST_X01(a, b, fa, fb) \
+ p0 = a * v0.y - b * v0.z; \
+ p2 = a * v2.y - b * v2.z; \
+ if (p0 < p2) { \
+ min = p0; \
+ max = p2; \
+ } else { \
+ min = p2; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) return false;
+
+#define AXISTEST_X2(a, b, fa, fb) \
+ p0 = a * v0.y - b * v0.z; \
+ p1 = a * v1.y - b * v1.z; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) return false;
+
+/*======================== Y-tests ========================*/
+#define AXISTEST_Y02(a, b, fa, fb) \
+ p0 = -a * v0.x + b * v0.z; \
+ p2 = -a * v2.x + b * v2.z; \
+ if (p0 < p2) { \
+ min = p0; \
+ max = p2; \
+ } else { \
+ min = p2; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) return false;
+
+#define AXISTEST_Y1(a, b, fa, fb) \
+ p0 = -a * v0.x + b * v0.z; \
+ p1 = -a * v1.x + b * v1.z; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) return false;
+
+/*======================== Z-tests ========================*/
+
+#define AXISTEST_Z12(a, b, fa, fb) \
+ p1 = a * v1.x - b * v1.y; \
+ p2 = a * v2.x - b * v2.y; \
+ if (p2 < p1) { \
+ min = p2; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p2; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
+ if (min > rad || max < -rad) return false;
+
+#define AXISTEST_Z0(a, b, fa, fb) \
+ p0 = a * v0.x - b * v0.y; \
+ p1 = a * v1.x - b * v1.y; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
+ if (min > rad || max < -rad) return false;
+
+static bool fast_tri_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) {
+
+ /* use separating axis theorem to test overlap between triangle and box */
+ /* need to test for overlap in these directions: */
+ /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
+ /* we do not even need to test these) */
+ /* 2) normal of the triangle */
+ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */
+ /* this gives 3x3=9 more tests */
+ Vector3 v0, v1, v2;
+ float min, max, d, p0, p1, p2, rad, fex, fey, fez;
+ Vector3 normal, e0, e1, e2;
+
+ /* This is the fastest branch on Sun */
+ /* move everything so that the boxcenter is in (0,0,0) */
+
+ v0 = triverts[0] - boxcenter;
+ v1 = triverts[1] - boxcenter;
+ v2 = triverts[2] - boxcenter;
+
+ /* compute triangle edges */
+ e0 = v1 - v0; /* tri edge 0 */
+ e1 = v2 - v1; /* tri edge 1 */
+ e2 = v0 - v2; /* tri edge 2 */
+
+ /* Bullet 3: */
+ /* test the 9 tests first (this was faster) */
+ fex = Math::abs(e0.x);
+ fey = Math::abs(e0.y);
+ fez = Math::abs(e0.z);
+ AXISTEST_X01(e0.z, e0.y, fez, fey);
+ AXISTEST_Y02(e0.z, e0.x, fez, fex);
+ AXISTEST_Z12(e0.y, e0.x, fey, fex);
+
+ fex = Math::abs(e1.x);
+ fey = Math::abs(e1.y);
+ fez = Math::abs(e1.z);
+ AXISTEST_X01(e1.z, e1.y, fez, fey);
+ AXISTEST_Y02(e1.z, e1.x, fez, fex);
+ AXISTEST_Z0(e1.y, e1.x, fey, fex);
+
+ fex = Math::abs(e2.x);
+ fey = Math::abs(e2.y);
+ fez = Math::abs(e2.z);
+ AXISTEST_X2(e2.z, e2.y, fez, fey);
+ AXISTEST_Y1(e2.z, e2.x, fez, fex);
+ AXISTEST_Z12(e2.y, e2.x, fey, fex);
+
+ /* Bullet 1: */
+ /* first test overlap in the {x,y,z}-directions */
+ /* find min, max of the triangle each direction, and test for overlap in */
+ /* that direction -- this is equivalent to testing a minimal AABB around */
+ /* the triangle against the AABB */
+
+ /* test in X-direction */
+ FINDMINMAX(v0.x, v1.x, v2.x, min, max);
+ if (min > boxhalfsize.x || max < -boxhalfsize.x) return false;
+
+ /* test in Y-direction */
+ FINDMINMAX(v0.y, v1.y, v2.y, min, max);
+ if (min > boxhalfsize.y || max < -boxhalfsize.y) return false;
+
+ /* test in Z-direction */
+ FINDMINMAX(v0.z, v1.z, v2.z, min, max);
+ if (min > boxhalfsize.z || max < -boxhalfsize.z) return false;
+
+ /* Bullet 2: */
+ /* test if the box intersects the plane of the triangle */
+ /* compute plane equation of triangle: normal*x+d=0 */
+ normal = e0.cross(e1);
+ d = -normal.dot(v0); /* plane eq: normal.x+d=0 */
+ return planeBoxOverlap(normal, d, boxhalfsize); /* if true, box and triangle overlaps */
+}
+
+static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3 *p_vtx, const Vector2 *p_uv, const Vector3 *p_normal, Vector2 &r_uv, Vector3 &r_normal) {
+
+ if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2) {
+ r_uv = p_uv[0];
+ r_normal = p_normal[0];
+ return;
+ }
+ if (p_pos.distance_squared_to(p_vtx[1]) < CMP_EPSILON2) {
+ r_uv = p_uv[1];
+ r_normal = p_normal[1];
+ return;
+ }
+ if (p_pos.distance_squared_to(p_vtx[2]) < CMP_EPSILON2) {
+ r_uv = p_uv[2];
+ r_normal = p_normal[2];
+ return;
+ }
+
+ Vector3 v0 = p_vtx[1] - p_vtx[0];
+ Vector3 v1 = p_vtx[2] - p_vtx[0];
+ Vector3 v2 = p_pos - p_vtx[0];
+
+ float d00 = v0.dot(v0);
+ float d01 = v0.dot(v1);
+ float d11 = v1.dot(v1);
+ float d20 = v2.dot(v0);
+ float d21 = v2.dot(v1);
+ float denom = (d00 * d11 - d01 * d01);
+ if (denom == 0) {
+ r_uv = p_uv[0];
+ r_normal = p_normal[0];
+ return;
+ }
+ float v = (d11 * d20 - d01 * d21) / denom;
+ float w = (d00 * d21 - d01 * d20) / denom;
+ float u = 1.0f - v - w;
+
+ r_uv = p_uv[0] * u + p_uv[1] * v + p_uv[2] * w;
+ r_normal = (p_normal[0] * u + p_normal[1] * v + p_normal[2] * w).normalized();
+}
+
+void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb) {
+
+ if (p_level == cell_subdiv) {
+ //plot the face by guessing its albedo and emission value
+
+ //find best axis to map to, for scanning values
+ int closest_axis = 0;
+ float closest_dot = 0;
+
+ Plane plane = Plane(p_vtx[0], p_vtx[1], p_vtx[2]);
+ Vector3 normal = plane.normal;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 axis;
+ axis[i] = 1.0;
+ float dot = ABS(normal.dot(axis));
+ if (i == 0 || dot > closest_dot) {
+ closest_axis = i;
+ closest_dot = dot;
+ }
+ }
+
+ Vector3 axis;
+ axis[closest_axis] = 1.0;
+ Vector3 t1;
+ t1[(closest_axis + 1) % 3] = 1.0;
+ Vector3 t2;
+ t2[(closest_axis + 2) % 3] = 1.0;
+
+ t1 *= p_aabb.size[(closest_axis + 1) % 3] / float(color_scan_cell_width);
+ t2 *= p_aabb.size[(closest_axis + 2) % 3] / float(color_scan_cell_width);
+
+ Color albedo_accum;
+ Color emission_accum;
+ Vector3 normal_accum;
+
+ float alpha = 0.0;
+
+ //map to a grid average in the best axis for this face
+ for (int i = 0; i < color_scan_cell_width; i++) {
+
+ Vector3 ofs_i = float(i) * t1;
+
+ for (int j = 0; j < color_scan_cell_width; j++) {
+
+ Vector3 ofs_j = float(j) * t2;
+
+ Vector3 from = p_aabb.position + ofs_i + ofs_j;
+ Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis];
+ Vector3 half = (to - from) * 0.5;
+
+ //is in this cell?
+ if (!fast_tri_box_overlap(from + half, half, p_vtx)) {
+ continue; //face does not span this cell
+ }
+
+ //go from -size to +size*2 to avoid skipping collisions
+ Vector3 ray_from = from + (t1 + t2) * 0.5 - axis * p_aabb.size[closest_axis];
+ Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis] * 2;
+
+ if (normal.dot(ray_from - ray_to) < 0) {
+ SWAP(ray_from, ray_to);
+ }
+
+ Vector3 intersection;
+
+ if (!plane.intersects_segment(ray_from, ray_to, &intersection)) {
+ if (ABS(plane.distance_to(ray_from)) < ABS(plane.distance_to(ray_to))) {
+ intersection = plane.project(ray_from);
+ } else {
+
+ intersection = plane.project(ray_to);
+ }
+ }
+
+ intersection = Face3(p_vtx[0], p_vtx[1], p_vtx[2]).get_closest_point_to(intersection);
+
+ Vector2 uv;
+ Vector3 lnormal;
+ get_uv_and_normal(intersection, p_vtx, p_uv, p_normal, uv, lnormal);
+ if (lnormal == Vector3()) //just in case normal as nor provided
+ lnormal = normal;
+
+ int uv_x = CLAMP(int(Math::fposmod(uv.x, 1.0f) * bake_texture_size), 0, bake_texture_size - 1);
+ int uv_y = CLAMP(int(Math::fposmod(uv.y, 1.0f) * bake_texture_size), 0, bake_texture_size - 1);
+
+ int ofs = uv_y * bake_texture_size + uv_x;
+ albedo_accum.r += p_material.albedo[ofs].r;
+ albedo_accum.g += p_material.albedo[ofs].g;
+ albedo_accum.b += p_material.albedo[ofs].b;
+ albedo_accum.a += p_material.albedo[ofs].a;
+
+ emission_accum.r += p_material.emission[ofs].r;
+ emission_accum.g += p_material.emission[ofs].g;
+ emission_accum.b += p_material.emission[ofs].b;
+
+ normal_accum += lnormal;
+
+ alpha += 1.0;
+ }
+ }
+
+ if (alpha == 0) {
+ //could not in any way get texture information.. so use closest point to center
+
+ Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]);
+ Vector3 inters = f.get_closest_point_to(p_aabb.position + p_aabb.size * 0.5);
+
+ Vector3 lnormal;
+ Vector2 uv;
+ get_uv_and_normal(inters, p_vtx, p_uv, p_normal, uv, normal);
+ if (lnormal == Vector3()) //just in case normal as nor provided
+ lnormal = normal;
+
+ int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
+ int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
+
+ int ofs = uv_y * bake_texture_size + uv_x;
+
+ alpha = 1.0 / (color_scan_cell_width * color_scan_cell_width);
+
+ albedo_accum.r = p_material.albedo[ofs].r * alpha;
+ albedo_accum.g = p_material.albedo[ofs].g * alpha;
+ albedo_accum.b = p_material.albedo[ofs].b * alpha;
+ albedo_accum.a = p_material.albedo[ofs].a * alpha;
+
+ emission_accum.r = p_material.emission[ofs].r * alpha;
+ emission_accum.g = p_material.emission[ofs].g * alpha;
+ emission_accum.b = p_material.emission[ofs].b * alpha;
+
+ normal_accum = lnormal * alpha;
+
+ } else {
+
+ float accdiv = 1.0 / (color_scan_cell_width * color_scan_cell_width);
+ alpha *= accdiv;
+
+ albedo_accum.r *= accdiv;
+ albedo_accum.g *= accdiv;
+ albedo_accum.b *= accdiv;
+ albedo_accum.a *= accdiv;
+
+ emission_accum.r *= accdiv;
+ emission_accum.g *= accdiv;
+ emission_accum.b *= accdiv;
+
+ normal_accum *= accdiv;
+ }
+
+ //put this temporarily here, corrected in a later step
+ bake_cells.write[p_idx].albedo[0] += albedo_accum.r;
+ bake_cells.write[p_idx].albedo[1] += albedo_accum.g;
+ bake_cells.write[p_idx].albedo[2] += albedo_accum.b;
+ bake_cells.write[p_idx].emission[0] += emission_accum.r;
+ bake_cells.write[p_idx].emission[1] += emission_accum.g;
+ bake_cells.write[p_idx].emission[2] += emission_accum.b;
+ bake_cells.write[p_idx].normal[0] += normal_accum.x;
+ bake_cells.write[p_idx].normal[1] += normal_accum.y;
+ bake_cells.write[p_idx].normal[2] += normal_accum.z;
+ bake_cells.write[p_idx].alpha += alpha;
+
+ } else {
+ //go down
+
+ int half = (1 << cell_subdiv) >> (p_level + 1);
+ for (int i = 0; i < 8; i++) {
+
+ AABB aabb = p_aabb;
+ aabb.size *= 0.5;
+
+ int nx = p_x;
+ int ny = p_y;
+ int nz = p_z;
+
+ if (i & 1) {
+ aabb.position.x += aabb.size.x;
+ nx += half;
+ }
+ if (i & 2) {
+ aabb.position.y += aabb.size.y;
+ ny += half;
+ }
+ if (i & 4) {
+ aabb.position.z += aabb.size.z;
+ nz += half;
+ }
+ //make sure to not plot beyond limits
+ if (nx < 0 || nx >= axis_cell_size[0] || ny < 0 || ny >= axis_cell_size[1] || nz < 0 || nz >= axis_cell_size[2])
+ continue;
+
+ {
+ AABB test_aabb = aabb;
+ //test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
+ Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test
+
+ if (!fast_tri_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) {
+ //if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
+ //does not fit in child, go on
+ continue;
+ }
+ }
+
+ if (bake_cells[p_idx].children[i] == CHILD_EMPTY) {
+ //sub cell must be created
+
+ uint32_t child_idx = bake_cells.size();
+ bake_cells.write[p_idx].children[i] = child_idx;
+ bake_cells.resize(bake_cells.size() + 1);
+ bake_cells.write[child_idx].level = p_level + 1;
+ bake_cells.write[child_idx].x = nx / half;
+ bake_cells.write[child_idx].y = ny / half;
+ bake_cells.write[child_idx].z = nz / half;
+ }
+
+ _plot_face(bake_cells[p_idx].children[i], p_level + 1, nx, ny, nz, p_vtx, p_normal, p_uv, p_material, aabb);
+ }
+ }
+}
+
+Vector<Color> Voxelizer::_get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add) {
+
+ Vector<Color> ret;
+
+ if (p_image.is_null() || p_image->empty()) {
+
+ ret.resize(bake_texture_size * bake_texture_size);
+ for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
+ ret.write[i] = p_color_add;
+ }
+
+ return ret;
+ }
+ p_image = p_image->duplicate();
+
+ if (p_image->is_compressed()) {
+ p_image->decompress();
+ }
+ p_image->convert(Image::FORMAT_RGBA8);
+ p_image->resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC);
+
+ PoolVector<uint8_t>::Read r = p_image->get_data().read();
+ ret.resize(bake_texture_size * bake_texture_size);
+
+ for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
+ Color c;
+ c.r = (r[i * 4 + 0] / 255.0) * p_color_mul.r + p_color_add.r;
+ c.g = (r[i * 4 + 1] / 255.0) * p_color_mul.g + p_color_add.g;
+ c.b = (r[i * 4 + 2] / 255.0) * p_color_mul.b + p_color_add.b;
+
+ c.a = r[i * 4 + 3] / 255.0;
+
+ ret.write[i] = c;
+ }
+
+ return ret;
+}
+
+Voxelizer::MaterialCache Voxelizer::_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<StandardMaterial3D> mat = p_material;
+
+ Ref<Material> material = mat; //hack for now
+
+ if (material_cache.has(material)) {
+ return material_cache[material];
+ }
+
+ MaterialCache mc;
+
+ if (mat.is_valid()) {
+
+ Ref<Texture2D> albedo_tex = mat->get_texture(StandardMaterial3D::TEXTURE_ALBEDO);
+
+ Ref<Image> img_albedo;
+ if (albedo_tex.is_valid()) {
+
+ img_albedo = albedo_tex->get_data();
+ mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), Color(0, 0, 0)); // albedo texture, color is multiplicative
+ } else {
+ mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive
+ }
+
+ Ref<Texture2D> emission_tex = mat->get_texture(StandardMaterial3D::TEXTURE_EMISSION);
+
+ Color emission_col = mat->get_emission();
+ float emission_energy = mat->get_emission_energy();
+
+ Ref<Image> img_emission;
+
+ if (emission_tex.is_valid()) {
+
+ img_emission = emission_tex->get_data();
+ }
+
+ if (mat->get_emission_operator() == StandardMaterial3D::EMISSION_OP_ADD) {
+ mc.emission = _get_bake_texture(img_emission, Color(1, 1, 1) * emission_energy, emission_col * emission_energy);
+ } else {
+ mc.emission = _get_bake_texture(img_emission, emission_col * emission_energy, Color(0, 0, 0));
+ }
+
+ } else {
+ Ref<Image> empty;
+
+ mc.albedo = _get_bake_texture(empty, Color(0, 0, 0), Color(1, 1, 1));
+ mc.emission = _get_bake_texture(empty, Color(0, 0, 0), Color(0, 0, 0));
+ }
+
+ material_cache[p_material] = mc;
+ return mc;
+}
+
+void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) {
+
+ for (int i = 0; i < p_mesh->get_surface_count(); i++) {
+
+ if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
+ continue; //only triangles
+
+ Ref<Material> src_material;
+
+ if (p_override_material.is_valid()) {
+ src_material = p_override_material;
+ } else if (i < p_materials.size() && p_materials[i].is_valid()) {
+ src_material = p_materials[i];
+ } else {
+ src_material = p_mesh->surface_get_material(i);
+ }
+ MaterialCache material = _get_material_cache(src_material);
+
+ Array a = p_mesh->surface_get_arrays(i);
+
+ PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
+ PoolVector<Vector3>::Read vr = vertices.read();
+ PoolVector<Vector2> uv = a[Mesh::ARRAY_TEX_UV];
+ PoolVector<Vector2>::Read uvr;
+ PoolVector<Vector3> normals = a[Mesh::ARRAY_NORMAL];
+ PoolVector<Vector3>::Read nr;
+ PoolVector<int> index = a[Mesh::ARRAY_INDEX];
+
+ bool read_uv = false;
+ bool read_normals = false;
+
+ if (uv.size()) {
+
+ uvr = uv.read();
+ read_uv = true;
+ }
+
+ if (normals.size()) {
+ read_normals = true;
+ nr = normals.read();
+ }
+
+ if (index.size()) {
+
+ int facecount = index.size() / 3;
+ PoolVector<int>::Read ir = index.read();
+
+ for (int j = 0; j < facecount; j++) {
+
+ Vector3 vtxs[3];
+ Vector2 uvs[3];
+ Vector3 normal[3];
+
+ for (int k = 0; k < 3; k++) {
+ vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]);
+ }
+
+ if (read_uv) {
+ for (int k = 0; k < 3; k++) {
+ uvs[k] = uvr[ir[j * 3 + k]];
+ }
+ }
+
+ if (read_normals) {
+ for (int k = 0; k < 3; k++) {
+ normal[k] = nr[ir[j * 3 + k]];
+ }
+ }
+
+ //test against original bounds
+ if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs))
+ continue;
+ //plot
+ _plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds);
+ }
+
+ } else {
+
+ int facecount = vertices.size() / 3;
+
+ for (int j = 0; j < facecount; j++) {
+
+ Vector3 vtxs[3];
+ Vector2 uvs[3];
+ Vector3 normal[3];
+
+ for (int k = 0; k < 3; k++) {
+ vtxs[k] = p_xform.xform(vr[j * 3 + k]);
+ }
+
+ if (read_uv) {
+ for (int k = 0; k < 3; k++) {
+ uvs[k] = uvr[j * 3 + k];
+ }
+ }
+
+ if (read_normals) {
+ for (int k = 0; k < 3; k++) {
+ normal[k] = nr[j * 3 + k];
+ }
+ }
+
+ //test against original bounds
+ if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs))
+ continue;
+ //plot face
+ _plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds);
+ }
+ }
+ }
+
+ max_original_cells = bake_cells.size();
+}
+
+void Voxelizer::_sort() {
+
+ // cells need to be sorted by level and coordinates
+ // it is important that level has more priority (for compute), and that Z has the least,
+ // given it may aid older implementations plot using GPU
+
+ Vector<CellSort> sorted_cells;
+ uint32_t cell_count = bake_cells.size();
+ sorted_cells.resize(cell_count);
+ {
+
+ CellSort *sort_cellsp = sorted_cells.ptrw();
+ const Cell *bake_cellsp = bake_cells.ptr();
+
+ for (uint32_t i = 0; i < cell_count; i++) {
+ sort_cellsp[i].x = bake_cellsp[i].x;
+ sort_cellsp[i].y = bake_cellsp[i].y;
+ sort_cellsp[i].z = bake_cellsp[i].z;
+ sort_cellsp[i].level = bake_cellsp[i].level;
+ sort_cellsp[i].index = i;
+ }
+ }
+
+ sorted_cells.sort();
+
+ //verify just in case, index 0 must be level 0
+ ERR_FAIL_COND(sorted_cells[0].level != 0);
+
+ Vector<Cell> new_bake_cells;
+ new_bake_cells.resize(cell_count);
+ Vector<uint32_t> reverse_map;
+
+ {
+ reverse_map.resize(cell_count);
+ const CellSort *sort_cellsp = sorted_cells.ptr();
+ uint32_t *reverse_mapp = reverse_map.ptrw();
+
+ for (uint32_t i = 0; i < cell_count; i++) {
+ reverse_mapp[sort_cellsp[i].index] = i;
+ }
+ }
+
+ {
+
+ const CellSort *sort_cellsp = sorted_cells.ptr();
+ const Cell *bake_cellsp = bake_cells.ptr();
+ const uint32_t *reverse_mapp = reverse_map.ptr();
+ Cell *new_bake_cellsp = new_bake_cells.ptrw();
+
+ for (uint32_t i = 0; i < cell_count; i++) {
+ //copy to new cell
+ new_bake_cellsp[i] = bake_cellsp[sort_cellsp[i].index];
+ //remap children
+ for (uint32_t j = 0; j < 8; j++) {
+ if (new_bake_cellsp[i].children[j] != CHILD_EMPTY) {
+ new_bake_cellsp[i].children[j] = reverse_mapp[new_bake_cellsp[i].children[j]];
+ }
+ }
+ }
+ }
+
+ bake_cells = new_bake_cells;
+ sorted = true;
+}
+
+void Voxelizer::_fixup_plot(int p_idx, int p_level) {
+
+ if (p_level == cell_subdiv) {
+
+ leaf_voxel_count++;
+ float alpha = bake_cells[p_idx].alpha;
+
+ bake_cells.write[p_idx].albedo[0] /= alpha;
+ bake_cells.write[p_idx].albedo[1] /= alpha;
+ bake_cells.write[p_idx].albedo[2] /= alpha;
+
+ //transfer emission to light
+ bake_cells.write[p_idx].emission[0] /= alpha;
+ bake_cells.write[p_idx].emission[1] /= alpha;
+ bake_cells.write[p_idx].emission[2] /= alpha;
+
+ bake_cells.write[p_idx].normal[0] /= alpha;
+ bake_cells.write[p_idx].normal[1] /= alpha;
+ bake_cells.write[p_idx].normal[2] /= alpha;
+
+ Vector3 n(bake_cells[p_idx].normal[0], bake_cells[p_idx].normal[1], bake_cells[p_idx].normal[2]);
+ if (n.length() < 0.01) {
+ //too much fight over normal, zero it
+ bake_cells.write[p_idx].normal[0] = 0;
+ bake_cells.write[p_idx].normal[1] = 0;
+ bake_cells.write[p_idx].normal[2] = 0;
+ } else {
+ n.normalize();
+ bake_cells.write[p_idx].normal[0] = n.x;
+ bake_cells.write[p_idx].normal[1] = n.y;
+ bake_cells.write[p_idx].normal[2] = n.z;
+ }
+
+ bake_cells.write[p_idx].alpha = 1.0;
+
+ /*if (bake_light.size()) {
+ for(int i=0;i<6;i++) {
+
+ }
+ }*/
+
+ } else {
+
+ //go down
+
+ bake_cells.write[p_idx].emission[0] = 0;
+ bake_cells.write[p_idx].emission[1] = 0;
+ bake_cells.write[p_idx].emission[2] = 0;
+ bake_cells.write[p_idx].normal[0] = 0;
+ bake_cells.write[p_idx].normal[1] = 0;
+ bake_cells.write[p_idx].normal[2] = 0;
+ bake_cells.write[p_idx].albedo[0] = 0;
+ bake_cells.write[p_idx].albedo[1] = 0;
+ bake_cells.write[p_idx].albedo[2] = 0;
+
+ float alpha_average = 0;
+ int children_found = 0;
+
+ for (int i = 0; i < 8; i++) {
+
+ uint32_t child = bake_cells[p_idx].children[i];
+
+ if (child == CHILD_EMPTY)
+ continue;
+
+ _fixup_plot(child, p_level + 1);
+ alpha_average += bake_cells[child].alpha;
+
+ children_found++;
+ }
+
+ bake_cells.write[p_idx].alpha = alpha_average / 8.0;
+ }
+}
+
+void Voxelizer::begin_bake(int p_subdiv, const AABB &p_bounds) {
+
+ sorted = false;
+ original_bounds = p_bounds;
+ cell_subdiv = p_subdiv;
+ bake_cells.resize(1);
+ material_cache.clear();
+
+ print_line("subdiv: " + itos(p_subdiv));
+ //find out the actual real bounds, power of 2, which gets the highest subdivision
+ po2_bounds = p_bounds;
+ int longest_axis = po2_bounds.get_longest_axis_index();
+ axis_cell_size[longest_axis] = 1 << cell_subdiv;
+ leaf_voxel_count = 0;
+
+ for (int i = 0; i < 3; i++) {
+
+ if (i == longest_axis)
+ continue;
+
+ axis_cell_size[i] = axis_cell_size[longest_axis];
+ float axis_size = po2_bounds.size[longest_axis];
+
+ //shrink until fit subdiv
+ while (axis_size / 2.0 >= po2_bounds.size[i]) {
+ axis_size /= 2.0;
+ axis_cell_size[i] >>= 1;
+ }
+
+ po2_bounds.size[i] = po2_bounds.size[longest_axis];
+ }
+
+ Transform to_bounds;
+ to_bounds.basis.scale(Vector3(po2_bounds.size[longest_axis], po2_bounds.size[longest_axis], po2_bounds.size[longest_axis]));
+ to_bounds.origin = po2_bounds.position;
+
+ Transform to_grid;
+ to_grid.basis.scale(Vector3(axis_cell_size[longest_axis], axis_cell_size[longest_axis], axis_cell_size[longest_axis]));
+
+ to_cell_space = to_grid * to_bounds.affine_inverse();
+
+ cell_size = po2_bounds.size[longest_axis] / axis_cell_size[longest_axis];
+}
+
+void Voxelizer::end_bake() {
+ if (!sorted) {
+ _sort();
+ }
+ _fixup_plot(0, 0);
+}
+
+//create the data for visual server
+
+int Voxelizer::get_gi_probe_octree_depth() const {
+ return cell_subdiv;
+}
+Vector3i Voxelizer::get_giprobe_octree_size() const {
+ return Vector3i(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]);
+}
+int Voxelizer::get_giprobe_cell_count() const {
+ return bake_cells.size();
+}
+
+PoolVector<uint8_t> Voxelizer::get_giprobe_octree_cells() const {
+ PoolVector<uint8_t> data;
+ data.resize((8 * 4) * bake_cells.size()); //8 uint32t values
+ {
+ PoolVector<uint8_t>::Write w = data.write();
+ uint32_t *children_cells = (uint32_t *)w.ptr();
+ const Cell *cells = bake_cells.ptr();
+
+ uint32_t cell_count = bake_cells.size();
+
+ for (uint32_t i = 0; i < cell_count; i++) {
+
+ for (uint32_t j = 0; j < 8; j++) {
+ children_cells[i * 8 + j] = cells[i].children[j];
+ }
+ }
+ }
+
+ return data;
+}
+PoolVector<uint8_t> Voxelizer::get_giprobe_data_cells() const {
+ PoolVector<uint8_t> data;
+ data.resize((4 * 4) * bake_cells.size()); //8 uint32t values
+ {
+ PoolVector<uint8_t>::Write w = data.write();
+ uint32_t *dataptr = (uint32_t *)w.ptr();
+ const Cell *cells = bake_cells.ptr();
+
+ uint32_t cell_count = bake_cells.size();
+
+ for (uint32_t i = 0; i < cell_count; i++) {
+
+ { //position
+
+ uint32_t x = cells[i].x;
+ uint32_t y = cells[i].y;
+ uint32_t z = cells[i].z;
+
+ uint32_t position = x;
+ position |= y << 11;
+ position |= z << 21;
+
+ dataptr[i * 4 + 0] = position;
+ }
+
+ { //albedo + alpha
+ uint32_t rgba = uint32_t(CLAMP(cells[i].alpha * 255.0, 0, 255)) << 24; //a
+ rgba |= uint32_t(CLAMP(cells[i].albedo[2] * 255.0, 0, 255)) << 16; //b
+ rgba |= uint32_t(CLAMP(cells[i].albedo[1] * 255.0, 0, 255)) << 8; //g
+ rgba |= uint32_t(CLAMP(cells[i].albedo[0] * 255.0, 0, 255)); //r
+
+ dataptr[i * 4 + 1] = rgba;
+ }
+
+ { //emission, as rgbe9995
+ Color emission = Color(cells[i].emission[0], cells[i].emission[1], cells[i].emission[2]);
+ dataptr[i * 4 + 2] = emission.to_rgbe9995();
+ }
+
+ { //normal
+
+ Vector3 n(bake_cells[i].normal[0], bake_cells[i].normal[1], bake_cells[i].normal[2]);
+ n.normalize();
+
+ uint32_t normal = uint32_t(uint8_t(int8_t(CLAMP(n.x * 127.0, -128, 127))));
+ normal |= uint32_t(uint8_t(int8_t(CLAMP(n.y * 127.0, -128, 127)))) << 8;
+ normal |= uint32_t(uint8_t(int8_t(CLAMP(n.z * 127.0, -128, 127)))) << 16;
+
+ dataptr[i * 4 + 3] = normal;
+ }
+ }
+ }
+
+ return data;
+}
+
+PoolVector<int> Voxelizer::get_giprobe_level_cell_count() const {
+ uint32_t cell_count = bake_cells.size();
+ const Cell *cells = bake_cells.ptr();
+ PoolVector<int> level_count;
+ level_count.resize(cell_subdiv + 1); //remember, always x+1 levels for x subdivisions
+ {
+ PoolVector<int>::Write w = level_count.write();
+ for (int i = 0; i < cell_subdiv + 1; i++) {
+ w[i] = 0;
+ }
+
+ for (uint32_t i = 0; i < cell_count; i++) {
+ w[cells[i].level]++;
+ }
+ }
+
+ return level_count;
+}
+
+// euclidean distance computation based on:
+// https://prideout.net/blog/distance_fields/
+
+#define square(m_s) ((m_s) * (m_s))
+#define INF 1e20
+
+/* dt of 1d function using squared distance */
+static void edt(float *f, int stride, int n) {
+
+ float *d = (float *)alloca(sizeof(float) * n + sizeof(int) * n + sizeof(float) * (n + 1));
+ int *v = (int *)&(d[n]);
+ float *z = (float *)&v[n];
+
+ int k = 0;
+ v[0] = 0;
+ z[0] = -INF;
+ z[1] = +INF;
+ for (int q = 1; q <= n - 1; q++) {
+ float s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]);
+ while (s <= z[k]) {
+ k--;
+ s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]);
+ }
+ k++;
+ v[k] = q;
+
+ z[k] = s;
+ z[k + 1] = +INF;
+ }
+
+ k = 0;
+ for (int q = 0; q <= n - 1; q++) {
+ while (z[k + 1] < q)
+ k++;
+ d[q] = square(q - v[k]) + f[v[k] * stride];
+ }
+
+ for (int i = 0; i < n; i++) {
+ f[i * stride] = d[i];
+ }
+}
+
+#undef square
+
+PoolVector<uint8_t> Voxelizer::get_sdf_3d_image() const {
+
+ Vector3i octree_size = get_giprobe_octree_size();
+
+ uint32_t float_count = octree_size.x * octree_size.y * octree_size.z;
+ float *work_memory = memnew_arr(float, float_count);
+ for (uint32_t i = 0; i < float_count; i++) {
+ work_memory[i] = INF;
+ }
+
+ uint32_t y_mult = octree_size.x;
+ uint32_t z_mult = y_mult * octree_size.y;
+
+ //plot solid cells
+ {
+ const Cell *cells = bake_cells.ptr();
+ uint32_t cell_count = bake_cells.size();
+
+ for (uint32_t i = 0; i < cell_count; i++) {
+
+ if (cells[i].level < (cell_subdiv - 1)) {
+ continue; //do not care about this level
+ }
+
+ work_memory[cells[i].x + cells[i].y * y_mult + cells[i].z * z_mult] = 0;
+ }
+ }
+
+ //process in each direction
+
+ //xy->z
+
+ for (int i = 0; i < octree_size.x; i++) {
+ for (int j = 0; j < octree_size.y; j++) {
+ edt(&work_memory[i + j * y_mult], z_mult, octree_size.z);
+ }
+ }
+
+ //xz->y
+
+ for (int i = 0; i < octree_size.x; i++) {
+ for (int j = 0; j < octree_size.z; j++) {
+ edt(&work_memory[i + j * z_mult], y_mult, octree_size.y);
+ }
+ }
+
+ //yz->x
+ for (int i = 0; i < octree_size.y; i++) {
+ for (int j = 0; j < octree_size.z; j++) {
+ edt(&work_memory[i * y_mult + j * z_mult], 1, octree_size.x);
+ }
+ }
+
+ PoolVector<uint8_t> image3d;
+ image3d.resize(float_count);
+ {
+ PoolVector<uint8_t>::Write w = image3d.write();
+ for (uint32_t i = 0; i < float_count; i++) {
+ uint32_t d = uint32_t(Math::sqrt(work_memory[i]));
+ if (d == 0) {
+ w[i] = 0;
+ } else {
+ w[i] = MIN(d, 254) + 1;
+ }
+ }
+ }
+
+ return image3d;
+}
+
+#undef INF
+
+void Voxelizer::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx) {
+
+ if (p_level == cell_subdiv - 1) {
+
+ Vector3 center = p_aabb.position + p_aabb.size * 0.5;
+ Transform xform;
+ xform.origin = center;
+ xform.basis.scale(p_aabb.size * 0.5);
+ p_multimesh->set_instance_transform(idx, xform);
+ Color col;
+ col = Color(bake_cells[p_idx].albedo[0], bake_cells[p_idx].albedo[1], bake_cells[p_idx].albedo[2]);
+ //Color col = Color(bake_cells[p_idx].emission[0], bake_cells[p_idx].emission[1], bake_cells[p_idx].emission[2]);
+ p_multimesh->set_instance_color(idx, col);
+
+ idx++;
+
+ } else {
+
+ for (int i = 0; i < 8; i++) {
+
+ uint32_t child = bake_cells[p_idx].children[i];
+
+ if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells)
+ continue;
+
+ AABB aabb = p_aabb;
+ aabb.size *= 0.5;
+
+ if (i & 1)
+ aabb.position.x += aabb.size.x;
+ if (i & 2)
+ aabb.position.y += aabb.size.y;
+ if (i & 4)
+ aabb.position.z += aabb.size.z;
+
+ _debug_mesh(bake_cells[p_idx].children[i], p_level + 1, aabb, p_multimesh, idx);
+ }
+ }
+}
+
+Ref<MultiMesh> Voxelizer::create_debug_multimesh() {
+
+ Ref<MultiMesh> mm;
+
+ mm.instance();
+
+ mm->set_transform_format(MultiMesh::TRANSFORM_3D);
+ mm->set_use_colors(true);
+ mm->set_instance_count(leaf_voxel_count);
+
+ Ref<ArrayMesh> mesh;
+ mesh.instance();
+
+ {
+ Array arr;
+ arr.resize(Mesh::ARRAY_MAX);
+
+ PoolVector<Vector3> vertices;
+ PoolVector<Color> colors;
+#define ADD_VTX(m_idx) \
+ vertices.push_back(face_points[m_idx]); \
+ colors.push_back(Color(1, 1, 1, 1));
+
+ for (int i = 0; i < 6; i++) {
+
+ Vector3 face_points[4];
+
+ for (int j = 0; j < 4; j++) {
+
+ float v[3];
+ v[0] = 1.0;
+ v[1] = 1 - 2 * ((j >> 1) & 1);
+ v[2] = v[1] * (1 - 2 * (j & 1));
+
+ for (int k = 0; k < 3; k++) {
+
+ if (i < 3)
+ face_points[j][(i + k) % 3] = v[k];
+ else
+ face_points[3 - j][(i + k) % 3] = -v[k];
+ }
+ }
+
+ //tri 1
+ ADD_VTX(0);
+ ADD_VTX(1);
+ ADD_VTX(2);
+ //tri 2
+ ADD_VTX(2);
+ ADD_VTX(3);
+ ADD_VTX(0);
+ }
+
+ arr[Mesh::ARRAY_VERTEX] = vertices;
+ arr[Mesh::ARRAY_COLOR] = colors;
+ mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr);
+ }
+
+ {
+ Ref<StandardMaterial3D> fsm;
+ fsm.instance();
+ fsm->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+ fsm->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ fsm->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ fsm->set_albedo(Color(1, 1, 1, 1));
+
+ mesh->surface_set_material(0, fsm);
+ }
+
+ mm->set_mesh(mesh);
+
+ int idx = 0;
+ _debug_mesh(0, 0, po2_bounds, mm, idx);
+
+ return mm;
+}
+
+Transform Voxelizer::get_to_cell_space_xform() const {
+ return to_cell_space;
+}
+Voxelizer::Voxelizer() {
+ sorted = false;
+ color_scan_cell_width = 4;
+ bake_texture_size = 128;
+}
diff --git a/scene/3d/voxel_light_baker.h b/scene/3d/voxelizer.h
index 7e78a19830..5016ff029f 100644
--- a/scene/3d/voxel_light_baker.h
+++ b/scene/3d/voxelizer.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* voxel_light_baker.h */
+/* voxelizer.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -31,27 +31,11 @@
#ifndef VOXEL_LIGHT_BAKER_H
#define VOXEL_LIGHT_BAKER_H
+#include "core/math/vector3i.h"
#include "scene/3d/mesh_instance.h"
#include "scene/resources/multimesh.h"
-class VoxelLightBaker {
-public:
- enum DebugMode {
- DEBUG_ALBEDO,
- DEBUG_LIGHT
- };
-
- enum BakeQuality {
- BAKE_QUALITY_LOW,
- BAKE_QUALITY_MEDIUM,
- BAKE_QUALITY_HIGH
- };
-
- enum BakeMode {
- BAKE_MODE_CONE_TRACE,
- BAKE_MODE_RAY_TRACE,
- };
-
+class Voxelizer {
private:
enum {
CHILD_EMPTY = 0xFFFFFFFF
@@ -66,7 +50,10 @@ private:
float normal[3];
uint32_t used_sides;
float alpha; //used for upsampling
- int level;
+ uint16_t x;
+ uint16_t y;
+ uint16_t z;
+ uint16_t level;
Cell() {
for (int i = 0; i < 8; i++) {
@@ -80,6 +67,7 @@ private:
}
alpha = 0;
used_sides = 0;
+ x = y = z = 0;
level = 0;
}
};
@@ -87,27 +75,24 @@ private:
Vector<Cell> bake_cells;
int cell_subdiv;
- struct Light {
- int x, y, z;
- float accum[6][3]; //rgb anisotropic
- float direct_accum[6][3]; //for direct bake
- int next_leaf;
- Light() {
- x = y = z = 0;
- for (int i = 0; i < 6; i++) {
- for (int j = 0; j < 3; j++) {
- accum[i][j] = 0;
- direct_accum[i][j] = 0;
- }
- }
- next_leaf = 0;
+ struct CellSort {
+ union {
+ struct {
+ uint64_t z : 16;
+ uint64_t y : 16;
+ uint64_t x : 16;
+ uint64_t level : 16;
+ };
+ uint64_t key;
+ };
+
+ int32_t index;
+
+ _FORCE_INLINE_ bool operator<(const CellSort &p_cell_sort) const {
+ return key < p_cell_sort.key;
}
};
- int first_leaf;
-
- Vector<Light> bake_light;
-
struct MaterialCache {
//128x128 textures
Vector<Color> albedo;
@@ -115,9 +100,6 @@ private:
};
Map<Ref<Material>, MaterialCache> material_cache;
- int leaf_voxel_count;
- bool direct_lights_baked;
-
AABB original_bounds;
AABB po2_bounds;
int axis_cell_size[3];
@@ -128,64 +110,37 @@ private:
int bake_texture_size;
float cell_size;
float propagation;
- float energy;
-
- BakeQuality bake_quality;
- BakeMode bake_mode;
int max_original_cells;
-
- void _init_light_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, uint32_t p_parent);
+ int leaf_voxel_count;
Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add);
MaterialCache _get_material_cache(Ref<Material> p_material);
void _plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb);
void _fixup_plot(int p_idx, int p_level);
- void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, DebugMode p_mode);
- void _check_init_light();
-
- uint32_t _find_cell_at_pos(const Cell *cells, int x, int y, int z);
+ void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx);
- struct LightMap {
- Vector3 light;
- Vector3 pos;
- Vector3 normal;
- };
-
- void _plot_triangle(Vector2 *vertices, Vector3 *positions, Vector3 *normals, LightMap *pixels, int width, int height);
-
- _FORCE_INLINE_ void _sample_baked_octree_filtered_and_anisotropic(const Vector3 &p_posf, const Vector3 &p_direction, float p_level, Vector3 &r_color, float &r_alpha);
- _FORCE_INLINE_ Vector3 _voxel_cone_trace(const Vector3 &p_pos, const Vector3 &p_normal, float p_aperture);
- _FORCE_INLINE_ Vector3 _compute_pixel_light_at_pos(const Vector3 &p_pos, const Vector3 &p_normal);
- _FORCE_INLINE_ Vector3 _compute_ray_trace_at_pos(const Vector3 &p_pos, const Vector3 &p_normal);
-
- void _lightmap_bake_point(uint32_t p_x, LightMap *p_line);
+ bool sorted;
+ void _sort();
public:
void begin_bake(int p_subdiv, const AABB &p_bounds);
void plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material);
- void begin_bake_light(BakeQuality p_quality = BAKE_QUALITY_MEDIUM, BakeMode p_bake_mode = BAKE_MODE_CONE_TRACE, float p_propagation = 0.85, float p_energy = 1);
- void plot_light_directional(const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_energy, bool p_direct);
- void plot_light_omni(const Vector3 &p_pos, const Color &p_color, float p_energy, float p_indirect_energy, float p_radius, float p_attenutation, bool p_direct);
- void plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axis, const Color &p_color, float p_energy, float p_indirect_energy, float p_radius, float p_attenutation, float p_spot_angle, float p_spot_attenuation, bool p_direct);
void end_bake();
- struct LightMapData {
- int width;
- int height;
- PoolVector<float> light;
- };
-
- Error make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, float default_texels_per_unit, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float) = NULL, void *p_bake_time_ud = NULL);
+ int get_gi_probe_octree_depth() const;
+ Vector3i get_giprobe_octree_size() const;
+ int get_giprobe_cell_count() const;
+ PoolVector<uint8_t> get_giprobe_octree_cells() const;
+ PoolVector<uint8_t> get_giprobe_data_cells() const;
+ PoolVector<int> get_giprobe_level_cell_count() const;
+ PoolVector<uint8_t> get_sdf_3d_image() const;
- PoolVector<int> create_gi_probe_data();
- Ref<MultiMesh> create_debug_multimesh(DebugMode p_mode = DEBUG_ALBEDO);
- PoolVector<uint8_t> create_capture_octree(int p_subdiv);
+ Ref<MultiMesh> create_debug_multimesh();
- float get_cell_size() const;
Transform get_to_cell_space_xform() const;
- VoxelLightBaker();
+ Voxelizer();
};
#endif // VOXEL_LIGHT_BAKER_H
diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp
index c8d7382e81..83a7243906 100644
--- a/scene/3d/world_environment.cpp
+++ b/scene/3d/world_environment.cpp
@@ -43,12 +43,25 @@ void WorldEnvironment::_notification(int p_what) {
add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
}
+ if (camera_effects.is_valid()) {
+ if (get_viewport()->find_world()->get_camera_effects().is_valid()) {
+ WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding.");
+ }
+ get_viewport()->find_world()->set_camera_effects(camera_effects);
+ add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ }
+
} else if (p_what == Spatial::NOTIFICATION_EXIT_WORLD || p_what == Spatial::NOTIFICATION_EXIT_TREE) {
if (environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) {
get_viewport()->find_world()->set_environment(Ref<Environment>());
remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
}
+
+ if (camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) {
+ get_viewport()->find_world()->set_camera_effects(Ref<CameraEffects>());
+ remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ }
}
}
@@ -77,13 +90,38 @@ Ref<Environment> WorldEnvironment::get_environment() const {
return environment;
}
+void WorldEnvironment::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) {
+
+ if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) {
+ get_viewport()->find_world()->set_camera_effects(Ref<CameraEffects>());
+ remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ //clean up
+ }
+
+ camera_effects = p_camera_effects;
+ if (is_inside_tree() && camera_effects.is_valid()) {
+ if (get_viewport()->find_world()->get_camera_effects().is_valid()) {
+ WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding.");
+ }
+ get_viewport()->find_world()->set_camera_effects(camera_effects);
+ add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ }
+
+ update_configuration_warning();
+}
+
+Ref<CameraEffects> WorldEnvironment::get_camera_effects() const {
+
+ return camera_effects;
+}
+
String WorldEnvironment::get_configuration_warning() const {
if (!environment.is_valid()) {
return TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect.");
}
- if (/*!is_visible_in_tree() ||*/ !is_inside_tree())
+ if (!is_inside_tree())
return String();
List<Node *> nodes;
@@ -93,11 +131,6 @@ String WorldEnvironment::get_configuration_warning() const {
return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes).");
}
- // Commenting this warning for now, I think it makes no sense. If anyone can figure out what its supposed to do, feedback welcome. Else it should be deprecated.
- //if (environment.is_valid() && get_viewport() && !get_viewport()->get_camera() && environment->get_background() != Environment::BG_CANVAS) {
- // return TTR("This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set this environment's Background Mode to Canvas (for 2D scenes).");
- //}
-
return String();
}
@@ -106,6 +139,10 @@ void WorldEnvironment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_environment", "env"), &WorldEnvironment::set_environment);
ClassDB::bind_method(D_METHOD("get_environment"), &WorldEnvironment::get_environment);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
+
+ ClassDB::bind_method(D_METHOD("set_camera_effects", "env"), &WorldEnvironment::set_camera_effects);
+ ClassDB::bind_method(D_METHOD("get_camera_effects"), &WorldEnvironment::get_camera_effects);
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects");
}
WorldEnvironment::WorldEnvironment() {
diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h
index 6e89fe8517..0c590bfc07 100644
--- a/scene/3d/world_environment.h
+++ b/scene/3d/world_environment.h
@@ -38,6 +38,7 @@ class WorldEnvironment : public Node {
GDCLASS(WorldEnvironment, Node);
Ref<Environment> environment;
+ Ref<CameraEffects> camera_effects;
protected:
void _notification(int p_what);
@@ -47,6 +48,9 @@ public:
void set_environment(const Ref<Environment> &p_environment);
Ref<Environment> get_environment() const;
+ void set_camera_effects(const Ref<CameraEffects> &p_camera_effects);
+ Ref<CameraEffects> get_camera_effects() const;
+
String get_configuration_warning() const;
WorldEnvironment();
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 2bc9336b14..ceee0529c2 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -106,7 +106,7 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
} else if (name.begins_with("anims/")) {
String which = name.get_slicec('/', 1);
- r_ret = get_animation(which).get_ref_ptr();
+ r_ret = get_animation(which);
} else if (name.begins_with("next/")) {
@@ -249,7 +249,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
Vector<StringName> leftover_path;
Node *child = parent->get_node_and_resource(a->track_get_path(i), resource, leftover_path);
ERR_CONTINUE_MSG(!child, "On Animation: '" + p_anim->name + "', couldn't resolve track: '" + String(a->track_get_path(i)) + "'."); // couldn't find the child node
- uint32_t id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id();
+ ObjectID id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id();
int bone_idx = -1;
if (a->track_get_path(i).get_subname_count() == 1 && Object::cast_to<Skeleton>(child)) {
@@ -493,7 +493,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
pa->object->set_indexed(pa->subpath, value, &valid); //you are not speshul
#ifdef DEBUG_ENABLED
if (!valid) {
- ERR_PRINTS("Failed setting track value '" + String(pa->owner->path) + "'. Check if property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -501,7 +501,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
case SP_NODE2D_POS: {
#ifdef DEBUG_ENABLED
if (value.get_type() != Variant::VECTOR2) {
- ERR_PRINTS("Position key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not of type Vector2(). Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Position key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not of type Vector2(). Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
static_cast<Node2D *>(pa->object)->set_position(value);
@@ -509,7 +509,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
case SP_NODE2D_ROT: {
#ifdef DEBUG_ENABLED
if (value.is_num()) {
- ERR_PRINTS("Rotation key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not numerical. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Rotation key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not numerical. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -518,7 +518,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
case SP_NODE2D_SCALE: {
#ifdef DEBUG_ENABLED
if (value.get_type() != Variant::VECTOR2) {
- ERR_PRINTS("Scale key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not of type Vector2()." + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Scale key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not of type Vector2()." + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -553,7 +553,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
ERR_CONTINUE(s > VARIANT_ARG_MAX);
#ifdef DEBUG_ENABLED
if (!nc->node->has_method(method)) {
- ERR_PRINTS("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -884,7 +884,7 @@ void AnimationPlayer::_animation_update_transforms() {
pa->object->set_indexed(pa->subpath, pa->value_accum, &valid); //you are not speshul
#ifdef DEBUG_ENABLED
if (!valid) {
- ERR_PRINTS("Failed setting key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "'. Check if property exists or the type of key is right for the property");
+ ERR_PRINT("Failed setting key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "'. Check if property exists or the type of key is right for the property");
}
#endif
@@ -892,7 +892,7 @@ void AnimationPlayer::_animation_update_transforms() {
case SP_NODE2D_POS: {
#ifdef DEBUG_ENABLED
if (pa->value_accum.get_type() != Variant::VECTOR2) {
- ERR_PRINTS("Position key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not of type Vector2()");
+ ERR_PRINT("Position key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not of type Vector2()");
}
#endif
static_cast<Node2D *>(pa->object)->set_position(pa->value_accum);
@@ -900,7 +900,7 @@ void AnimationPlayer::_animation_update_transforms() {
case SP_NODE2D_ROT: {
#ifdef DEBUG_ENABLED
if (pa->value_accum.is_num()) {
- ERR_PRINTS("Rotation key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not numerical");
+ ERR_PRINT("Rotation key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not numerical");
}
#endif
@@ -909,7 +909,7 @@ void AnimationPlayer::_animation_update_transforms() {
case SP_NODE2D_SCALE: {
#ifdef DEBUG_ENABLED
if (pa->value_accum.get_type() != Variant::VECTOR2) {
- ERR_PRINTS("Scale key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not of type Vector2()");
+ ERR_PRINT("Scale key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not of type Vector2()");
}
#endif
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 06f762e63e..48829b02b9 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -159,17 +159,15 @@ private:
struct TrackNodeCacheKey {
- uint32_t id;
+ ObjectID id;
int bone_idx;
inline bool operator<(const TrackNodeCacheKey &p_right) const {
- if (id < p_right.id)
- return true;
- else if (id > p_right.id)
- return false;
- else
+ if (id == p_right.id)
return bone_idx < p_right.bone_idx;
+ else
+ return id < p_right.id;
}
};
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 8b2d8861e7..a08cc0927b 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -49,7 +49,7 @@ void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const {
if (get_script_instance()) {
- return get_script_instance()->call("get_parameter_default_value");
+ return get_script_instance()->call("get_parameter_default_value", p_parameter);
}
return Variant();
}
@@ -397,7 +397,7 @@ void AnimationNode::_validate_property(PropertyInfo &property) const {
Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) {
if (get_script_instance()) {
- return get_script_instance()->call("get_child_by_name");
+ return get_script_instance()->call("get_child_by_name", p_name);
}
return Ref<AnimationNode>();
}
@@ -578,7 +578,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
Node *child = parent->get_node_and_resource(path, resource, leftover_path);
if (!child) {
- ERR_PRINTS("AnimationTree: '" + String(E->get()) + "', couldn't resolve track: '" + String(path) + "'");
+ ERR_PRINT("AnimationTree: '" + String(E->get()) + "', couldn't resolve track: '" + String(path) + "'");
continue;
}
@@ -608,7 +608,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
Spatial *spatial = Object::cast_to<Spatial>(child);
if (!spatial) {
- ERR_PRINTS("AnimationTree: '" + String(E->get()) + "', transform track does not point to spatial: '" + String(path) + "'");
+ ERR_PRINT("AnimationTree: '" + String(E->get()) + "', transform track does not point to spatial: '" + String(path) + "'");
continue;
}
@@ -767,7 +767,7 @@ void AnimationTree::_process_graph(float p_delta) {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
- ObjectID current_animation_player = 0;
+ ObjectID current_animation_player;
if (player) {
current_animation_player = player->get_instance_id();
@@ -775,7 +775,7 @@ void AnimationTree::_process_graph(float p_delta) {
if (last_animation_player != current_animation_player) {
- if (last_animation_player) {
+ if (last_animation_player.is_valid()) {
Object *old_player = ObjectDB::get_instance(last_animation_player);
if (old_player) {
old_player->disconnect("caches_cleared", this, "_clear_caches");
@@ -1296,7 +1296,7 @@ void AnimationTree::_notification(int p_what) {
if (p_what == NOTIFICATION_EXIT_TREE) {
_clear_caches();
- if (last_animation_player) {
+ if (last_animation_player.is_valid()) {
Object *player = ObjectDB::get_instance(last_animation_player);
if (player) {
@@ -1304,7 +1304,7 @@ void AnimationTree::_notification(int p_what) {
}
}
} else if (p_what == NOTIFICATION_ENTER_TREE) {
- if (last_animation_player) {
+ if (last_animation_player.is_valid()) {
Object *player = ObjectDB::get_instance(last_animation_player);
if (player) {
@@ -1584,7 +1584,6 @@ AnimationTree::AnimationTree() {
process_pass = 1;
started = true;
properties_dirty = true;
- last_animation_player = 0;
}
AnimationTree::~AnimationTree() {
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 0a8dc8109f..8769e2c61d 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -187,7 +187,6 @@ private:
setup_pass = 0;
process_pass = 0;
object = NULL;
- object_id = 0;
}
virtual ~TrackCache() {}
};
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
deleted file mode 100644
index c7362391dc..0000000000
--- a/scene/animation/animation_tree_player.cpp
+++ /dev/null
@@ -1,1866 +0,0 @@
-/*************************************************************************/
-/* animation_tree_player.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "animation_tree_player.h"
-#include "animation_player.h"
-
-#include "scene/scene_string_names.h"
-
-void AnimationTreePlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
-
- if (animation_process_mode == p_mode)
- return;
-
- bool pr = processing;
- if (pr)
- _set_process(false);
- animation_process_mode = p_mode;
- if (pr)
- _set_process(true);
-}
-
-AnimationTreePlayer::AnimationProcessMode AnimationTreePlayer::get_animation_process_mode() const {
-
- return animation_process_mode;
-}
-
-void AnimationTreePlayer::_set_process(bool p_process, bool p_force) {
- if (processing == p_process && !p_force)
- return;
-
- switch (animation_process_mode) {
-
- case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break;
- case ANIMATION_PROCESS_IDLE: set_process_internal(p_process && active); break;
- }
-
- processing = p_process;
-}
-
-bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) {
-
- if (String(p_name) == "base_path") {
- set_base_path(p_value);
- return true;
- }
-
- if (String(p_name) == "master_player") {
- set_master_player(p_value);
- return true;
- }
-
- if (String(p_name) == SceneStringNames::get_singleton()->playback_active) {
- set_active(p_value);
- return true;
- }
-
- if (String(p_name) != "data")
- return false;
-
- Dictionary data = p_value;
-
- Array nodes = data.get_valid("nodes");
-
- for (int i = 0; i < nodes.size(); i++) {
-
- Dictionary node = nodes[i];
-
- StringName id = node.get_valid("id");
- Point2 pos = node.get_valid("position");
-
- NodeType nt = NODE_MAX;
- String type = node.get_valid("type");
-
- if (type == "output")
- nt = NODE_OUTPUT;
- else if (type == "animation")
- nt = NODE_ANIMATION;
- else if (type == "oneshot")
- nt = NODE_ONESHOT;
- else if (type == "mix")
- nt = NODE_MIX;
- else if (type == "blend2")
- nt = NODE_BLEND2;
- else if (type == "blend3")
- nt = NODE_BLEND3;
- else if (type == "blend4")
- nt = NODE_BLEND4;
- else if (type == "timescale")
- nt = NODE_TIMESCALE;
- else if (type == "timeseek")
- nt = NODE_TIMESEEK;
- else if (type == "transition")
- nt = NODE_TRANSITION;
-
- ERR_FAIL_COND_V(nt == NODE_MAX, false);
-
- if (nt != NODE_OUTPUT)
- add_node(nt, id);
- node_set_position(id, pos);
-
- switch (nt) {
- case NODE_OUTPUT: {
-
- } break;
- case NODE_ANIMATION: {
-
- if (node.has("from"))
- animation_node_set_master_animation(id, node.get_valid("from"));
- else
- animation_node_set_animation(id, node.get_valid("animation"));
- Array filters = node.get_valid("filter");
- for (int j = 0; j < filters.size(); j++) {
-
- animation_node_set_filter_path(id, filters[j], true);
- }
- } break;
- case NODE_ONESHOT: {
-
- oneshot_node_set_fadein_time(id, node.get_valid("fade_in"));
- oneshot_node_set_fadeout_time(id, node.get_valid("fade_out"));
- oneshot_node_set_mix_mode(id, node.get_valid("mix"));
- oneshot_node_set_autorestart(id, node.get_valid("autorestart"));
- oneshot_node_set_autorestart_delay(id, node.get_valid("autorestart_delay"));
- oneshot_node_set_autorestart_random_delay(id, node.get_valid("autorestart_random_delay"));
- Array filters = node.get_valid("filter");
- for (int j = 0; j < filters.size(); j++) {
-
- oneshot_node_set_filter_path(id, filters[j], true);
- }
-
- } break;
- case NODE_MIX: {
- mix_node_set_amount(id, node.get_valid("mix"));
- } break;
- case NODE_BLEND2: {
- blend2_node_set_amount(id, node.get_valid("blend"));
- Array filters = node.get_valid("filter");
- for (int j = 0; j < filters.size(); j++) {
-
- blend2_node_set_filter_path(id, filters[j], true);
- }
- } break;
- case NODE_BLEND3: {
- blend3_node_set_amount(id, node.get_valid("blend"));
- } break;
- case NODE_BLEND4: {
- blend4_node_set_amount(id, node.get_valid("blend"));
- } break;
- case NODE_TIMESCALE: {
- timescale_node_set_scale(id, node.get_valid("scale"));
- } break;
- case NODE_TIMESEEK: {
- } break;
- case NODE_TRANSITION: {
-
- transition_node_set_xfade_time(id, node.get_valid("xfade"));
-
- Array transitions = node.get_valid("transitions");
- transition_node_set_input_count(id, transitions.size());
-
- for (int x = 0; x < transitions.size(); x++) {
-
- Dictionary d = transitions[x];
- bool aa = d.get_valid("auto_advance");
- transition_node_set_input_auto_advance(id, x, aa);
- }
-
- } break;
- default: {
- };
- }
- }
-
- Array connections = data.get_valid("connections");
- ERR_FAIL_COND_V(connections.size() % 3, false);
-
- int cc = connections.size() / 3;
-
- for (int i = 0; i < cc; i++) {
-
- StringName src = connections[i * 3 + 0];
- StringName dst = connections[i * 3 + 1];
- int dst_in = connections[i * 3 + 2];
- connect_nodes(src, dst, dst_in);
- }
-
- set_active(data.get_valid("active"));
- set_master_player(data.get_valid("master"));
-
- return true;
-}
-
-bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (String(p_name) == "base_path") {
- r_ret = base_path;
- return true;
- }
-
- if (String(p_name) == "master_player") {
- r_ret = master;
- return true;
- }
-
- if (String(p_name) == "playback/active") {
- r_ret = is_active();
- return true;
- }
-
- if (String(p_name) != "data")
- return false;
-
- Dictionary data;
-
- Array nodes;
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *n = node_map[E->key()];
-
- Dictionary node;
- node["id"] = E->key();
- node["position"] = n->pos;
-
- switch (n->type) {
- case NODE_OUTPUT: node["type"] = "output"; break;
- case NODE_ANIMATION: node["type"] = "animation"; break;
- case NODE_ONESHOT: node["type"] = "oneshot"; break;
- case NODE_MIX: node["type"] = "mix"; break;
- case NODE_BLEND2: node["type"] = "blend2"; break;
- case NODE_BLEND3: node["type"] = "blend3"; break;
- case NODE_BLEND4: node["type"] = "blend4"; break;
- case NODE_TIMESCALE: node["type"] = "timescale"; break;
- case NODE_TIMESEEK: node["type"] = "timeseek"; break;
- case NODE_TRANSITION: node["type"] = "transition"; break;
- default: node["type"] = ""; break;
- }
-
- switch (n->type) {
- case NODE_OUTPUT: {
-
- } break;
- case NODE_ANIMATION: {
- AnimationNode *an = static_cast<AnimationNode *>(n);
- if (master != NodePath() && an->from != "") {
- node["from"] = an->from;
- } else {
- node["animation"] = an->animation;
- }
- Array k;
- List<NodePath> keys;
- an->filter.get_key_list(&keys);
- k.resize(keys.size());
- int i = 0;
- for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) {
- k[i++] = F->get();
- }
- node["filter"] = k;
- } break;
- case NODE_ONESHOT: {
- OneShotNode *osn = static_cast<OneShotNode *>(n);
- node["fade_in"] = osn->fade_in;
- node["fade_out"] = osn->fade_out;
- node["mix"] = osn->mix;
- node["autorestart"] = osn->autorestart;
- node["autorestart_delay"] = osn->autorestart_delay;
- node["autorestart_random_delay"] = osn->autorestart_random_delay;
-
- Array k;
- List<NodePath> keys;
- osn->filter.get_key_list(&keys);
- k.resize(keys.size());
- int i = 0;
- for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) {
- k[i++] = F->get();
- }
- node["filter"] = k;
-
- } break;
- case NODE_MIX: {
- MixNode *mn = static_cast<MixNode *>(n);
- node["mix"] = mn->amount;
- } break;
- case NODE_BLEND2: {
- Blend2Node *bn = static_cast<Blend2Node *>(n);
- node["blend"] = bn->value;
- Array k;
- List<NodePath> keys;
- bn->filter.get_key_list(&keys);
- k.resize(keys.size());
- int i = 0;
- for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) {
- k[i++] = F->get();
- }
- node["filter"] = k;
-
- } break;
- case NODE_BLEND3: {
- Blend3Node *bn = static_cast<Blend3Node *>(n);
- node["blend"] = bn->value;
- } break;
- case NODE_BLEND4: {
- Blend4Node *bn = static_cast<Blend4Node *>(n);
- node["blend"] = bn->value;
-
- } break;
- case NODE_TIMESCALE: {
- TimeScaleNode *tsn = static_cast<TimeScaleNode *>(n);
- node["scale"] = tsn->scale;
- } break;
- case NODE_TIMESEEK: {
- } break;
- case NODE_TRANSITION: {
-
- TransitionNode *tn = static_cast<TransitionNode *>(n);
- node["xfade"] = tn->xfade;
- Array transitions;
-
- for (int i = 0; i < tn->input_data.size(); i++) {
-
- Dictionary d;
- d["auto_advance"] = tn->input_data[i].auto_advance;
- transitions.push_back(d);
- }
-
- node["transitions"] = transitions;
-
- } break;
- default: {
- };
- }
-
- nodes.push_back(node);
- }
-
- data["nodes"] = nodes;
- //connectiosn
-
- List<Connection> connections;
- get_connection_list(&connections);
- Array connections_arr;
- connections_arr.resize(connections.size() * 3);
-
- int idx = 0;
- for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
-
- connections_arr.set(idx + 0, E->get().src_node);
- connections_arr.set(idx + 1, E->get().dst_node);
- connections_arr.set(idx + 2, E->get().dst_input);
-
- idx += 3;
- }
-
- data["connections"] = connections_arr;
- data["active"] = active;
- data["master"] = master;
-
- r_ret = data;
-
- return true;
-}
-
-void AnimationTreePlayer::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK));
-}
-
-void AnimationTreePlayer::advance(float p_time) {
-
- _process_animation(p_time);
-}
-
-void AnimationTreePlayer::_notification(int p_what) {
-
- switch (p_what) {
-
- case NOTIFICATION_ENTER_TREE: {
-
- WARN_DEPRECATED_MSG("AnimationTreePlayer has been deprecated. Use AnimationTree instead.");
-
- if (!processing) {
- //make sure that a previous process state was not saved
- //only process if "processing" is set
- set_physics_process_internal(false);
- set_process_internal(false);
- }
- } break;
- case NOTIFICATION_READY: {
-
- dirty_caches = true;
- if (master != NodePath()) {
- _update_sources();
- }
- } break;
- case NOTIFICATION_INTERNAL_PROCESS: {
-
- if (animation_process_mode == ANIMATION_PROCESS_PHYSICS)
- break;
-
- if (processing)
- _process_animation(get_process_delta_time());
- } break;
- case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
- if (animation_process_mode == ANIMATION_PROCESS_IDLE)
- break;
-
- if (processing)
- _process_animation(get_physics_process_delta_time());
- } break;
- }
-}
-
-void AnimationTreePlayer::_compute_weights(float *p_fallback_weight, HashMap<NodePath, float> *p_weights, float p_coeff, const HashMap<NodePath, bool> *p_filter, float p_filtered_coeff) {
-
- if (p_filter != NULL) {
-
- List<NodePath> key_list;
- p_filter->get_key_list(&key_list);
-
- for (List<NodePath>::Element *E = key_list.front(); E; E = E->next()) {
-
- if ((*p_filter)[E->get()]) {
-
- if (p_weights->has(E->get())) {
- (*p_weights)[E->get()] *= p_filtered_coeff;
- } else {
- p_weights->set(E->get(), *p_fallback_weight * p_filtered_coeff);
- }
-
- } else if (p_weights->has(E->get())) {
- (*p_weights)[E->get()] *= p_coeff;
- }
- }
- }
-
- List<NodePath> key_list;
- p_weights->get_key_list(&key_list);
-
- for (List<NodePath>::Element *E = key_list.front(); E; E = E->next()) {
- if (p_filter == NULL || !p_filter->has(E->get())) {
- (*p_weights)[E->get()] *= p_coeff;
- }
- }
-
- *p_fallback_weight *= p_coeff;
-}
-
-float AnimationTreePlayer::_process_node(const StringName &p_node, AnimationNode **r_prev_anim, float p_time, bool p_seek, float p_fallback_weight, HashMap<NodePath, float> *p_weights) {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), 0);
- NodeBase *nb = node_map[p_node];
-
- //transform to seconds...
-
- switch (nb->type) {
-
- case NODE_OUTPUT: {
-
- NodeOut *on = static_cast<NodeOut *>(nb);
- HashMap<NodePath, float> weights;
-
- return _process_node(on->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, &weights);
-
- } break;
- case NODE_ANIMATION: {
-
- AnimationNode *an = static_cast<AnimationNode *>(nb);
-
- float rem = 0;
- if (!an->animation.is_null()) {
-
- //float pos = an->time;
- //float delta = p_time;
-
- //const Animation *a = an->animation.operator->();
-
- if (p_seek) {
- an->time = p_time;
- an->step = 0;
- } else {
- an->time = MAX(0, an->time + p_time);
- an->step = p_time;
- }
-
- float anim_size = an->animation->get_length();
-
- if (an->animation->has_loop()) {
-
- if (anim_size)
- an->time = Math::fposmod(an->time, anim_size);
-
- } else if (an->time > anim_size) {
-
- an->time = anim_size;
- }
-
- an->skip = true;
-
- for (List<AnimationNode::TrackRef>::Element *E = an->tref.front(); E; E = E->next()) {
- NodePath track_path = an->animation->track_get_path(E->get().local_track);
- if (an->filter.has(track_path) && an->filter[track_path]) {
- E->get().weight = 0;
- } else {
- if (p_weights->has(track_path)) {
- float weight = (*p_weights)[track_path];
- E->get().weight = weight;
- } else {
- E->get().weight = p_fallback_weight;
- }
- }
- if (E->get().weight > CMP_EPSILON)
- an->skip = false;
- }
-
- rem = anim_size - an->time;
- }
-
- if (!(*r_prev_anim))
- active_list = an;
- else
- (*r_prev_anim)->next = an;
-
- an->next = NULL;
- *r_prev_anim = an;
-
- return rem;
-
- } break;
- case NODE_ONESHOT: {
-
- OneShotNode *osn = static_cast<OneShotNode *>(nb);
-
- if (!osn->active) {
- //make it as if this node doesn't exist, pass input 0 by.
- return _process_node(osn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- }
-
- bool os_seek = p_seek;
-
- if (p_seek)
- osn->time = p_time;
- if (osn->start) {
- osn->time = 0;
- os_seek = true;
- }
-
- float blend;
-
- if (osn->time < osn->fade_in) {
-
- if (osn->fade_in > 0)
- blend = osn->time / osn->fade_in;
- else
- blend = 0; //wtf
-
- } else if (!osn->start && osn->remaining < osn->fade_out) {
-
- if (osn->fade_out)
- blend = (osn->remaining / osn->fade_out);
- else
- blend = 1.0;
- } else
- blend = 1.0;
-
- float main_rem;
- float os_rem;
-
- HashMap<NodePath, float> os_weights(*p_weights);
- float os_fallback_weight = p_fallback_weight;
- _compute_weights(&p_fallback_weight, p_weights, osn->mix ? 1.0 : 1.0 - blend, &osn->filter, 1.0);
- _compute_weights(&os_fallback_weight, &os_weights, blend, &osn->filter, 0.0);
-
- main_rem = _process_node(osn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- os_rem = _process_node(osn->inputs[1].node, r_prev_anim, p_time, os_seek, os_fallback_weight, &os_weights);
-
- if (osn->start) {
- osn->remaining = os_rem;
- osn->start = false;
- }
-
- if (!p_seek) {
- osn->time += p_time;
- osn->remaining = os_rem;
- if (osn->remaining <= 0)
- osn->active = false;
- }
-
- return MAX(main_rem, osn->remaining);
- } break;
- case NODE_MIX: {
- MixNode *mn = static_cast<MixNode *>(nb);
-
- HashMap<NodePath, float> mn_weights(*p_weights);
- float mn_fallback_weight = p_fallback_weight;
- _compute_weights(&mn_fallback_weight, &mn_weights, mn->amount);
- float rem = _process_node(mn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- _process_node(mn->inputs[1].node, r_prev_anim, p_time, p_seek, mn_fallback_weight, &mn_weights);
- return rem;
-
- } break;
- case NODE_BLEND2: {
-
- Blend2Node *bn = static_cast<Blend2Node *>(nb);
-
- HashMap<NodePath, float> bn_weights(*p_weights);
- float bn_fallback_weight = p_fallback_weight;
- _compute_weights(&p_fallback_weight, p_weights, 1.0 - bn->value, &bn->filter, 1.0);
- _compute_weights(&bn_fallback_weight, &bn_weights, bn->value, &bn->filter, 0.0);
- float rem = _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, bn_fallback_weight, &bn_weights);
-
- return rem;
- } break;
- case NODE_BLEND3: {
- Blend3Node *bn = static_cast<Blend3Node *>(nb);
-
- float rem;
- float blend, lower_blend, upper_blend;
- if (bn->value < 0) {
- lower_blend = -bn->value;
- blend = 1.0 - lower_blend;
- upper_blend = 0;
- } else {
- lower_blend = 0;
- blend = 1.0 - bn->value;
- upper_blend = bn->value;
- }
-
- HashMap<NodePath, float> upper_weights(*p_weights);
- float upper_fallback_weight = p_fallback_weight;
- HashMap<NodePath, float> lower_weights(*p_weights);
- float lower_fallback_weight = p_fallback_weight;
- _compute_weights(&upper_fallback_weight, &upper_weights, upper_blend);
- _compute_weights(&p_fallback_weight, p_weights, blend);
- _compute_weights(&lower_fallback_weight, &lower_weights, lower_blend);
-
- rem = _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, lower_fallback_weight, &lower_weights);
- _process_node(bn->inputs[2].node, r_prev_anim, p_time, p_seek, upper_fallback_weight, &upper_weights);
-
- return rem;
- } break;
- case NODE_BLEND4: {
- Blend4Node *bn = static_cast<Blend4Node *>(nb);
-
- HashMap<NodePath, float> weights1(*p_weights);
- float fallback_weight1 = p_fallback_weight;
- HashMap<NodePath, float> weights2(*p_weights);
- float fallback_weight2 = p_fallback_weight;
- HashMap<NodePath, float> weights3(*p_weights);
- float fallback_weight3 = p_fallback_weight;
-
- _compute_weights(&p_fallback_weight, p_weights, 1.0 - bn->value.x);
- _compute_weights(&fallback_weight1, &weights1, bn->value.x);
- _compute_weights(&fallback_weight2, &weights2, 1.0 - bn->value.y);
- _compute_weights(&fallback_weight3, &weights3, bn->value.y);
-
- float rem = _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, fallback_weight1, &weights1);
- float rem2 = _process_node(bn->inputs[2].node, r_prev_anim, p_time, p_seek, fallback_weight2, &weights2);
- _process_node(bn->inputs[3].node, r_prev_anim, p_time, p_seek, fallback_weight3, &weights3);
-
- return MAX(rem, rem2);
-
- } break;
- case NODE_TIMESCALE: {
- TimeScaleNode *tsn = static_cast<TimeScaleNode *>(nb);
- float rem;
- if (p_seek)
- rem = _process_node(tsn->inputs[0].node, r_prev_anim, p_time, true, p_fallback_weight, p_weights);
- else
- rem = _process_node(tsn->inputs[0].node, r_prev_anim, p_time * tsn->scale, false, p_fallback_weight, p_weights);
- if (tsn->scale == 0)
- return Math_INF;
- else
- return rem / tsn->scale;
-
- } break;
- case NODE_TIMESEEK: {
-
- TimeSeekNode *tsn = static_cast<TimeSeekNode *>(nb);
- if (tsn->seek_pos >= 0 && !p_seek) {
-
- p_time = tsn->seek_pos;
- p_seek = true;
- }
- tsn->seek_pos = -1;
-
- return _process_node(tsn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
-
- } break;
- case NODE_TRANSITION: {
-
- TransitionNode *tn = static_cast<TransitionNode *>(nb);
- HashMap<NodePath, float> prev_weights(*p_weights);
- float prev_fallback_weight = p_fallback_weight;
-
- if (tn->prev < 0) { // process current animation, check for transition
-
- float rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- if (p_seek)
- tn->time = p_time;
- else
- tn->time += p_time;
-
- if (tn->input_data[tn->current].auto_advance && rem <= tn->xfade) {
-
- tn->set_current((tn->current + 1) % tn->inputs.size());
- }
-
- return rem;
- } else { // cross-fading from tn->prev to tn->current
-
- float blend = tn->xfade ? (tn->prev_xfading / tn->xfade) : 1;
-
- float rem;
-
- _compute_weights(&p_fallback_weight, p_weights, 1.0 - blend);
- _compute_weights(&prev_fallback_weight, &prev_weights, blend);
-
- if (!p_seek && tn->switched) { //just switched, seek to start of current
-
- rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, 0, true, p_fallback_weight, p_weights);
- } else {
-
- rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- }
-
- tn->switched = false;
-
- if (p_seek) { // don't seek prev animation
- _process_node(tn->inputs[tn->prev].node, r_prev_anim, 0, false, prev_fallback_weight, &prev_weights);
- tn->time = p_time;
- } else {
- _process_node(tn->inputs[tn->prev].node, r_prev_anim, p_time, false, prev_fallback_weight, &prev_weights);
- tn->time += p_time;
- tn->prev_xfading -= p_time;
- if (tn->prev_xfading < 0) {
-
- tn->prev = -1;
- }
- }
-
- return rem;
- }
-
- } break;
- default: {
- }
- }
-
- return 0;
-}
-
-void AnimationTreePlayer::_process_animation(float p_delta) {
-
- if (last_error != CONNECT_OK)
- return;
-
- if (dirty_caches)
- _recompute_caches();
-
- active_list = NULL;
- AnimationNode *prev = NULL;
-
- if (reset_request) {
-
- _process_node(out_name, &prev, 0, true);
- reset_request = false;
- } else
- _process_node(out_name, &prev, p_delta);
-
- if (dirty_caches) {
- //some animation changed.. ignore this pass
- return;
- }
-
- //update the tracks..
-
- /* STEP 1 CLEAR TRACKS */
-
- for (TrackMap::Element *E = track_map.front(); E; E = E->next()) {
-
- Track &t = E->get();
-
- t.loc.zero();
- t.rot = Quat();
- t.scale.x = 0;
- t.scale.y = 0;
- t.scale.z = 0;
-
- t.value = t.object->get_indexed(t.subpath);
- t.value.zero();
-
- t.skip = false;
- }
-
- /* STEP 2 PROCESS ANIMATIONS */
-
- AnimationNode *anim_list = active_list;
- Quat empty_rot;
-
- while (anim_list) {
-
- if (!anim_list->animation.is_null() && !anim_list->skip) {
- //check if animation is meaningful
- Animation *a = anim_list->animation.operator->();
-
- for (List<AnimationNode::TrackRef>::Element *E = anim_list->tref.front(); E; E = E->next()) {
-
- AnimationNode::TrackRef &tr = E->get();
- if (tr.track == NULL || tr.local_track < 0 || tr.weight < CMP_EPSILON || !a->track_is_enabled(tr.local_track))
- continue;
-
- switch (a->track_get_type(tr.local_track)) {
- case Animation::TYPE_TRANSFORM: { ///< Transform a node or a bone.
-
- Vector3 loc;
- Quat rot;
- Vector3 scale;
- a->transform_track_interpolate(tr.local_track, anim_list->time, &loc, &rot, &scale);
-
- tr.track->loc += loc * tr.weight;
-
- scale.x -= 1.0;
- scale.y -= 1.0;
- scale.z -= 1.0;
- tr.track->scale += scale * tr.weight;
-
- tr.track->rot = tr.track->rot * empty_rot.slerp(rot, tr.weight);
-
- } break;
- case Animation::TYPE_VALUE: { ///< Set a value in a property, can be interpolated.
-
- if (a->value_track_get_update_mode(tr.local_track) == Animation::UPDATE_CONTINUOUS) {
- Variant value = a->value_track_interpolate(tr.local_track, anim_list->time);
- Variant::blend(tr.track->value, value, tr.weight, tr.track->value);
- } else {
- int index = a->track_find_key(tr.local_track, anim_list->time);
- tr.track->value = a->track_get_key_value(tr.local_track, index);
- }
- } break;
- case Animation::TYPE_METHOD: { ///< Call any method on a specific node.
-
- List<int> indices;
- a->method_track_get_key_indices(tr.local_track, anim_list->time, anim_list->step, &indices);
- for (List<int>::Element *F = indices.front(); F; F = F->next()) {
-
- StringName method = a->method_track_get_name(tr.local_track, F->get());
- Vector<Variant> args = a->method_track_get_params(tr.local_track, F->get());
- args.resize(VARIANT_ARG_MAX);
- tr.track->object->call(method, args[0], args[1], args[2], args[3], args[4]);
- }
- } break;
- default: {
- }
- }
- }
- }
-
- anim_list = anim_list->next;
- }
-
- /* STEP 3 APPLY TRACKS */
-
- for (TrackMap::Element *E = track_map.front(); E; E = E->next()) {
-
- Track &t = E->get();
-
- if (t.skip || !t.object)
- continue;
-
- if (t.subpath.size()) { // value track
- t.object->set_indexed(t.subpath, t.value);
- continue;
- }
-
- Transform xform;
- xform.origin = t.loc;
-
- t.scale.x += 1.0;
- t.scale.y += 1.0;
- t.scale.z += 1.0;
- xform.basis.set_quat_scale(t.rot, t.scale);
-
- if (t.bone_idx >= 0) {
- if (t.skeleton)
- t.skeleton->set_bone_pose(t.bone_idx, xform);
-
- } else if (t.spatial) {
-
- t.spatial->set_transform(xform);
- }
- }
-}
-
-void AnimationTreePlayer::add_node(NodeType p_type, const StringName &p_node) {
-
- ERR_FAIL_COND(p_type == NODE_OUTPUT);
- ERR_FAIL_COND(node_map.has(p_node));
-
- NodeBase *n = NULL;
-
- switch (p_type) {
-
- case NODE_ANIMATION: {
-
- n = memnew(AnimationNode);
- } break;
- case NODE_ONESHOT: {
-
- n = memnew(OneShotNode);
-
- } break;
- case NODE_MIX: {
- n = memnew(MixNode);
-
- } break;
- case NODE_BLEND2: {
- n = memnew(Blend2Node);
-
- } break;
- case NODE_BLEND3: {
- n = memnew(Blend3Node);
-
- } break;
- case NODE_BLEND4: {
- n = memnew(Blend4Node);
-
- } break;
- case NODE_TIMESCALE: {
- n = memnew(TimeScaleNode);
-
- } break;
- case NODE_TIMESEEK: {
- n = memnew(TimeSeekNode);
-
- } break;
- case NODE_TRANSITION: {
- n = memnew(TransitionNode);
-
- } break;
- default: {
- }
- }
-
- //n->name+=" "+itos(p_node);
- node_map[p_node] = n;
-}
-
-StringName AnimationTreePlayer::node_get_input_source(const StringName &p_node, int p_input) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), StringName());
- ERR_FAIL_INDEX_V(p_input, node_map[p_node]->inputs.size(), StringName());
- return node_map[p_node]->inputs[p_input].node;
-}
-
-int AnimationTreePlayer::node_get_input_count(const StringName &p_node) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), -1);
- return node_map[p_node]->inputs.size();
-}
-#define GET_NODE(m_type, m_cast) \
- ERR_FAIL_COND(!node_map.has(p_node)); \
- ERR_FAIL_COND_MSG(node_map[p_node]->type != m_type, "Invalid parameter for node type."); \
- m_cast *n = static_cast<m_cast *>(node_map[p_node]);
-
-void AnimationTreePlayer::animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation) {
-
- GET_NODE(NODE_ANIMATION, AnimationNode);
- n->animation = p_animation;
- dirty_caches = true;
-}
-
-void AnimationTreePlayer::animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation) {
-
- GET_NODE(NODE_ANIMATION, AnimationNode);
- n->from = p_master_animation;
- dirty_caches = true;
- if (master != NodePath())
- _update_sources();
-}
-
-void AnimationTreePlayer::animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter) {
-
- GET_NODE(NODE_ANIMATION, AnimationNode);
-
- if (p_filter)
- n->filter[p_track_path] = true;
- else
- n->filter.erase(p_track_path);
-}
-
-void AnimationTreePlayer::animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const {
-
- GET_NODE(NODE_ANIMATION, AnimationNode);
-
- n->filter.get_key_list(r_paths);
-}
-
-void AnimationTreePlayer::oneshot_node_set_fadein_time(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->fade_in = p_time;
-}
-
-void AnimationTreePlayer::oneshot_node_set_fadeout_time(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->fade_out = p_time;
-}
-
-void AnimationTreePlayer::oneshot_node_set_mix_mode(const StringName &p_node, bool p_mix) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->mix = p_mix;
-}
-
-void AnimationTreePlayer::oneshot_node_set_autorestart(const StringName &p_node, bool p_active) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->autorestart = p_active;
-}
-
-void AnimationTreePlayer::oneshot_node_set_autorestart_delay(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->autorestart_delay = p_time;
-}
-void AnimationTreePlayer::oneshot_node_set_autorestart_random_delay(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->autorestart_random_delay = p_time;
-}
-
-void AnimationTreePlayer::oneshot_node_start(const StringName &p_node) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->active = true;
- n->start = true;
-}
-
-void AnimationTreePlayer::oneshot_node_stop(const StringName &p_node) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->active = false;
-}
-
-void AnimationTreePlayer::oneshot_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
-
- if (p_enable)
- n->filter[p_filter] = true;
- else
- n->filter.erase(p_filter);
-}
-
-void AnimationTreePlayer::oneshot_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
-
- n->filter.get_key_list(r_paths);
-}
-
-void AnimationTreePlayer::mix_node_set_amount(const StringName &p_node, float p_amount) {
-
- GET_NODE(NODE_MIX, MixNode);
- n->amount = p_amount;
-}
-
-void AnimationTreePlayer::blend2_node_set_amount(const StringName &p_node, float p_amount) {
-
- GET_NODE(NODE_BLEND2, Blend2Node);
- n->value = p_amount;
-}
-
-void AnimationTreePlayer::blend2_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable) {
-
- GET_NODE(NODE_BLEND2, Blend2Node);
-
- if (p_enable)
- n->filter[p_filter] = true;
- else
- n->filter.erase(p_filter);
-}
-
-void AnimationTreePlayer::blend2_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const {
-
- GET_NODE(NODE_BLEND2, Blend2Node);
-
- n->filter.get_key_list(r_paths);
-}
-
-void AnimationTreePlayer::blend3_node_set_amount(const StringName &p_node, float p_amount) {
-
- GET_NODE(NODE_BLEND3, Blend3Node);
- n->value = p_amount;
-}
-void AnimationTreePlayer::blend4_node_set_amount(const StringName &p_node, const Vector2 &p_amount) {
-
- GET_NODE(NODE_BLEND4, Blend4Node);
- n->value = p_amount;
-}
-void AnimationTreePlayer::timescale_node_set_scale(const StringName &p_node, float p_scale) {
-
- GET_NODE(NODE_TIMESCALE, TimeScaleNode);
- n->scale = p_scale;
-}
-void AnimationTreePlayer::timeseek_node_seek(const StringName &p_node, float p_pos) {
-
- GET_NODE(NODE_TIMESEEK, TimeSeekNode);
- n->seek_pos = p_pos;
-}
-void AnimationTreePlayer::transition_node_set_input_count(const StringName &p_node, int p_inputs) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- ERR_FAIL_COND(p_inputs < 1);
-
- n->inputs.resize(p_inputs);
- n->input_data.resize(p_inputs);
-
- _clear_cycle_test();
-
- last_error = _cycle_test(out_name);
-}
-void AnimationTreePlayer::transition_node_set_input_auto_advance(const StringName &p_node, int p_input, bool p_auto_advance) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- ERR_FAIL_INDEX(p_input, n->input_data.size());
-
- n->input_data.write[p_input].auto_advance = p_auto_advance;
-}
-void AnimationTreePlayer::transition_node_set_xfade_time(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- n->xfade = p_time;
-}
-
-void AnimationTreePlayer::TransitionNode::set_current(int p_current) {
-
- ERR_FAIL_INDEX(p_current, inputs.size());
-
- if (current == p_current)
- return;
-
- prev = current;
- prev_xfading = xfade;
- prev_time = time;
- time = 0;
- current = p_current;
- switched = true;
-}
-
-void AnimationTreePlayer::transition_node_set_current(const StringName &p_node, int p_current) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- n->set_current(p_current);
-}
-
-void AnimationTreePlayer::node_set_position(const StringName &p_node, const Vector2 &p_pos) {
-
- ERR_FAIL_COND(!node_map.has(p_node));
- node_map[p_node]->pos = p_pos;
-}
-
-AnimationTreePlayer::NodeType AnimationTreePlayer::node_get_type(const StringName &p_node) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), NODE_OUTPUT);
- return node_map[p_node]->type;
-}
-Point2 AnimationTreePlayer::node_get_position(const StringName &p_node) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), Point2());
- return node_map[p_node]->pos;
-}
-
-#define GET_NODE_V(m_type, m_cast, m_ret) \
- ERR_FAIL_COND_V(!node_map.has(p_node), m_ret); \
- ERR_FAIL_COND_V_MSG(node_map[p_node]->type != m_type, m_ret, "Invalid parameter for node type."); \
- m_cast *n = static_cast<m_cast *>(node_map[p_node]);
-
-Ref<Animation> AnimationTreePlayer::animation_node_get_animation(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ANIMATION, AnimationNode, Ref<Animation>());
- return n->animation;
-}
-
-String AnimationTreePlayer::animation_node_get_master_animation(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ANIMATION, AnimationNode, String());
- return n->from;
-}
-
-float AnimationTreePlayer::animation_node_get_position(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ANIMATION, AnimationNode, 0);
- return n->time;
-}
-
-bool AnimationTreePlayer::animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const {
-
- GET_NODE_V(NODE_ANIMATION, AnimationNode, 0);
- return n->filter.has(p_path);
-}
-
-float AnimationTreePlayer::oneshot_node_get_fadein_time(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->fade_in;
-}
-
-float AnimationTreePlayer::oneshot_node_get_fadeout_time(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->fade_out;
-}
-
-bool AnimationTreePlayer::oneshot_node_get_mix_mode(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->mix;
-}
-bool AnimationTreePlayer::oneshot_node_has_autorestart(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->autorestart;
-}
-float AnimationTreePlayer::oneshot_node_get_autorestart_delay(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->autorestart_delay;
-}
-float AnimationTreePlayer::oneshot_node_get_autorestart_random_delay(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->autorestart_random_delay;
-}
-
-bool AnimationTreePlayer::oneshot_node_is_active(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->active;
-}
-
-bool AnimationTreePlayer::oneshot_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->filter.has(p_path);
-}
-
-float AnimationTreePlayer::mix_node_get_amount(const StringName &p_node) const {
-
- GET_NODE_V(NODE_MIX, MixNode, 0);
- return n->amount;
-}
-float AnimationTreePlayer::blend2_node_get_amount(const StringName &p_node) const {
-
- GET_NODE_V(NODE_BLEND2, Blend2Node, 0);
- return n->value;
-}
-
-bool AnimationTreePlayer::blend2_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const {
-
- GET_NODE_V(NODE_BLEND2, Blend2Node, 0);
- return n->filter.has(p_path);
-}
-
-float AnimationTreePlayer::blend3_node_get_amount(const StringName &p_node) const {
-
- GET_NODE_V(NODE_BLEND3, Blend3Node, 0);
- return n->value;
-}
-Vector2 AnimationTreePlayer::blend4_node_get_amount(const StringName &p_node) const {
-
- GET_NODE_V(NODE_BLEND4, Blend4Node, Vector2());
- return n->value;
-}
-
-float AnimationTreePlayer::timescale_node_get_scale(const StringName &p_node) const {
-
- GET_NODE_V(NODE_TIMESCALE, TimeScaleNode, 0);
- return n->scale;
-}
-
-void AnimationTreePlayer::transition_node_delete_input(const StringName &p_node, int p_input) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- ERR_FAIL_INDEX(p_input, n->inputs.size());
-
- if (n->inputs.size() <= 1)
- return;
-
- n->inputs.remove(p_input);
- n->input_data.remove(p_input);
- last_error = _cycle_test(out_name);
-}
-
-int AnimationTreePlayer::transition_node_get_input_count(const StringName &p_node) const {
-
- GET_NODE_V(NODE_TRANSITION, TransitionNode, 0);
- return n->inputs.size();
-}
-
-bool AnimationTreePlayer::transition_node_has_input_auto_advance(const StringName &p_node, int p_input) const {
-
- GET_NODE_V(NODE_TRANSITION, TransitionNode, false);
- ERR_FAIL_INDEX_V(p_input, n->inputs.size(), false);
- return n->input_data[p_input].auto_advance;
-}
-float AnimationTreePlayer::transition_node_get_xfade_time(const StringName &p_node) const {
-
- GET_NODE_V(NODE_TRANSITION, TransitionNode, 0);
- return n->xfade;
-}
-
-int AnimationTreePlayer::transition_node_get_current(const StringName &p_node) const {
-
- GET_NODE_V(NODE_TRANSITION, TransitionNode, -1);
- return n->current;
-}
-
-/*misc */
-void AnimationTreePlayer::get_node_list(List<StringName> *p_node_list) const {
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- p_node_list->push_back(E->key());
- }
-}
-
-void AnimationTreePlayer::remove_node(const StringName &p_node) {
-
- ERR_FAIL_COND(!node_map.has(p_node));
- ERR_FAIL_COND_MSG(p_node == out_name, "Node 0 (output) can't be removed.");
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *nb = E->get();
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- if (nb->inputs[i].node == p_node)
- nb->inputs.write[i].node = StringName();
- }
- }
-
- node_map.erase(p_node);
-
- _clear_cycle_test();
-
- // compute last error again, just in case
- last_error = _cycle_test(out_name);
- dirty_caches = true;
-}
-
-AnimationTreePlayer::ConnectError AnimationTreePlayer::_cycle_test(const StringName &p_at_node) {
-
- ERR_FAIL_COND_V(!node_map.has(p_at_node), CONNECT_INCOMPLETE);
-
- NodeBase *nb = node_map[p_at_node];
- if (nb->cycletest)
- return CONNECT_CYCLE;
-
- nb->cycletest = true;
-
- for (int i = 0; i < nb->inputs.size(); i++) {
- if (nb->inputs[i].node == StringName())
- return CONNECT_INCOMPLETE;
-
- ConnectError _err = _cycle_test(nb->inputs[i].node);
- if (_err)
- return _err;
- }
-
- return CONNECT_OK;
-}
-
-// Use this function to not alter next complete _cycle_test().
-void AnimationTreePlayer::_clear_cycle_test() {
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
- NodeBase *nb = E->get();
- nb->cycletest = false;
- }
-}
-
-Error AnimationTreePlayer::connect_nodes(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) {
-
- ERR_FAIL_COND_V(!node_map.has(p_src_node), ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(!node_map.has(p_dst_node), ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_src_node == p_dst_node, ERR_INVALID_PARAMETER);
-
- //NodeBase *src = node_map[p_src_node];
- NodeBase *dst = node_map[p_dst_node];
- ERR_FAIL_INDEX_V(p_dst_input, dst->inputs.size(), ERR_INVALID_PARAMETER);
-
- //int oldval = dst->inputs[p_dst_input].node;
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *nb = E->get();
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- if (nb->inputs[i].node == p_src_node)
- nb->inputs.write[i].node = StringName();
- }
- }
-
- dst->inputs.write[p_dst_input].node = p_src_node;
-
- _clear_cycle_test();
-
- last_error = _cycle_test(out_name);
- if (last_error) {
-
- if (last_error == CONNECT_INCOMPLETE)
- return ERR_UNCONFIGURED;
- else if (last_error == CONNECT_CYCLE)
- return ERR_CYCLIC_LINK;
- }
- dirty_caches = true;
- return OK;
-}
-
-bool AnimationTreePlayer::are_nodes_connected(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_src_node), false);
- ERR_FAIL_COND_V(!node_map.has(p_dst_node), false);
- ERR_FAIL_COND_V(p_src_node == p_dst_node, false);
-
- NodeBase *dst = node_map[p_dst_node];
-
- return dst->inputs[p_dst_input].node == p_src_node;
-}
-
-void AnimationTreePlayer::disconnect_nodes(const StringName &p_node, int p_input) {
-
- ERR_FAIL_COND(!node_map.has(p_node));
-
- NodeBase *dst = node_map[p_node];
- ERR_FAIL_INDEX(p_input, dst->inputs.size());
- dst->inputs.write[p_input].node = StringName();
- last_error = CONNECT_INCOMPLETE;
- dirty_caches = true;
-}
-
-void AnimationTreePlayer::get_connection_list(List<Connection> *p_connections) const {
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *nb = E->get();
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- if (nb->inputs[i].node != StringName()) {
- Connection c;
- c.src_node = nb->inputs[i].node;
- c.dst_node = E->key();
- c.dst_input = i;
- p_connections->push_back(c);
- }
- }
- }
-}
-
-AnimationTreePlayer::Track *AnimationTreePlayer::_find_track(const NodePath &p_path) {
-
- Node *parent = get_node(base_path);
- ERR_FAIL_COND_V(!parent, NULL);
-
- RES resource;
- Vector<StringName> leftover_path;
- Node *child = parent->get_node_and_resource(p_path, resource, leftover_path);
- if (!child) {
- String err = "Animation track references unknown Node: '" + String(p_path) + "'.";
- WARN_PRINT(err.ascii().get_data());
- return NULL;
- }
-
- ObjectID id = child->get_instance_id();
- int bone_idx = -1;
-
- if (p_path.get_subname_count()) {
-
- if (Object::cast_to<Skeleton>(child))
- bone_idx = Object::cast_to<Skeleton>(child)->find_bone(p_path.get_subname(0));
- }
-
- TrackKey key;
- key.id = id;
- key.bone_idx = bone_idx;
- key.subpath_concatenated = p_path.get_concatenated_subnames();
-
- if (!track_map.has(key)) {
-
- Track tr;
- tr.id = id;
- tr.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child;
- tr.skeleton = Object::cast_to<Skeleton>(child);
- tr.spatial = Object::cast_to<Spatial>(child);
- tr.bone_idx = bone_idx;
- if (bone_idx == -1) tr.subpath = leftover_path;
-
- track_map[key] = tr;
- }
-
- return &track_map[key];
-}
-
-void AnimationTreePlayer::_recompute_caches() {
-
- track_map.clear();
- _recompute_caches(out_name);
- dirty_caches = false;
-}
-
-void AnimationTreePlayer::_recompute_caches(const StringName &p_node) {
-
- ERR_FAIL_COND(!node_map.has(p_node));
-
- NodeBase *nb = node_map[p_node];
-
- if (nb->type == NODE_ANIMATION) {
-
- AnimationNode *an = static_cast<AnimationNode *>(nb);
- an->tref.clear();
-
- if (!an->animation.is_null()) {
-
- Ref<Animation> a = an->animation;
-
- for (int i = 0; i < an->animation->get_track_count(); i++) {
-
- Track *tr = _find_track(a->track_get_path(i));
- if (!tr)
- continue;
-
- AnimationNode::TrackRef tref;
- tref.local_track = i;
- tref.track = tr;
- tref.weight = 0;
-
- an->tref.push_back(tref);
- }
- }
- }
-
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- _recompute_caches(nb->inputs[i].node);
- }
-}
-
-void AnimationTreePlayer::recompute_caches() {
-
- dirty_caches = true;
-}
-
-/* playback */
-
-void AnimationTreePlayer::set_active(bool p_active) {
-
- if (active == p_active)
- return;
-
- active = p_active;
- processing = active;
- reset_request = p_active;
- _set_process(processing, true);
-}
-
-bool AnimationTreePlayer::is_active() const {
-
- return active;
-}
-
-AnimationTreePlayer::ConnectError AnimationTreePlayer::get_last_error() const {
-
- return last_error;
-}
-
-void AnimationTreePlayer::reset() {
-
- reset_request = true;
-}
-
-void AnimationTreePlayer::set_base_path(const NodePath &p_path) {
-
- base_path = p_path;
- recompute_caches();
-}
-
-NodePath AnimationTreePlayer::get_base_path() const {
-
- return base_path;
-}
-
-void AnimationTreePlayer::set_master_player(const NodePath &p_path) {
-
- if (p_path == master)
- return;
-
- master = p_path;
- _update_sources();
- recompute_caches();
-}
-
-NodePath AnimationTreePlayer::get_master_player() const {
-
- return master;
-}
-
-PoolVector<String> AnimationTreePlayer::_get_node_list() {
-
- List<StringName> nl;
- get_node_list(&nl);
- PoolVector<String> ret;
- ret.resize(nl.size());
- int idx = 0;
- for (List<StringName>::Element *E = nl.front(); E; E = E->next()) {
- ret.set(idx++, E->get());
- }
-
- return ret;
-}
-
-void AnimationTreePlayer::_update_sources() {
-
- if (master == NodePath())
- return;
- if (!is_inside_tree())
- return;
-
- Node *m = get_node(master);
- if (!m) {
- master = NodePath();
- ERR_FAIL_COND(!m);
- }
-
- AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(m);
-
- if (!ap) {
-
- master = NodePath();
- ERR_FAIL_COND(!ap);
- }
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- if (E->get()->type == NODE_ANIMATION) {
-
- AnimationNode *an = static_cast<AnimationNode *>(E->get());
-
- if (an->from != "") {
-
- an->animation = ap->get_animation(an->from);
- }
- }
- }
-}
-
-bool AnimationTreePlayer::node_exists(const StringName &p_name) const {
-
- return (node_map.has(p_name));
-}
-
-Error AnimationTreePlayer::node_rename(const StringName &p_node, const StringName &p_new_name) {
-
- if (p_new_name == p_node)
- return OK;
- ERR_FAIL_COND_V(!node_map.has(p_node), ERR_ALREADY_EXISTS);
- ERR_FAIL_COND_V(node_map.has(p_new_name), ERR_ALREADY_EXISTS);
- ERR_FAIL_COND_V(p_new_name == StringName(), ERR_INVALID_DATA);
- ERR_FAIL_COND_V(p_node == out_name, ERR_INVALID_DATA);
- ERR_FAIL_COND_V(p_new_name == out_name, ERR_INVALID_DATA);
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *nb = E->get();
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- if (nb->inputs[i].node == p_node) {
- nb->inputs.write[i].node = p_new_name;
- }
- }
- }
-
- node_map[p_new_name] = node_map[p_node];
- node_map.erase(p_node);
-
- return OK;
-}
-
-String AnimationTreePlayer::get_configuration_warning() const {
-
- return TTR("This node has been deprecated. Use AnimationTree instead.");
-}
-
-void AnimationTreePlayer::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("add_node", "type", "id"), &AnimationTreePlayer::add_node);
-
- ClassDB::bind_method(D_METHOD("node_exists", "node"), &AnimationTreePlayer::node_exists);
- ClassDB::bind_method(D_METHOD("node_rename", "node", "new_name"), &AnimationTreePlayer::node_rename);
-
- ClassDB::bind_method(D_METHOD("node_get_type", "id"), &AnimationTreePlayer::node_get_type);
- ClassDB::bind_method(D_METHOD("node_get_input_count", "id"), &AnimationTreePlayer::node_get_input_count);
- ClassDB::bind_method(D_METHOD("node_get_input_source", "id", "idx"), &AnimationTreePlayer::node_get_input_source);
-
- ClassDB::bind_method(D_METHOD("animation_node_set_animation", "id", "animation"), &AnimationTreePlayer::animation_node_set_animation);
- ClassDB::bind_method(D_METHOD("animation_node_get_animation", "id"), &AnimationTreePlayer::animation_node_get_animation);
-
- ClassDB::bind_method(D_METHOD("animation_node_set_master_animation", "id", "source"), &AnimationTreePlayer::animation_node_set_master_animation);
- ClassDB::bind_method(D_METHOD("animation_node_get_master_animation", "id"), &AnimationTreePlayer::animation_node_get_master_animation);
- ClassDB::bind_method(D_METHOD("animation_node_get_position", "id"), &AnimationTreePlayer::animation_node_get_position);
- ClassDB::bind_method(D_METHOD("animation_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::animation_node_set_filter_path);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_set_fadein_time", "id", "time_sec"), &AnimationTreePlayer::oneshot_node_set_fadein_time);
- ClassDB::bind_method(D_METHOD("oneshot_node_get_fadein_time", "id"), &AnimationTreePlayer::oneshot_node_get_fadein_time);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_set_fadeout_time", "id", "time_sec"), &AnimationTreePlayer::oneshot_node_set_fadeout_time);
- ClassDB::bind_method(D_METHOD("oneshot_node_get_fadeout_time", "id"), &AnimationTreePlayer::oneshot_node_get_fadeout_time);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart", "id", "enable"), &AnimationTreePlayer::oneshot_node_set_autorestart);
- ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart_delay", "id", "delay_sec"), &AnimationTreePlayer::oneshot_node_set_autorestart_delay);
- ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart_random_delay", "id", "rand_sec"), &AnimationTreePlayer::oneshot_node_set_autorestart_random_delay);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_has_autorestart", "id"), &AnimationTreePlayer::oneshot_node_has_autorestart);
- ClassDB::bind_method(D_METHOD("oneshot_node_get_autorestart_delay", "id"), &AnimationTreePlayer::oneshot_node_get_autorestart_delay);
- ClassDB::bind_method(D_METHOD("oneshot_node_get_autorestart_random_delay", "id"), &AnimationTreePlayer::oneshot_node_get_autorestart_random_delay);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_start", "id"), &AnimationTreePlayer::oneshot_node_start);
- ClassDB::bind_method(D_METHOD("oneshot_node_stop", "id"), &AnimationTreePlayer::oneshot_node_stop);
- ClassDB::bind_method(D_METHOD("oneshot_node_is_active", "id"), &AnimationTreePlayer::oneshot_node_is_active);
- ClassDB::bind_method(D_METHOD("oneshot_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::oneshot_node_set_filter_path);
-
- ClassDB::bind_method(D_METHOD("mix_node_set_amount", "id", "ratio"), &AnimationTreePlayer::mix_node_set_amount);
- ClassDB::bind_method(D_METHOD("mix_node_get_amount", "id"), &AnimationTreePlayer::mix_node_get_amount);
-
- ClassDB::bind_method(D_METHOD("blend2_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend2_node_set_amount);
- ClassDB::bind_method(D_METHOD("blend2_node_get_amount", "id"), &AnimationTreePlayer::blend2_node_get_amount);
- ClassDB::bind_method(D_METHOD("blend2_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::blend2_node_set_filter_path);
-
- ClassDB::bind_method(D_METHOD("blend3_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend3_node_set_amount);
- ClassDB::bind_method(D_METHOD("blend3_node_get_amount", "id"), &AnimationTreePlayer::blend3_node_get_amount);
-
- ClassDB::bind_method(D_METHOD("blend4_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend4_node_set_amount);
- ClassDB::bind_method(D_METHOD("blend4_node_get_amount", "id"), &AnimationTreePlayer::blend4_node_get_amount);
-
- ClassDB::bind_method(D_METHOD("timescale_node_set_scale", "id", "scale"), &AnimationTreePlayer::timescale_node_set_scale);
- ClassDB::bind_method(D_METHOD("timescale_node_get_scale", "id"), &AnimationTreePlayer::timescale_node_get_scale);
-
- ClassDB::bind_method(D_METHOD("timeseek_node_seek", "id", "seconds"), &AnimationTreePlayer::timeseek_node_seek);
-
- ClassDB::bind_method(D_METHOD("transition_node_set_input_count", "id", "count"), &AnimationTreePlayer::transition_node_set_input_count);
- ClassDB::bind_method(D_METHOD("transition_node_get_input_count", "id"), &AnimationTreePlayer::transition_node_get_input_count);
- ClassDB::bind_method(D_METHOD("transition_node_delete_input", "id", "input_idx"), &AnimationTreePlayer::transition_node_delete_input);
-
- ClassDB::bind_method(D_METHOD("transition_node_set_input_auto_advance", "id", "input_idx", "enable"), &AnimationTreePlayer::transition_node_set_input_auto_advance);
- ClassDB::bind_method(D_METHOD("transition_node_has_input_auto_advance", "id", "input_idx"), &AnimationTreePlayer::transition_node_has_input_auto_advance);
-
- ClassDB::bind_method(D_METHOD("transition_node_set_xfade_time", "id", "time_sec"), &AnimationTreePlayer::transition_node_set_xfade_time);
- ClassDB::bind_method(D_METHOD("transition_node_get_xfade_time", "id"), &AnimationTreePlayer::transition_node_get_xfade_time);
-
- ClassDB::bind_method(D_METHOD("transition_node_set_current", "id", "input_idx"), &AnimationTreePlayer::transition_node_set_current);
- ClassDB::bind_method(D_METHOD("transition_node_get_current", "id"), &AnimationTreePlayer::transition_node_get_current);
-
- ClassDB::bind_method(D_METHOD("node_set_position", "id", "screen_position"), &AnimationTreePlayer::node_set_position);
- ClassDB::bind_method(D_METHOD("node_get_position", "id"), &AnimationTreePlayer::node_get_position);
-
- ClassDB::bind_method(D_METHOD("remove_node", "id"), &AnimationTreePlayer::remove_node);
- ClassDB::bind_method(D_METHOD("connect_nodes", "id", "dst_id", "dst_input_idx"), &AnimationTreePlayer::connect_nodes);
- ClassDB::bind_method(D_METHOD("are_nodes_connected", "id", "dst_id", "dst_input_idx"), &AnimationTreePlayer::are_nodes_connected);
- ClassDB::bind_method(D_METHOD("disconnect_nodes", "id", "dst_input_idx"), &AnimationTreePlayer::disconnect_nodes);
-
- ClassDB::bind_method(D_METHOD("set_active", "enabled"), &AnimationTreePlayer::set_active);
- ClassDB::bind_method(D_METHOD("is_active"), &AnimationTreePlayer::is_active);
-
- ClassDB::bind_method(D_METHOD("set_base_path", "path"), &AnimationTreePlayer::set_base_path);
- ClassDB::bind_method(D_METHOD("get_base_path"), &AnimationTreePlayer::get_base_path);
-
- ClassDB::bind_method(D_METHOD("set_master_player", "nodepath"), &AnimationTreePlayer::set_master_player);
- ClassDB::bind_method(D_METHOD("get_master_player"), &AnimationTreePlayer::get_master_player);
-
- ClassDB::bind_method(D_METHOD("get_node_list"), &AnimationTreePlayer::_get_node_list);
-
- ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationTreePlayer::set_animation_process_mode);
- ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationTreePlayer::get_animation_process_mode);
-
- ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTreePlayer::advance);
-
- ClassDB::bind_method(D_METHOD("reset"), &AnimationTreePlayer::reset);
-
- ClassDB::bind_method(D_METHOD("recompute_caches"), &AnimationTreePlayer::recompute_caches);
-
- ADD_GROUP("Playback", "playback_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
-
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_master_player", "get_master_player");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "base_path"), "set_base_path", "get_base_path");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
-
- BIND_ENUM_CONSTANT(NODE_OUTPUT);
- BIND_ENUM_CONSTANT(NODE_ANIMATION);
- BIND_ENUM_CONSTANT(NODE_ONESHOT);
- BIND_ENUM_CONSTANT(NODE_MIX);
- BIND_ENUM_CONSTANT(NODE_BLEND2);
- BIND_ENUM_CONSTANT(NODE_BLEND3);
- BIND_ENUM_CONSTANT(NODE_BLEND4);
- BIND_ENUM_CONSTANT(NODE_TIMESCALE);
- BIND_ENUM_CONSTANT(NODE_TIMESEEK);
- BIND_ENUM_CONSTANT(NODE_TRANSITION);
-
- BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
- BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE);
-}
-
-AnimationTreePlayer::AnimationTreePlayer() {
-
- active_list = NULL;
- out = memnew(NodeOut);
- out_name = "out";
- out->pos = Point2(40, 40);
- node_map.insert(out_name, out);
- animation_process_mode = ANIMATION_PROCESS_IDLE;
- processing = false;
- active = false;
- dirty_caches = true;
- reset_request = true;
- last_error = CONNECT_INCOMPLETE;
- base_path = String("..");
-}
-
-AnimationTreePlayer::~AnimationTreePlayer() {
-
- while (node_map.size()) {
- memdelete(node_map.front()->get());
- node_map.erase(node_map.front());
- }
-}
diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h
deleted file mode 100644
index e1f6ce7b9c..0000000000
--- a/scene/animation/animation_tree_player.h
+++ /dev/null
@@ -1,487 +0,0 @@
-/*************************************************************************/
-/* animation_tree_player.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef ANIMATION_TREE_PLAYER_H
-#define ANIMATION_TREE_PLAYER_H
-
-#include "animation_player.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
-#include "scene/resources/animation.h"
-
-class AnimationTreePlayer : public Node {
-
- GDCLASS(AnimationTreePlayer, Node);
- OBJ_CATEGORY("Animation Nodes");
-
-public:
- enum AnimationProcessMode {
- ANIMATION_PROCESS_PHYSICS,
- ANIMATION_PROCESS_IDLE,
- };
-
- enum NodeType {
-
- NODE_OUTPUT,
- NODE_ANIMATION,
- NODE_ONESHOT,
- NODE_MIX,
- NODE_BLEND2,
- NODE_BLEND3,
- NODE_BLEND4,
- NODE_TIMESCALE,
- NODE_TIMESEEK,
- NODE_TRANSITION,
-
- NODE_MAX,
- };
-
- enum ConnectError {
-
- CONNECT_OK,
- CONNECT_INCOMPLETE,
- CONNECT_CYCLE
- };
-
-private:
- enum {
-
- DISCONNECTED = -1,
- };
-
- struct TrackKey {
-
- uint32_t id;
- StringName subpath_concatenated;
- int bone_idx;
-
- inline bool operator<(const TrackKey &p_right) const {
-
- if (id == p_right.id) {
- if (bone_idx == p_right.bone_idx) {
- return subpath_concatenated < p_right.subpath_concatenated;
- } else
- return bone_idx < p_right.bone_idx;
- } else
- return id < p_right.id;
- }
- };
-
- struct Track {
- uint32_t id;
- Object *object;
- Spatial *spatial;
- Skeleton *skeleton;
- int bone_idx;
- Vector<StringName> subpath;
-
- Vector3 loc;
- Quat rot;
- Vector3 scale;
-
- Variant value;
-
- bool skip;
-
- Track() :
- id(0),
- object(NULL),
- spatial(NULL),
- skeleton(NULL),
- bone_idx(-1),
- skip(false) {}
- };
-
- typedef Map<TrackKey, Track> TrackMap;
-
- TrackMap track_map;
-
- struct Input {
-
- StringName node;
- //Input() { node=-1; }
- };
-
- struct NodeBase {
-
- bool cycletest;
-
- NodeType type;
- Point2 pos;
-
- Vector<Input> inputs;
-
- NodeBase() { cycletest = false; };
- virtual ~NodeBase() { cycletest = false; }
- };
-
- struct NodeOut : public NodeBase {
-
- NodeOut() {
- type = NODE_OUTPUT;
- inputs.resize(1);
- }
- };
-
- struct AnimationNode : public NodeBase {
-
- Ref<Animation> animation;
-
- struct TrackRef {
- int local_track;
- Track *track;
- float weight;
- };
-
- uint64_t last_version;
- List<TrackRef> tref;
- AnimationNode *next;
- float time;
- float step;
- String from;
- bool skip;
-
- HashMap<NodePath, bool> filter;
-
- AnimationNode() {
- type = NODE_ANIMATION;
- next = NULL;
- last_version = 0;
- skip = false;
- }
- };
-
- struct OneShotNode : public NodeBase {
-
- bool active;
- bool start;
- float fade_in;
- float fade_out;
-
- bool autorestart;
- float autorestart_delay;
- float autorestart_random_delay;
- bool mix;
-
- float time;
- float remaining;
- float autorestart_remaining;
-
- HashMap<NodePath, bool> filter;
-
- OneShotNode() {
- type = NODE_ONESHOT;
- fade_in = 0;
- fade_out = 0;
- inputs.resize(2);
- autorestart = false;
- autorestart_delay = 1;
- autorestart_remaining = 0;
- mix = false;
- active = false;
- start = false;
- }
- };
-
- struct MixNode : public NodeBase {
-
- float amount;
- MixNode() {
- type = NODE_MIX;
- inputs.resize(2);
- }
- };
-
- struct Blend2Node : public NodeBase {
-
- float value;
- HashMap<NodePath, bool> filter;
- Blend2Node() {
- type = NODE_BLEND2;
- value = 0;
- inputs.resize(2);
- }
- };
-
- struct Blend3Node : public NodeBase {
-
- float value;
- Blend3Node() {
- type = NODE_BLEND3;
- value = 0;
- inputs.resize(3);
- }
- };
-
- struct Blend4Node : public NodeBase {
-
- Point2 value;
- Blend4Node() {
- type = NODE_BLEND4;
- inputs.resize(4);
- }
- };
-
- struct TimeScaleNode : public NodeBase {
-
- float scale;
- TimeScaleNode() {
- type = NODE_TIMESCALE;
- scale = 1;
- inputs.resize(1);
- }
- };
-
- struct TimeSeekNode : public NodeBase {
-
- float seek_pos;
-
- TimeSeekNode() {
- type = NODE_TIMESEEK;
- inputs.resize(1);
- seek_pos = -1;
- }
- };
-
- struct TransitionNode : public NodeBase {
-
- struct InputData {
-
- bool auto_advance;
- InputData() { auto_advance = false; }
- };
-
- Vector<InputData> input_data;
-
- float prev_time;
- float prev_xfading;
- int prev;
- bool switched;
-
- float time;
- int current;
-
- float xfade;
-
- TransitionNode() {
- type = NODE_TRANSITION;
- xfade = 0;
- inputs.resize(1);
- input_data.resize(1);
- current = 0;
- prev = -1;
- prev_time = 0;
- prev_xfading = 0;
- switched = false;
- }
- void set_current(int p_current);
- };
-
- void _update_sources();
-
- StringName out_name;
- NodeOut *out;
-
- NodePath base_path;
- NodePath master;
-
- ConnectError last_error;
- AnimationNode *active_list;
- AnimationProcessMode animation_process_mode;
- bool processing;
- bool active;
- bool dirty_caches;
- Map<StringName, NodeBase *> node_map;
-
- // return time left to finish animation
- float _process_node(const StringName &p_node, AnimationNode **r_prev_anim, float p_time, bool p_seek = false, float p_fallback_weight = 1.0, HashMap<NodePath, float> *p_weights = NULL);
- void _process_animation(float p_delta);
- bool reset_request;
-
- ConnectError _cycle_test(const StringName &p_at_node);
- void _clear_cycle_test();
-
- Track *_find_track(const NodePath &p_path);
- void _recompute_caches();
- void _recompute_caches(const StringName &p_node);
- PoolVector<String> _get_node_list();
-
- void _compute_weights(float *p_fallback_weight, HashMap<NodePath, float> *p_weights, float p_coeff, const HashMap<NodePath, bool> *p_filter = NULL, float p_filtered_coeff = 0);
-
-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;
- void _notification(int p_what);
-
- static void _bind_methods();
-
-public:
- void add_node(NodeType p_type, const StringName &p_node); // nodes must be >0 node 0 is built-in (exit)
- bool node_exists(const StringName &p_name) const;
-
- Error node_rename(const StringName &p_node, const StringName &p_new_name);
- int node_get_input_count(const StringName &p_node) const;
- StringName node_get_input_source(const StringName &p_node, int p_input) const;
-
- String get_configuration_warning() const;
-
- /* ANIMATION NODE */
- void animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation);
- Ref<Animation> animation_node_get_animation(const StringName &p_node) const;
- void animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation);
- String animation_node_get_master_animation(const StringName &p_node) const;
- float animation_node_get_position(const StringName &p_node) const;
-
- void animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter);
- void animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const;
- bool animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const;
-
- /* ONE SHOT NODE */
-
- void oneshot_node_set_fadein_time(const StringName &p_node, float p_time);
- void oneshot_node_set_fadeout_time(const StringName &p_node, float p_time);
-
- float oneshot_node_get_fadein_time(const StringName &p_node) const;
- float oneshot_node_get_fadeout_time(const StringName &p_node) const;
-
- void oneshot_node_set_autorestart(const StringName &p_node, bool p_active);
- void oneshot_node_set_autorestart_delay(const StringName &p_node, float p_time);
- void oneshot_node_set_autorestart_random_delay(const StringName &p_node, float p_time);
-
- bool oneshot_node_has_autorestart(const StringName &p_node) const;
- float oneshot_node_get_autorestart_delay(const StringName &p_node) const;
- float oneshot_node_get_autorestart_random_delay(const StringName &p_node) const;
-
- void oneshot_node_set_mix_mode(const StringName &p_node, bool p_mix);
- bool oneshot_node_get_mix_mode(const StringName &p_node) const;
-
- void oneshot_node_start(const StringName &p_node);
- void oneshot_node_stop(const StringName &p_node);
- bool oneshot_node_is_active(const StringName &p_node) const;
-
- void oneshot_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable);
- void oneshot_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const;
- bool oneshot_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const;
-
- /* MIX/BLEND NODES */
-
- void mix_node_set_amount(const StringName &p_node, float p_amount);
- float mix_node_get_amount(const StringName &p_node) const;
-
- void blend2_node_set_amount(const StringName &p_node, float p_amount);
- float blend2_node_get_amount(const StringName &p_node) const;
- void blend2_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable);
- void blend2_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const;
- bool blend2_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const;
-
- void blend3_node_set_amount(const StringName &p_node, float p_amount);
- float blend3_node_get_amount(const StringName &p_node) const;
-
- void blend4_node_set_amount(const StringName &p_node, const Point2 &p_amount);
- Point2 blend4_node_get_amount(const StringName &p_node) const;
-
- /* TIMESCALE/TIMESEEK NODES */
-
- void timescale_node_set_scale(const StringName &p_node, float p_scale);
- float timescale_node_get_scale(const StringName &p_node) const;
-
- void timeseek_node_seek(const StringName &p_node, float p_pos);
-
- /* TRANSITION NODE */
-
- void transition_node_set_input_count(const StringName &p_node, int p_inputs); // used for transition node
- int transition_node_get_input_count(const StringName &p_node) const;
- void transition_node_delete_input(const StringName &p_node, int p_input); // used for transition node
-
- void transition_node_set_input_auto_advance(const StringName &p_node, int p_input, bool p_auto_advance); // used for transition node
- bool transition_node_has_input_auto_advance(const StringName &p_node, int p_input) const;
-
- void transition_node_set_xfade_time(const StringName &p_node, float p_time); // used for transition node
- float transition_node_get_xfade_time(const StringName &p_node) const;
-
- void transition_node_set_current(const StringName &p_node, int p_current);
- int transition_node_get_current(const StringName &p_node) const;
-
- void node_set_position(const StringName &p_node, const Vector2 &p_pos); //for display
-
- /* GETS */
- Point2 node_get_position(const StringName &p_node) const; //for display
-
- NodeType node_get_type(const StringName &p_node) const;
-
- void get_node_list(List<StringName> *p_node_list) const;
- void remove_node(const StringName &p_node);
-
- Error connect_nodes(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input);
- bool are_nodes_connected(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) const;
- void disconnect_nodes(const StringName &p_node, int p_input);
-
- void set_base_path(const NodePath &p_path);
- NodePath get_base_path() const;
-
- void set_master_player(const NodePath &p_path);
- NodePath get_master_player() const;
-
- struct Connection {
-
- StringName src_node;
- StringName dst_node;
- int dst_input;
- };
-
- void get_connection_list(List<Connection> *p_connections) const;
-
- /* playback */
-
- void set_active(bool p_active);
- bool is_active() const;
-
- void reset();
-
- void recompute_caches();
-
- ConnectError get_last_error() const;
-
- void set_animation_process_mode(AnimationProcessMode p_mode);
- AnimationProcessMode get_animation_process_mode() const;
-
- void _set_process(bool p_process, bool p_force = false);
-
- void advance(float p_time);
-
- AnimationTreePlayer();
- ~AnimationTreePlayer();
-};
-
-VARIANT_ENUM_CAST(AnimationTreePlayer::NodeType);
-VARIANT_ENUM_CAST(AnimationTreePlayer::AnimationProcessMode);
-
-#endif // ANIMATION_TREE_PLAYER_H
diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp
index 32ceeb4dbf..fe062e0a20 100644
--- a/scene/animation/root_motion_view.cpp
+++ b/scene/animation/root_motion_view.cpp
@@ -79,7 +79,7 @@ void RootMotionView::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- VS::get_singleton()->immediate_set_material(immediate, SpatialMaterial::get_material_rid_for_2d(false, true, false, false, false));
+ VS::get_singleton()->immediate_set_material(immediate, StandardMaterial3D::get_material_rid_for_2d(false, true, false, false, false));
first = true;
}
diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp
index 46028a9ce2..518c243dd0 100644
--- a/scene/animation/skeleton_ik.cpp
+++ b/scene/animation/skeleton_ik.cpp
@@ -329,17 +329,6 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
}
}
-void FabrikInverseKinematic::reset(Task *p_task) {
- ChainItem *ci(&p_task->chain.chain_root);
- while (ci) {
- p_task->skeleton->set_bone_global_pose_override(ci->bone, Transform(), 0);
- if (!ci->children.empty())
- ci = &ci->children.write[0];
- else
- ci = NULL;
- }
-}
-
void SkeletonIK::_validate_property(PropertyInfo &property) const {
if (property.name == "root_bone" || property.name == "tip_bone") {
@@ -542,8 +531,6 @@ void SkeletonIK::start(bool p_one_time) {
void SkeletonIK::stop() {
set_process_internal(false);
- if (task)
- FabrikInverseKinematic::reset(task);
}
Transform SkeletonIK::_get_target_transform() {
diff --git a/scene/animation/skeleton_ik.h b/scene/animation/skeleton_ik.h
index 8fc8a58b99..02d5aba5ba 100644
--- a/scene/animation/skeleton_ik.h
+++ b/scene/animation/skeleton_ik.h
@@ -98,7 +98,7 @@ class FabrikInverseKinematic {
};
public:
- struct Task : public RID_Data {
+ struct Task {
RID self;
Skeleton *skeleton;
@@ -139,7 +139,6 @@ public:
static void set_goal(Task *p_task, const Transform &p_goal);
static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta);
static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position);
- static void reset(Task *p_task);
};
class SkeletonIK : public Node {
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 331a6c769c..a7f3794a05 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -1227,7 +1227,6 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
// Give it the object
ERR_FAIL_COND_V_MSG(p_object == NULL, false, "Invalid object provided to Tween.");
- ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(p_object), false, "Invalid object provided to Tween.");
data.id = p_object->get_instance_id();
// Validate the initial and final values
@@ -1328,7 +1327,6 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
// Check that the target object is valid
ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
// Duration cannot be negative
ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1387,7 +1385,6 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
// Check that the target object is valid
ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
// No negative durations allowed
ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1457,9 +1454,7 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
// Confirm the source and target objects are valid
ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
ERR_FAIL_COND_V(p_target == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false);
// No negative durations
ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1521,9 +1516,7 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
// Verify the source and target objects are valid
ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
ERR_FAIL_COND_V(p_target == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false);
// No negative durations
ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1587,9 +1580,7 @@ bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
// Verify both objects are valid
ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
ERR_FAIL_COND_V(p_initial == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false);
// No negative durations
ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1655,9 +1646,7 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
// Make sure the given objects are valid
ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
ERR_FAIL_COND_V(p_initial == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false);
// No negative durations
ERR_FAIL_COND_V(p_duration < 0, false);
diff --git a/scene/debugger/script_debugger_remote.cpp b/scene/debugger/script_debugger_remote.cpp
index 04d04ceb66..80972ba3d1 100644
--- a/scene/debugger/script_debugger_remote.cpp
+++ b/scene/debugger/script_debugger_remote.cpp
@@ -92,7 +92,7 @@ Error ScriptDebuggerRemote::connect_to_host(const String &p_host, uint16_t p_por
if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
- ERR_PRINTS("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()) + ".");
+ ERR_PRINT("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()) + ".");
return FAILED;
};
@@ -106,7 +106,7 @@ void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_
packet_peer_stream->put_var(p_name);
Variant var = p_variable;
- if (p_variable.get_type() == Variant::OBJECT && !ObjectDB::instance_validate(p_variable)) {
+ if (p_variable.get_type() == Variant::OBJECT && p_variable.get_validated_object() == nullptr) {
var = Variant();
}
@@ -805,14 +805,22 @@ void ScriptDebuggerRemote::_poll_events() {
profiling = false;
_send_profiling_data(false);
print_line("PROFILING END!");
+ } else if (command == "start_visual_profiling") {
+
+ visual_profiling = true;
+ VS::get_singleton()->set_frame_profiling_enabled(true);
+ } else if (command == "stop_visual_profiling") {
+
+ visual_profiling = false;
+ VS::get_singleton()->set_frame_profiling_enabled(false);
} else if (command == "start_network_profiling") {
+ network_profiling = true;
multiplayer->profiling_start();
- profiling_network = true;
} else if (command == "stop_network_profiling") {
+ network_profiling = false;
multiplayer->profiling_end();
- profiling_network = false;
} else if (command == "override_camera_2D:set") {
bool enforce = cmd[1];
@@ -985,6 +993,30 @@ void ScriptDebuggerRemote::idle_poll() {
packet_peer_stream->put_var(arr);
}
}
+ if (visual_profiling) {
+ Vector<VS::FrameProfileArea> profile_areas = VS::get_singleton()->get_frame_profile();
+ if (profile_areas.size()) {
+ PoolVector<String> area_names;
+ PoolVector<real_t> area_times;
+ area_names.resize(profile_areas.size());
+ area_times.resize(profile_areas.size() * 2);
+ {
+ PoolVector<String>::Write area_namesw = area_names.write();
+ PoolVector<real_t>::Write area_timesw = area_times.write();
+
+ for (int i = 0; i < profile_areas.size(); i++) {
+ area_namesw[i] = profile_areas[i].name;
+ area_timesw[i * 2 + 0] = profile_areas[i].cpu_msec;
+ area_timesw[i * 2 + 1] = profile_areas[i].gpu_msec;
+ }
+ }
+ packet_peer_stream->put_var("visual_profile");
+ packet_peer_stream->put_var(3);
+ packet_peer_stream->put_var(VS::get_singleton()->get_frame_profile_frame());
+ packet_peer_stream->put_var(area_names);
+ packet_peer_stream->put_var(area_times);
+ }
+ }
if (profiling) {
@@ -996,7 +1028,7 @@ void ScriptDebuggerRemote::idle_poll() {
}
}
- if (profiling_network) {
+ if (network_profiling) {
uint64_t pt = OS::get_singleton()->get_ticks_msec();
if (pt - last_net_bandwidth_time > 200) {
last_net_bandwidth_time = pt;
@@ -1229,7 +1261,8 @@ ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_fun
ScriptDebuggerRemote::ScriptDebuggerRemote() :
profiling(false),
- profiling_network(false),
+ visual_profiling(false),
+ network_profiling(false),
max_frame_functions(16),
skip_profile_frame(false),
reload_all_scripts(false),
diff --git a/scene/debugger/script_debugger_remote.h b/scene/debugger/script_debugger_remote.h
index 2c0dccdaf7..ae44bf9ca2 100644
--- a/scene/debugger/script_debugger_remote.h
+++ b/scene/debugger/script_debugger_remote.h
@@ -62,7 +62,8 @@ class ScriptDebuggerRemote : public ScriptDebugger {
float frame_time, idle_time, physics_time, physics_frame_time;
bool profiling;
- bool profiling_network;
+ bool visual_profiling;
+ bool network_profiling;
int max_frame_functions;
bool skip_profile_frame;
bool reload_all_scripts;
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index 24312af1b5..e0bfeac9f7 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -289,8 +289,6 @@ BoxContainer::BoxContainer(bool p_vertical) {
vertical = p_vertical;
align = ALIGN_BEGIN;
- //set_ignore_mouse(true);
- set_mouse_filter(MOUSE_FILTER_PASS);
}
void BoxContainer::_bind_methods() {
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 6f3d8c61cf..04ff11f20c 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -40,7 +40,7 @@ Size2 Button::get_minimum_size() const {
minsize.width = 0;
if (!expand_icon) {
- Ref<Texture> _icon;
+ Ref<Texture2D> _icon;
if (icon.is_null() && has_icon("icon"))
_icon = Control::get_icon("icon");
else
@@ -150,7 +150,7 @@ void Button::_notification(int p_what) {
}
Ref<Font> font = get_font("font");
- Ref<Texture> _icon;
+ Ref<Texture2D> _icon;
if (icon.is_null() && has_icon("icon"))
_icon = Control::get_icon("icon");
else
@@ -249,7 +249,7 @@ String Button::get_text() const {
return text;
}
-void Button::set_icon(const Ref<Texture> &p_icon) {
+void Button::set_icon(const Ref<Texture2D> &p_icon) {
if (icon == p_icon)
return;
@@ -259,7 +259,7 @@ void Button::set_icon(const Ref<Texture> &p_icon) {
minimum_size_changed();
}
-Ref<Texture> Button::get_icon() const {
+Ref<Texture2D> Button::get_icon() const {
return icon;
}
@@ -331,7 +331,7 @@ void Button::_bind_methods() {
BIND_ENUM_CONSTANT(ALIGN_RIGHT);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_button_icon", "get_button_icon");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text");
ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_align", "get_text_align");
diff --git a/scene/gui/button.h b/scene/gui/button.h
index e975dc52a5..3135b98578 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -48,7 +48,7 @@ private:
bool flat;
String text;
String xl_text;
- Ref<Texture> icon;
+ Ref<Texture2D> icon;
bool expand_icon;
bool clip_text;
TextAlign align;
@@ -65,8 +65,8 @@ public:
void set_text(const String &p_text);
String get_text() const;
- void set_icon(const Ref<Texture> &p_icon);
- Ref<Texture> get_icon() const;
+ void set_icon(const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_icon() const;
void set_expand_icon(bool p_expand_icon);
bool is_expand_icon() const;
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index 443121db32..89bd8ab0dd 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -33,10 +33,10 @@
#include "servers/visual_server.h"
Size2 CheckBox::get_icon_size() const {
- Ref<Texture> checked = Control::get_icon("checked");
- Ref<Texture> unchecked = Control::get_icon("unchecked");
- Ref<Texture> radio_checked = Control::get_icon("radio_checked");
- Ref<Texture> radio_unchecked = Control::get_icon("radio_unchecked");
+ Ref<Texture2D> checked = Control::get_icon("checked");
+ Ref<Texture2D> unchecked = Control::get_icon("unchecked");
+ Ref<Texture2D> radio_checked = Control::get_icon("radio_checked");
+ Ref<Texture2D> radio_unchecked = Control::get_icon("radio_unchecked");
Size2 tex_size = Size2(0, 0);
if (!checked.is_null())
@@ -73,8 +73,8 @@ void CheckBox::_notification(int p_what) {
RID ci = get_canvas_item();
- Ref<Texture> on = Control::get_icon(is_radio() ? "radio_checked" : "checked");
- Ref<Texture> off = Control::get_icon(is_radio() ? "radio_unchecked" : "unchecked");
+ Ref<Texture2D> on = Control::get_icon(is_radio() ? "radio_checked" : "checked");
+ Ref<Texture2D> off = Control::get_icon(is_radio() ? "radio_unchecked" : "unchecked");
Ref<StyleBox> sb = get_stylebox("normal");
Vector2 ofs;
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index 9d6df94cce..0b093ce850 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -35,8 +35,8 @@
Size2 CheckButton::get_icon_size() const {
- Ref<Texture> on = Control::get_icon(is_disabled() ? "on_disabled" : "on");
- Ref<Texture> off = Control::get_icon(is_disabled() ? "off_disabled" : "off");
+ Ref<Texture2D> on = Control::get_icon(is_disabled() ? "on_disabled" : "on");
+ Ref<Texture2D> off = Control::get_icon(is_disabled() ? "off_disabled" : "off");
Size2 tex_size = Size2(0, 0);
if (!on.is_null())
tex_size = Size2(on->get_width(), on->get_height());
@@ -68,8 +68,8 @@ void CheckButton::_notification(int p_what) {
RID ci = get_canvas_item();
- Ref<Texture> on = Control::get_icon(is_disabled() ? "on_disabled" : "on");
- Ref<Texture> off = Control::get_icon(is_disabled() ? "off_disabled" : "off");
+ Ref<Texture2D> on = Control::get_icon(is_disabled() ? "on_disabled" : "on");
+ Ref<Texture2D> off = Control::get_icon(is_disabled() ? "off_disabled" : "off");
Ref<StyleBox> sb = get_stylebox("normal");
Vector2 ofs;
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 01f4070883..2e903b6867 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -445,7 +445,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
c->draw_line(Point2(x, y), Point2(x, y), Color(1, 1, 1), 2);
} else if (p_which == 1) {
- Ref<Texture> hue = get_icon("color_hue", "ColorPicker");
+ Ref<Texture2D> hue = get_icon("color_hue", "ColorPicker");
c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
int y = c->get_size().y - c->get_size().y * (1.0 - h);
Color col = Color();
@@ -667,6 +667,7 @@ void ColorPicker::set_presets_visible(bool p_visible) {
presets_visible = p_visible;
preset_separator->set_visible(p_visible);
preset_container->set_visible(p_visible);
+ preset_container2->set_visible(p_visible);
}
bool ColorPicker::are_presets_visible() const {
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index b07fec90c2..b411f563b8 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -197,4 +197,6 @@ void Container::_bind_methods() {
Container::Container() {
pending_sort = false;
+ // All containers should let mouse events pass by default.
+ set_mouse_filter(MOUSE_FILTER_PASS);
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index ae48a1356e..b7bc2f9c9e 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -358,7 +358,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
if (data.icon_override.has(E->get()))
hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
- p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture", hint));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", hint));
}
}
{
@@ -462,11 +462,6 @@ void Control::_update_canvas_item_transform() {
Transform2D xform = _get_internal_transform();
xform[2] += get_position();
- // We use a little workaround to avoid flickering when moving the pivot with _edit_set_pivot()
- if (is_inside_tree() && Math::abs(Math::sin(data.rotation * 4.0f)) < 0.00001f && get_viewport()->is_snap_controls_to_pixels_enabled()) {
- xform[2] = xform[2].round();
- }
-
VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), xform);
}
@@ -710,12 +705,12 @@ void Control::set_drag_forwarding(Control *p_target) {
if (p_target)
data.drag_owner = p_target->get_instance_id();
else
- data.drag_owner = 0;
+ data.drag_owner = ObjectID();
}
Variant Control::get_drag_data(const Point2 &p_point) {
- if (data.drag_owner) {
+ if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
Control *c = Object::cast_to<Control>(obj);
@@ -737,7 +732,7 @@ Variant Control::get_drag_data(const Point2 &p_point) {
bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
- if (data.drag_owner) {
+ if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
Control *c = Object::cast_to<Control>(obj);
@@ -758,7 +753,7 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const
}
void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
- if (data.drag_owner) {
+ if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
Control *c = Object::cast_to<Control>(obj);
@@ -818,11 +813,11 @@ Size2 Control::get_minimum_size() const {
return Size2();
}
-Ref<Texture> Control::get_icon(const StringName &p_name, const StringName &p_type) const {
+Ref<Texture2D> Control::get_icon(const StringName &p_name, const StringName &p_type) const {
if (p_type == StringName() || p_type == get_class_name()) {
- const Ref<Texture> *tex = data.icon_override.getptr(p_name);
+ const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
if (tex)
return *tex;
}
@@ -1068,7 +1063,7 @@ int Control::get_constant(const StringName &p_name, const StringName &p_type) co
bool Control::has_icon_override(const StringName &p_name) const {
- const Ref<Texture> *tex = data.icon_override.getptr(p_name);
+ const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
return tex != NULL;
}
@@ -1885,7 +1880,7 @@ Rect2 Control::get_anchorable_rect() const {
return Rect2(Point2(), get_size());
}
-void Control::add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon) {
+void Control::add_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) {
if (data.icon_override.has(p_name)) {
data.icon_override[p_name]->disconnect("changed", this, "_override_changed");
@@ -2229,7 +2224,7 @@ void Control::_modal_stack_remove() {
get_viewport()->_gui_remove_from_modal_stack(element, data.modal_prev_focus_owner);
- data.modal_prev_focus_owner = 0;
+ data.modal_prev_focus_owner = ObjectID();
}
void Control::_propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool p_assign) {
@@ -3115,7 +3110,7 @@ Control::Control() {
data.rotation = 0;
data.parent_canvas_item = NULL;
data.scale = Vector2(1, 1);
- data.drag_owner = 0;
+
data.modal_frame = 0;
data.block_minimum_size_adjust = false;
data.disable_visibility_clip = false;
@@ -3130,7 +3125,6 @@ Control::Control() {
data.margin[i] = 0;
}
data.focus_mode = FOCUS_NONE;
- data.modal_prev_focus_owner = 0;
}
Control::~Control() {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 357858beb6..67e8ed0d27 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -198,7 +198,7 @@ private:
NodePath focus_next;
NodePath focus_prev;
- HashMap<StringName, Ref<Texture> > icon_override;
+ HashMap<StringName, Ref<Texture2D> > icon_override;
HashMap<StringName, Ref<Shader> > shader_override;
HashMap<StringName, Ref<StyleBox> > style_override;
HashMap<StringName, Ref<Font> > font_override;
@@ -420,14 +420,14 @@ public:
/* SKINNING */
- void add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon);
+ void add_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon);
void add_shader_override(const StringName &p_name, const Ref<Shader> &p_shader);
void add_style_override(const StringName &p_name, const Ref<StyleBox> &p_style);
void add_font_override(const StringName &p_name, const Ref<Font> &p_font);
void add_color_override(const StringName &p_name, const Color &p_color);
void add_constant_override(const StringName &p_name, int p_constant);
- Ref<Texture> get_icon(const StringName &p_name, const StringName &p_type = StringName()) const;
+ Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_type = StringName()) const;
Ref<Shader> get_shader(const StringName &p_name, const StringName &p_type = StringName()) const;
Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_type = StringName()) const;
Ref<Font> get_font(const StringName &p_name, const StringName &p_type = StringName()) const;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 2cc9c1a53a..6e7491e7b4 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -424,7 +424,7 @@ void FileDialog::update_file_list() {
dir_access->list_dir_begin();
TreeItem *root = tree->create_item();
- Ref<Texture> folder = get_icon("folder");
+ Ref<Texture2D> folder = get_icon("folder");
const Color folder_color = get_color("folder_icon_modulate");
List<String> files;
List<String> dirs;
@@ -518,7 +518,7 @@ void FileDialog::update_file_list() {
if (get_icon_func) {
- Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
+ Ref<Texture2D> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
ti->set_icon(0, icon);
}
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index d9ab00e0f2..9f6650c276 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -58,7 +58,7 @@ public:
MODE_SAVE_FILE
};
- typedef Ref<Texture> (*GetIconFunc)(const String &);
+ typedef Ref<Texture2D> (*GetIconFunc)(const String &);
typedef void (*RegisterFunc)(FileDialog *);
static GetIconFunc get_icon_func;
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 46c59f42fc..80431cefe0 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -54,7 +54,6 @@ GradientEdit::GradientEdit() {
checker = Ref<ImageTexture>(memnew(ImageTexture));
Ref<Image> img = memnew(Image(checker_bg_png));
- checker->create_from_image(img, ImageTexture::FLAG_REPEAT);
}
int GradientEdit::_get_point_from_pos(int x) {
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 00ce57eb04..c6a5e21ff8 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -357,7 +357,7 @@ void GraphEdit::_notification(int p_what) {
bool GraphEdit::_filter_input(const Point2 &p_point) {
- Ref<Texture> port = get_icon("port", "GraphNode");
+ Ref<Texture2D> port = get_icon("port", "GraphNode");
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -389,7 +389,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
- Ref<Texture> port = get_icon("port", "GraphNode");
+ Ref<Texture2D> port = get_icon("port", "GraphNode");
Vector2 mpos(mb->get_position().x, mb->get_position().y);
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -501,7 +501,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_target = false;
top_layer->update();
- Ref<Texture> port = get_icon("port", "GraphNode");
+ Ref<Texture2D> port = get_icon("port", "GraphNode");
Vector2 mpos = mm->get_position();
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -689,9 +689,9 @@ void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const
colors.push_back(p_to_color);
#ifdef TOOLS_ENABLED
- p_where->draw_polyline_colors(points, colors, Math::floor(2 * EDSCALE), true);
+ p_where->draw_polyline_colors(points, colors, Math::floor(2 * EDSCALE));
#else
- p_where->draw_polyline_colors(points, colors, 2, true);
+ p_where->draw_polyline_colors(points, colors, 2);
#endif
}
@@ -1342,7 +1342,6 @@ GraphEdit::GraphEdit() {
top_layer->set_mouse_filter(MOUSE_FILTER_PASS);
top_layer->set_anchors_and_margins_preset(Control::PRESET_WIDE);
top_layer->connect("draw", this, "_top_layer_draw");
- top_layer->set_mouse_filter(MOUSE_FILTER_PASS);
top_layer->connect("gui_input", this, "_top_layer_input");
connections_layer = memnew(Control);
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 7b1bfdfdb5..82e890395a 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -170,7 +170,7 @@ bool GraphNode::has_point(const Point2 &p_point) const {
if (comment) {
Ref<StyleBox> comment = get_stylebox("comment");
- Ref<Texture> resizer = get_icon("resizer");
+ Ref<Texture2D> resizer = get_icon("resizer");
if (Rect2(get_size() - resizer->get_size(), resizer->get_size()).has_point(p_point)) {
return true;
@@ -204,9 +204,9 @@ void GraphNode::_notification(int p_what) {
//sb=sb->duplicate();
//sb->call("set_modulate",modulate);
- Ref<Texture> port = get_icon("port");
- Ref<Texture> close = get_icon("close");
- Ref<Texture> resizer = get_icon("resizer");
+ Ref<Texture2D> port = get_icon("port");
+ Ref<Texture2D> close = get_icon("close");
+ Ref<Texture2D> resizer = get_icon("resizer");
int close_offset = get_constant("close_offset");
int close_h_offset = get_constant("close_h_offset");
Color close_color = get_color("close_color");
@@ -259,14 +259,14 @@ void GraphNode::_notification(int p_what) {
const Slot &s = slot_info[E->key()];
//left
if (s.enable_left) {
- Ref<Texture> p = port;
+ Ref<Texture2D> p = port;
if (s.custom_slot_left.is_valid()) {
p = s.custom_slot_left;
}
p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E->key()]), s.color_left);
}
if (s.enable_right) {
- Ref<Texture> p = port;
+ Ref<Texture2D> p = port;
if (s.custom_slot_right.is_valid()) {
p = s.custom_slot_right;
}
@@ -291,7 +291,7 @@ void GraphNode::_notification(int p_what) {
}
}
-void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture> &p_custom_left, const Ref<Texture> &p_custom_right) {
+void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right) {
ERR_FAIL_COND(p_idx < 0);
@@ -379,7 +379,7 @@ Size2 GraphNode::get_minimum_size() const {
Size2 minsize;
minsize.x = title_font->get_string_size(title).x;
if (show_close) {
- Ref<Texture> close = get_icon("close");
+ Ref<Texture2D> close = get_icon("close");
minsize.x += sep + close->get_width();
}
@@ -606,7 +606,7 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
return;
}
- Ref<Texture> resizer = get_icon("resizer");
+ Ref<Texture2D> resizer = get_icon("resizer");
if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) {
@@ -674,7 +674,7 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_title"), &GraphNode::get_title);
ClassDB::bind_method(D_METHOD("_gui_input"), &GraphNode::_gui_input);
- ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right"), &GraphNode::set_slot, DEFVAL(Ref<Texture>()), DEFVAL(Ref<Texture>()));
+ ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right"), &GraphNode::set_slot, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("clear_slot", "idx"), &GraphNode::clear_slot);
ClassDB::bind_method(D_METHOD("clear_all_slots"), &GraphNode::clear_all_slots);
ClassDB::bind_method(D_METHOD("is_slot_enabled_left", "idx"), &GraphNode::is_slot_enabled_left);
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index e1a81b5f3d..a3eb8ed152 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -52,8 +52,8 @@ private:
bool enable_right;
int type_right;
Color color_right;
- Ref<Texture> custom_slot_left;
- Ref<Texture> custom_slot_right;
+ Ref<Texture2D> custom_slot_left;
+ Ref<Texture2D> custom_slot_right;
Slot() {
enable_left = false;
@@ -112,7 +112,7 @@ protected:
public:
bool has_point(const Point2 &p_point) const;
- void set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture> &p_custom_left = Ref<Texture>(), const Ref<Texture> &p_custom_right = Ref<Texture>());
+ void set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left = Ref<Texture2D>(), const Ref<Texture2D> &p_custom_right = Ref<Texture2D>());
void clear_slot(int p_idx);
void clear_all_slots();
bool is_slot_enabled_left(int p_idx) const;
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index 04aed532d4..0028093a95 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -247,7 +247,5 @@ Size2 GridContainer::get_minimum_size() const {
}
GridContainer::GridContainer() {
-
- set_mouse_filter(MOUSE_FILTER_PASS);
columns = 1;
}
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 526950dbb3..cf798f36e4 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -32,7 +32,7 @@
#include "core/os/os.h"
#include "core/project_settings.h"
-void ItemList::add_item(const String &p_item, const Ref<Texture> &p_texture, bool p_selectable) {
+void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) {
Item item;
item.icon = p_texture;
@@ -51,7 +51,7 @@ void ItemList::add_item(const String &p_item, const Ref<Texture> &p_texture, boo
shape_changed = true;
}
-void ItemList::add_icon_item(const Ref<Texture> &p_item, bool p_selectable) {
+void ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) {
Item item;
item.icon = p_item;
@@ -110,7 +110,7 @@ String ItemList::get_item_tooltip(int p_idx) const {
return items[p_idx].tooltip;
}
-void ItemList::set_item_icon(int p_idx, const Ref<Texture> &p_icon) {
+void ItemList::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
@@ -119,9 +119,9 @@ void ItemList::set_item_icon(int p_idx, const Ref<Texture> &p_icon) {
shape_changed = true;
}
-Ref<Texture> ItemList::get_item_icon(int p_idx) const {
+Ref<Texture2D> ItemList::get_item_icon(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>());
return items[p_idx].icon;
}
@@ -201,7 +201,7 @@ Color ItemList::get_item_custom_fg_color(int p_idx) const {
return items[p_idx].custom_fg;
}
-void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon) {
+void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture2D> &p_tag_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
@@ -209,9 +209,9 @@ void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon) {
update();
shape_changed = true;
}
-Ref<Texture> ItemList::get_item_tag_icon(int p_idx) const {
+Ref<Texture2D> ItemList::get_item_tag_icon(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>());
return items[p_idx].tag_icon;
}
@@ -1398,7 +1398,7 @@ void ItemList::_set_items(const Array &p_items) {
for (int i = 0; i < p_items.size(); i += 3) {
String text = p_items[i + 0];
- Ref<Texture> icon = p_items[i + 1];
+ Ref<Texture2D> icon = p_items[i + 1];
bool disabled = p_items[i + 2];
int idx = get_item_count();
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index d9b510c762..da9851dd7d 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -52,11 +52,11 @@ public:
private:
struct Item {
- Ref<Texture> icon;
+ Ref<Texture2D> icon;
bool icon_transposed;
Rect2i icon_region;
Color icon_modulate;
- Ref<Texture> tag_icon;
+ Ref<Texture2D> tag_icon;
String text;
bool selectable;
bool selected;
@@ -125,14 +125,14 @@ protected:
static void _bind_methods();
public:
- void add_item(const String &p_item, const Ref<Texture> &p_texture = Ref<Texture>(), bool p_selectable = true);
- void add_icon_item(const Ref<Texture> &p_item, bool p_selectable = true);
+ void add_item(const String &p_item, const Ref<Texture2D> &p_texture = Ref<Texture2D>(), bool p_selectable = true);
+ void add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable = true);
void set_item_text(int p_idx, const String &p_text);
String get_item_text(int p_idx) const;
- void set_item_icon(int p_idx, const Ref<Texture> &p_icon);
- Ref<Texture> get_item_icon(int p_idx) const;
+ void set_item_icon(int p_idx, const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_item_icon(int p_idx) const;
void set_item_icon_transposed(int p_idx, const bool transposed);
bool is_item_icon_transposed(int p_idx) const;
@@ -152,8 +152,8 @@ public:
void set_item_metadata(int p_idx, const Variant &p_metadata);
Variant get_item_metadata(int p_idx) const;
- void set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon);
- Ref<Texture> get_item_tag_icon(int p_idx) const;
+ void set_item_tag_icon(int p_idx, const Ref<Texture2D> &p_tag_icon);
+ Ref<Texture2D> get_item_tag_icon(int p_idx) const;
void set_item_tooltip_enabled(int p_idx, const bool p_enabled);
bool is_item_tooltip_enabled(int p_idx) const;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 7afc3b0d00..3f4fd37c08 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -184,6 +184,12 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
case KEY_H: {
remap_key = KEY_BACKSPACE;
} break;
+ case KEY_A: {
+ remap_key = KEY_HOME;
+ } break;
+ case KEY_E: {
+ remap_key = KEY_END;
+ } break;
}
if (remap_key != KEY_UNKNOWN) {
@@ -240,15 +246,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
deselect();
text = text.substr(cursor_pos, text.length() - cursor_pos);
-
- Ref<Font> font = get_font("font");
-
- cached_width = 0;
- if (font != NULL) {
- for (int i = 0; i < text.length(); i++)
- cached_width += font->get_char_size(text[i]).width;
- }
-
+ update_cached_width();
set_cursor_position(0);
_text_changed();
}
@@ -636,7 +634,7 @@ bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const {
if (!clear_button_enabled || !has_point(p_pos)) {
return false;
}
- Ref<Texture> icon = Control::get_icon("clear");
+ Ref<Texture2D> icon = Control::get_icon("clear");
int x_ofs = get_stylebox("normal")->get_offset().x;
return p_pos.x > get_size().width - icon->get_width() - x_ofs;
}
@@ -750,7 +748,7 @@ void LineEdit::_notification(int p_what) {
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
- Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon;
+ Ref<Texture2D> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon;
Color color_icon(1, 1, 1, !is_editable() ? .5 * .9 : .9);
if (display_clear_icon) {
if (clear_button_status.press_attempt && clear_button_status.pressing_inside) {
@@ -1311,7 +1309,7 @@ void LineEdit::set_cursor_position(int p_pos) {
int window_width = get_size().width - style->get_minimum_size().width;
bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
- Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon;
+ Ref<Texture2D> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon;
window_width -= r_icon->get_width();
}
@@ -1358,18 +1356,10 @@ void LineEdit::set_window_pos(int p_pos) {
void LineEdit::append_at_cursor(String p_text) {
if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) {
-
- Ref<Font> font = get_font("font");
- if (font != NULL) {
- for (int i = 0; i < p_text.length(); i++)
- cached_width += font->get_char_size(p_text[i]).width;
- } else {
- cached_width = 0;
- }
-
String pre = text.substr(0, cursor_pos);
String post = text.substr(cursor_pos, text.length() - cursor_pos);
text = pre + p_text + post;
+ update_cached_width();
set_cursor_position(cursor_pos + p_text.length());
} else {
emit_signal("text_change_rejected");
@@ -1499,6 +1489,7 @@ bool LineEdit::is_editable() const {
void LineEdit::set_secret(bool p_secret) {
pass = p_secret;
+ update_cached_width();
update();
}
@@ -1514,6 +1505,7 @@ void LineEdit::set_secret_character(const String &p_string) {
ERR_FAIL_COND_MSG(p_string.length() != 1, "Secret character must be exactly one character long (" + itos(p_string.length()) + " characters given).");
secret_character = p_string;
+ update_cached_width();
update();
}
@@ -1658,7 +1650,7 @@ bool LineEdit::is_selecting_enabled() const {
return selecting_enabled;
}
-void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
+void LineEdit::set_right_icon(const Ref<Texture2D> &p_icon) {
if (right_icon == p_icon) {
return;
}
@@ -1667,7 +1659,7 @@ void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
update();
}
-Ref<Texture> LineEdit::get_right_icon() {
+Ref<Texture2D> LineEdit::get_right_icon() {
return right_icon;
}
@@ -1685,6 +1677,17 @@ void LineEdit::_emit_text_change() {
text_changed_dirty = false;
}
+void LineEdit::update_cached_width() {
+ Ref<Font> font = get_font("font");
+ cached_width = 0;
+ if (font != NULL) {
+ String text = get_text();
+ for (int i = 0; i < text.length(); i++) {
+ cached_width += font->get_char_size(pass ? secret_character[0] : text[i]).width;
+ }
+ }
+}
+
void LineEdit::update_placeholder_width() {
if ((max_length <= 0) || (placeholder_translated.length() <= max_length)) {
Ref<Font> font = get_font("font");
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index cf597d11b6..938974453a 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -91,7 +91,7 @@ private:
bool shortcut_keys_enabled;
- Ref<Texture> right_icon;
+ Ref<Texture2D> right_icon;
struct Selection {
@@ -132,6 +132,7 @@ private:
void _emit_text_change();
bool expand_to_text_length;
+ void update_cached_width();
void update_placeholder_width();
bool caret_blink_enabled;
@@ -231,8 +232,8 @@ public:
void set_selecting_enabled(bool p_enabled);
bool is_selecting_enabled() const;
- void set_right_icon(const Ref<Texture> &p_icon);
- Ref<Texture> get_right_icon();
+ void set_right_icon(const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_right_icon();
virtual bool is_text_field() const;
LineEdit();
diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp
index 945d1850d7..0ef1f53006 100644
--- a/scene/gui/nine_patch_rect.cpp
+++ b/scene/gui/nine_patch_rect.cpp
@@ -70,7 +70,7 @@ void NinePatchRect::_bind_methods() {
ADD_SIGNAL(MethodInfo("texture_changed"));
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
@@ -88,7 +88,7 @@ void NinePatchRect::_bind_methods() {
BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_TILE_FIT);
}
-void NinePatchRect::set_texture(const Ref<Texture> &p_tex) {
+void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) {
if (texture == p_tex)
return;
@@ -103,7 +103,7 @@ void NinePatchRect::set_texture(const Ref<Texture> &p_tex) {
_change_notify("texture");
}
-Ref<Texture> NinePatchRect::get_texture() const {
+Ref<Texture2D> NinePatchRect::get_texture() const {
return texture;
}
diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h
index 3329c0a64c..0ef7f6b299 100644
--- a/scene/gui/nine_patch_rect.h
+++ b/scene/gui/nine_patch_rect.h
@@ -47,7 +47,7 @@ public:
bool draw_center;
int margin[4];
Rect2 region_rect;
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
AxisStretchMode axis_h, axis_v;
@@ -57,8 +57,8 @@ protected:
static void _bind_methods();
public:
- void set_texture(const Ref<Texture> &p_tex);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_tex);
+ Ref<Texture2D> get_texture() const;
void set_patch_margin(Margin p_margin, int p_size);
int get_patch_margin(Margin p_margin) const;
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 3f46afa8e8..6f656025e6 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -58,7 +58,7 @@ void OptionButton::_notification(int p_what) {
return;
RID ci = get_canvas_item();
- Ref<Texture> arrow = Control::get_icon("arrow");
+ Ref<Texture2D> arrow = Control::get_icon("arrow");
Color clr = Color(1, 1, 1);
if (get_constant("modulate_arrow")) {
switch (get_draw_mode()) {
@@ -114,7 +114,7 @@ void OptionButton::pressed() {
popup->popup();
}
-void OptionButton::add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id) {
+void OptionButton::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id) {
popup->add_icon_radio_check_item(p_icon, p_label, p_id);
if (popup->get_item_count() == 1)
@@ -134,7 +134,7 @@ void OptionButton::set_item_text(int p_idx, const String &p_text) {
if (current == p_idx)
set_text(p_text);
}
-void OptionButton::set_item_icon(int p_idx, const Ref<Texture> &p_icon) {
+void OptionButton::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
popup->set_item_icon(p_idx, p_icon);
@@ -161,7 +161,7 @@ String OptionButton::get_item_text(int p_idx) const {
return popup->get_item_text(p_idx);
}
-Ref<Texture> OptionButton::get_item_icon(int p_idx) const {
+Ref<Texture2D> OptionButton::get_item_icon(int p_idx) const {
return popup->get_item_icon(p_idx);
}
@@ -289,7 +289,7 @@ void OptionButton::_set_items(const Array &p_items) {
for (int i = 0; i < p_items.size(); i += 5) {
String text = p_items[i + 0];
- Ref<Texture> icon = p_items[i + 1];
+ Ref<Texture2D> icon = p_items[i + 1];
bool disabled = p_items[i + 2];
int id = p_items[i + 3];
Variant meta = p_items[i + 4];
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 04bd28fe28..9658e1fea8 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -57,17 +57,17 @@ protected:
static void _bind_methods();
public:
- void add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1);
+ void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1);
void add_item(const String &p_label, int p_id = -1);
void set_item_text(int p_idx, const String &p_text);
- void set_item_icon(int p_idx, const Ref<Texture> &p_icon);
+ void set_item_icon(int p_idx, const Ref<Texture2D> &p_icon);
void set_item_id(int p_idx, int p_id);
void set_item_metadata(int p_idx, const Variant &p_metadata);
void set_item_disabled(int p_idx, bool p_disabled);
String get_item_text(int p_idx) const;
- Ref<Texture> get_item_icon(int p_idx) const;
+ Ref<Texture2D> get_item_icon(int p_idx) const;
int get_item_id(int p_idx) const;
int get_item_index(int p_id) const;
Variant get_item_metadata(int p_idx) const;
diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp
index aa1a381934..0356607071 100644
--- a/scene/gui/panel.cpp
+++ b/scene/gui/panel.cpp
@@ -42,7 +42,7 @@ void Panel::_notification(int p_what) {
}
Panel::Panel() {
-
+ // Has visible stylebox, so stop by default.
set_mouse_filter(MOUSE_FILTER_STOP);
}
diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp
index 74663c33e3..6cf23b8a32 100644
--- a/scene/gui/panel_container.cpp
+++ b/scene/gui/panel_container.cpp
@@ -103,4 +103,6 @@ void PanelContainer::_notification(int p_what) {
}
PanelContainer::PanelContainer() {
+ // Has visible stylebox, so stop by default.
+ set_mouse_filter(MOUSE_FILTER_STOP);
}
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 87f17838cf..b494506c6c 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -467,9 +467,9 @@ void PopupMenu::_notification(int p_what) {
Ref<StyleBox> hover = get_stylebox("hover");
Ref<Font> font = get_font("font");
// In Item::checkable_type enum order (less the non-checkable member)
- Ref<Texture> check[] = { get_icon("checked"), get_icon("radio_checked") };
- Ref<Texture> uncheck[] = { get_icon("unchecked"), get_icon("radio_unchecked") };
- Ref<Texture> submenu = get_icon("submenu");
+ Ref<Texture2D> check[] = { get_icon("checked"), get_icon("radio_checked") };
+ Ref<Texture2D> uncheck[] = { get_icon("unchecked"), get_icon("radio_unchecked") };
+ Ref<Texture2D> submenu = get_icon("submenu");
Ref<StyleBox> separator = get_stylebox("separator");
Ref<StyleBox> labeled_separator_left = get_stylebox("labeled_separator_left");
Ref<StyleBox> labeled_separator_right = get_stylebox("labeled_separator_right");
@@ -549,7 +549,7 @@ void PopupMenu::_notification(int p_what) {
Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1);
if (items[i].checkable_type) {
- Texture *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr();
+ Texture2D *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr();
icon->draw(ci, item_ofs + Point2(0, Math::floor((h - icon->get_height()) / 2.0)), icon_color);
}
@@ -651,7 +651,7 @@ void PopupMenu::add_item(const String &p_label, int p_id, uint32_t p_accel) {
minimum_size_changed();
}
-void PopupMenu::add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
+void PopupMenu::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
@@ -671,7 +671,7 @@ void PopupMenu::add_check_item(const String &p_label, int p_id, uint32_t p_accel
minimum_size_changed();
}
-void PopupMenu::add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
+void PopupMenu::add_icon_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
@@ -692,7 +692,7 @@ void PopupMenu::add_radio_check_item(const String &p_label, int p_id, uint32_t p
minimum_size_changed();
}
-void PopupMenu::add_icon_radio_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
+void PopupMenu::add_icon_radio_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
@@ -732,7 +732,7 @@ void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_g
minimum_size_changed();
}
-void PopupMenu::add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
@@ -752,7 +752,7 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bo
minimum_size_changed();
}
-void PopupMenu::add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
@@ -773,7 +773,7 @@ void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_
minimum_size_changed();
}
-void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
@@ -810,7 +810,7 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) {
update();
minimum_size_changed();
}
-void PopupMenu::set_item_icon(int p_idx, const Ref<Texture> &p_icon) {
+void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon = p_icon;
@@ -893,9 +893,9 @@ int PopupMenu::get_item_idx_from_text(const String &text) const {
return -1;
}
-Ref<Texture> PopupMenu::get_item_icon(int p_idx) const {
+Ref<Texture2D> PopupMenu::get_item_icon(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>());
return items[p_idx].icon;
}
@@ -1257,7 +1257,7 @@ void PopupMenu::_set_items(const Array &p_items) {
for (int i = 0; i < p_items.size(); i += 10) {
String text = p_items[i + 0];
- Ref<Texture> icon = p_items[i + 1];
+ Ref<Texture2D> icon = p_items[i + 1];
// For compatibility, use false/true for no/checkbox and integers for other values
bool checkable = p_items[i + 2];
bool radio_checkable = (int)p_items[i + 2] == Item::CHECKABLE_TYPE_RADIO_BUTTON;
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index f77ede0a8b..a3a858cfde 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -38,7 +38,7 @@ class PopupMenu : public Popup {
GDCLASS(PopupMenu, Popup);
struct Item {
- Ref<Texture> icon;
+ Ref<Texture2D> icon;
String text;
String xl_text;
bool checked;
@@ -121,25 +121,25 @@ protected:
public:
void add_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0);
- void add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0);
+ void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0);
void add_check_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0);
- void add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0);
+ void add_icon_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0);
void add_radio_check_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0);
- void add_icon_radio_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0);
+ void add_icon_radio_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0);
void add_multistate_item(const String &p_label, int p_max_states, int p_default_state = 0, int p_id = -1, uint32_t p_accel = 0);
void add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_radio_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_submenu_item(const String &p_label, const String &p_submenu, int p_id = -1);
void set_item_text(int p_idx, const String &p_text);
- void set_item_icon(int p_idx, const Ref<Texture> &p_icon);
+ void set_item_icon(int p_idx, const Ref<Texture2D> &p_icon);
void set_item_checked(int p_idx, bool p_checked);
void set_item_id(int p_idx, int p_id);
void set_item_accelerator(int p_idx, uint32_t p_accel);
@@ -160,7 +160,7 @@ public:
String get_item_text(int p_idx) const;
int get_item_idx_from_text(const String &text) const;
- Ref<Texture> get_item_icon(int p_idx) const;
+ Ref<Texture2D> get_item_icon(int p_idx) const;
bool is_item_checked(int p_idx) const;
int get_item_id(int p_idx) const;
int get_item_index(int p_id) const;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 6c2928c65c..6d8be469bd 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -33,8 +33,13 @@
#include "core/math/math_defs.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
-#include "modules/regex/regex.h"
#include "scene/scene_string_names.h"
+
+#include "modules/modules_enabled.gen.h"
+#ifdef MODULE_REGEX_ENABLED
+#include "modules/regex/regex.h"
+#endif
+
#ifdef TOOLS_ENABLED
#include "editor/editor_scale.h"
#endif
@@ -199,6 +204,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int line_ascent = cfont->get_ascent();
int line_descent = cfont->get_descent();
+ int backtrack = 0; // for dynamic hidden content.
+
int nonblank_line_count = 0; //number of nonblank lines as counted during PROCESS_DRAW
Variant meta;
@@ -209,6 +216,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
{ \
if (p_mode != PROCESS_CACHE) { \
line++; \
+ backtrack = 0; \
if (!line_is_blank) { \
nonblank_line_count++; \
} \
@@ -258,7 +266,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \
l.minimum_width = MAX(l.minimum_width, m_width); \
} \
- if (wofs + m_width > p_width) { \
+ if (wofs - backtrack + m_width > p_width) { \
line_wrapped = true; \
if (p_mode == PROCESS_CACHE) { \
if (spaces > 0) \
@@ -385,6 +393,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int fw = 0;
lh = 0;
+
if (p_mode != PROCESS_CACHE) {
lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1;
@@ -427,13 +436,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
{
- int ofs = 0;
+ int ofs = 0 - backtrack;
for (int i = 0; i < end; i++) {
int pofs = wofs + ofs;
if (p_mode == PROCESS_POINTER && r_click_char && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) {
- //int o = (wofs+w)-p_click_pos.x;
int cw = font->get_char_size(c[i], c[i + 1]).x;
@@ -476,7 +484,10 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
bool visible = visible_characters < 0 || ((p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - line_descent - line_ascent, line_ascent + line_descent)) &&
faded_visibility > 0.0f);
+ const bool previously_visible = visible;
+
for (int j = 0; j < fx_stack.size(); j++) {
+
ItemFX *item_fx = fx_stack[j];
if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) {
@@ -570,6 +581,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} else {
cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent) + fx_offset, fx_char, c[i + 1], fx_color);
}
+ } else if (previously_visible) {
+ backtrack += font->get_char_size(fx_char, c[i + 1]).x;
}
p_char_count++;
@@ -643,6 +656,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
case ITEM_NEWLINE: {
lh = 0;
+
if (p_mode != PROCESS_CACHE) {
lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
line_is_blank = true;
@@ -1643,7 +1657,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
}
}
-void RichTextLabel::add_image(const Ref<Texture> &p_image, const int p_width, const int p_height) {
+void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height) {
if (current->type == ITEM_TABLE)
return;
@@ -2199,7 +2213,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
- Ref<Texture> texture = ResourceLoader::load(image, "Texture");
+ Ref<Texture2D> texture = ResourceLoader::load(image, "Texture2D");
if (texture.is_valid())
add_image(texture);
@@ -2225,7 +2239,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
- Ref<Texture> texture = ResourceLoader::load(image, "Texture");
+ Ref<Texture2D> texture = ResourceLoader::load(image, "Texture");
if (texture.is_valid())
add_image(texture, width, height);
@@ -2650,7 +2664,7 @@ void RichTextLabel::set_effects(const Vector<Variant> &effects) {
Vector<Variant> RichTextLabel::get_effects() {
Vector<Variant> r;
for (int i = 0; i < custom_effects.size(); i++) {
- r.push_back(custom_effects[i].get_ref_ptr());
+ r.push_back(custom_effects[i]);
}
return r;
}
@@ -2864,6 +2878,7 @@ Dictionary RichTextLabel::parse_expressions_for_values(Vector<String> p_expressi
Vector<String> values = parts[1].split(",", false);
+#ifdef MODULE_REGEX_ENABLED
RegEx color = RegEx();
color.compile("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
RegEx nodepath = RegEx();
@@ -2897,6 +2912,7 @@ Dictionary RichTextLabel::parse_expressions_for_values(Vector<String> p_expressi
a.append(values[j]);
}
}
+#endif
if (values.size() > 1) {
d[key] = a;
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 61ac0bd86c..409aec0ca6 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -147,7 +147,7 @@ private:
};
struct ItemImage : public Item {
- Ref<Texture> image;
+ Ref<Texture2D> image;
Size2 size;
ItemImage() { type = ITEM_IMAGE; }
};
@@ -407,7 +407,7 @@ protected:
public:
String get_text();
void add_text(const String &p_text);
- void add_image(const Ref<Texture> &p_image, const int p_width = 0, const int p_height = 0);
+ void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0);
void add_newline();
bool remove_line(const int p_line);
void push_font(const Ref<Font> &p_font);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 45fa212886..8e6d0843a7 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -71,8 +71,8 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
if (b->is_pressed()) {
double ofs = orientation == VERTICAL ? b->get_position().y : b->get_position().x;
- Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
+ Ref<Texture2D> incr = get_icon("increment");
double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width();
@@ -148,7 +148,7 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
if (drag.active) {
double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x;
- Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture2D> decr = get_icon("decrement");
double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
ofs -= decr_size;
@@ -159,8 +159,8 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
} else {
double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x;
- Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
+ Ref<Texture2D> incr = get_icon("increment");
double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width();
@@ -233,8 +233,8 @@ void ScrollBar::_notification(int p_what) {
RID ci = get_canvas_item();
- Ref<Texture> decr = highlight == HIGHLIGHT_DECR ? get_icon("decrement_highlight") : get_icon("decrement");
- Ref<Texture> incr = highlight == HIGHLIGHT_INCR ? get_icon("increment_highlight") : get_icon("increment");
+ Ref<Texture2D> decr = highlight == HIGHLIGHT_DECR ? get_icon("decrement_highlight") : get_icon("decrement");
+ Ref<Texture2D> incr = highlight == HIGHLIGHT_INCR ? get_icon("increment_highlight") : get_icon("increment");
Ref<StyleBox> bg = has_focus() ? get_stylebox("scroll_focus") : get_stylebox("scroll");
Ref<StyleBox> grabber;
@@ -500,8 +500,8 @@ double ScrollBar::get_grabber_offset() const {
Size2 ScrollBar::get_minimum_size() const {
- Ref<Texture> incr = get_icon("increment");
- Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture2D> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
Ref<StyleBox> bg = get_stylebox("scroll");
Size2 minsize;
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 9b3ed35e6e..85887ef7b1 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -36,7 +36,7 @@ Size2 Slider::get_minimum_size() const {
Ref<StyleBox> style = get_stylebox("slider");
Size2i ss = style->get_minimum_size() + style->get_center_size();
- Ref<Texture> grabber = get_icon("grabber");
+ Ref<Texture2D> grabber = get_icon("grabber");
Size2i rs = grabber->get_size();
if (orientation == HORIZONTAL)
@@ -57,7 +57,7 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
if (mb->get_button_index() == BUTTON_LEFT) {
if (mb->is_pressed()) {
- Ref<Texture> grabber = get_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber");
+ Ref<Texture2D> grabber = get_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber");
grab.pos = orientation == VERTICAL ? mb->get_position().y : mb->get_position().x;
double grab_width = (double)grabber->get_size().width;
@@ -87,7 +87,7 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
if (grab.active) {
Size2i size = get_size();
- Ref<Texture> grabber = get_icon("grabber");
+ Ref<Texture2D> grabber = get_icon("grabber");
float motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos;
if (orientation == VERTICAL)
motion = -motion;
@@ -167,8 +167,8 @@ void Slider::_notification(int p_what) {
Size2i size = get_size();
Ref<StyleBox> style = get_stylebox("slider");
Ref<StyleBox> grabber_area = get_stylebox("grabber_area");
- Ref<Texture> grabber = get_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled");
- Ref<Texture> tick = get_icon("tick");
+ Ref<Texture2D> grabber = get_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled");
+ Ref<Texture2D> tick = get_icon("tick");
double ratio = Math::is_nan(get_as_ratio()) ? 0 : get_as_ratio();
if (orientation == VERTICAL) {
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 92377949f8..c49d7f3d12 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -182,7 +182,7 @@ void SpinBox::_line_edit_focus_exit() {
_text_entered(line_edit->get_text());
}
-inline void SpinBox::_adjust_width_for_icon(const Ref<Texture> &icon) {
+inline void SpinBox::_adjust_width_for_icon(const Ref<Texture2D> &icon) {
int w = icon->get_width();
if (w != last_w) {
@@ -195,7 +195,7 @@ void SpinBox::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
- Ref<Texture> updown = get_icon("updown");
+ Ref<Texture2D> updown = get_icon("updown");
_adjust_width_for_icon(updown);
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index 04491c8477..d3a3d8fe3d 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -62,7 +62,7 @@ class SpinBox : public Range {
void _line_edit_focus_exit();
- inline void _adjust_width_for_icon(const Ref<Texture> &icon);
+ inline void _adjust_width_for_icon(const Ref<Texture2D> &icon);
protected:
void _gui_input(const Ref<InputEvent> &p_event);
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index bb5260b15e..255278be2b 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -74,7 +74,7 @@ void SplitContainer::_resort() {
bool second_expanded = (vertical ? second->get_v_size_flags() : second->get_h_size_flags()) & SIZE_EXPAND;
// Determine the separation between items
- Ref<Texture> g = get_icon("grabber");
+ Ref<Texture2D> g = get_icon("grabber");
int sep = get_constant("separation");
sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0;
@@ -123,7 +123,7 @@ Size2 SplitContainer::get_minimum_size() const {
/* Calculate MINIMUM SIZE */
Size2i minimum;
- Ref<Texture> g = get_icon("grabber");
+ Ref<Texture2D> g = get_icon("grabber");
int sep = get_constant("separation");
sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0;
@@ -182,7 +182,7 @@ void SplitContainer::_notification(int p_what) {
return;
int sep = dragger_visibility != DRAGGER_HIDDEN_COLLAPSED ? get_constant("separation") : 0;
- Ref<Texture> tex = get_icon("grabber");
+ Ref<Texture2D> tex = get_icon("grabber");
Size2 size = get_size();
if (vertical)
@@ -266,7 +266,7 @@ void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) {
Control::CursorShape SplitContainer::get_cursor_shape(const Point2 &p_pos) const {
if (dragging)
- return (vertical ? CURSOR_VSIZE : CURSOR_HSIZE);
+ return (vertical ? CURSOR_VSPLIT : CURSOR_HSPLIT);
if (!collapsed && _getch(0) && _getch(1) && dragger_visibility == DRAGGER_VISIBLE) {
@@ -275,11 +275,11 @@ Control::CursorShape SplitContainer::get_cursor_shape(const Point2 &p_pos) const
if (vertical) {
if (p_pos.y > middle_sep && p_pos.y < middle_sep + sep)
- return CURSOR_VSIZE;
+ return CURSOR_VSPLIT;
} else {
if (p_pos.x > middle_sep && p_pos.x < middle_sep + sep)
- return CURSOR_HSIZE;
+ return CURSOR_HSPLIT;
}
}
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index b045ff4fe1..402623e53d 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -58,7 +58,7 @@ int TabContainer::_get_top_margin() const {
if (!c->has_meta("_tab_icon"))
continue;
- Ref<Texture> tex = c->get_meta("_tab_icon");
+ Ref<Texture2D> tex = c->get_meta("_tab_icon");
if (!tex.is_valid())
continue;
content_height = MAX(content_height, tex->get_size().height);
@@ -81,7 +81,7 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
return;
// Handle menu button.
- Ref<Texture> menu = get_icon("menu");
+ Ref<Texture2D> menu = get_icon("menu");
if (popup && pos.x > size.width - menu->get_width()) {
emit_signal("pre_popup_pressed");
@@ -107,8 +107,8 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
popup_ofs = menu->get_width();
}
- Ref<Texture> increment = get_icon("increment");
- Ref<Texture> decrement = get_icon("decrement");
+ Ref<Texture2D> increment = get_icon("increment");
+ Ref<Texture2D> decrement = get_icon("decrement");
if (pos.x > size.width - increment->get_width() - popup_ofs) {
if (last_tab_cache < tabs.size() - 1) {
first_tab_cache += 1;
@@ -159,7 +159,7 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
return;
}
- Ref<Texture> menu = get_icon("menu");
+ Ref<Texture2D> menu = get_icon("menu");
if (popup) {
if (pos.x >= size.width - menu->get_width()) {
@@ -191,8 +191,8 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
popup_ofs = menu->get_width();
}
- Ref<Texture> increment = get_icon("increment");
- Ref<Texture> decrement = get_icon("decrement");
+ Ref<Texture2D> increment = get_icon("increment");
+ Ref<Texture2D> decrement = get_icon("decrement");
if (pos.x >= size.width - increment->get_width() - popup_ofs) {
if (highlight_arrow != 1) {
@@ -225,9 +225,9 @@ void TabContainer::_notification(int p_what) {
Vector<Control *> tabs = _get_tabs();
int side_margin = get_constant("side_margin");
- Ref<Texture> menu = get_icon("menu");
- Ref<Texture> increment = get_icon("increment");
- Ref<Texture> decrement = get_icon("decrement");
+ Ref<Texture2D> menu = get_icon("menu");
+ Ref<Texture2D> increment = get_icon("increment");
+ Ref<Texture2D> decrement = get_icon("decrement");
int header_width = get_size().width - side_margin * 2;
// Find the width of the header area.
@@ -272,12 +272,12 @@ void TabContainer::_notification(int p_what) {
Ref<StyleBox> tab_bg = get_stylebox("tab_bg");
Ref<StyleBox> tab_fg = get_stylebox("tab_fg");
Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled");
- Ref<Texture> increment = get_icon("increment");
- Ref<Texture> increment_hl = get_icon("increment_highlight");
- Ref<Texture> decrement = get_icon("decrement");
- Ref<Texture> decrement_hl = get_icon("decrement_highlight");
- Ref<Texture> menu = get_icon("menu");
- Ref<Texture> menu_hl = get_icon("menu_highlight");
+ Ref<Texture2D> increment = get_icon("increment");
+ Ref<Texture2D> increment_hl = get_icon("increment_highlight");
+ Ref<Texture2D> decrement = get_icon("decrement");
+ Ref<Texture2D> decrement_hl = get_icon("decrement_highlight");
+ Ref<Texture2D> menu = get_icon("menu");
+ Ref<Texture2D> menu_hl = get_icon("menu_highlight");
Ref<Font> font = get_font("font");
Color font_color_fg = get_color("font_color_fg");
Color font_color_bg = get_color("font_color_bg");
@@ -383,7 +383,7 @@ void TabContainer::_notification(int p_what) {
// Draw the tab icon.
if (control->has_meta("_tab_icon")) {
- Ref<Texture> icon = control->get_meta("_tab_icon");
+ Ref<Texture2D> icon = control->get_meta("_tab_icon");
if (icon.is_valid()) {
int y = y_center - (icon->get_height() / 2);
icon->draw(canvas, Point2i(x_content, y));
@@ -464,7 +464,7 @@ int TabContainer::_get_tab_width(int p_index) const {
// Add space for a tab icon.
if (control->has_meta("_tab_icon")) {
- Ref<Texture> icon = control->get_meta("_tab_icon");
+ Ref<Texture2D> icon = control->get_meta("_tab_icon");
if (icon.is_valid()) {
width += icon->get_width();
if (text != "")
@@ -648,7 +648,7 @@ Variant TabContainer::get_drag_data(const Point2 &p_point) {
HBoxContainer *drag_preview = memnew(HBoxContainer);
- Ref<Texture> icon = get_tab_icon(tab_over);
+ Ref<Texture2D> icon = get_tab_icon(tab_over);
if (!icon.is_null()) {
TextureRect *tf = memnew(TextureRect);
tf->set_texture(icon);
@@ -745,12 +745,12 @@ int TabContainer::get_tab_idx_at_point(const Point2 &p_point) const {
int right_ofs = 0;
if (popup) {
- Ref<Texture> menu = get_icon("menu");
+ Ref<Texture2D> menu = get_icon("menu");
right_ofs += menu->get_width();
}
if (buttons_visible_cache) {
- Ref<Texture> increment = get_icon("increment");
- Ref<Texture> decrement = get_icon("decrement");
+ Ref<Texture2D> increment = get_icon("increment");
+ Ref<Texture2D> decrement = get_icon("decrement");
right_ofs += increment->get_width() + decrement->get_width();
}
if (p_point.x > size.width - right_ofs) {
@@ -834,21 +834,21 @@ String TabContainer::get_tab_title(int p_tab) const {
return child->get_name();
}
-void TabContainer::set_tab_icon(int p_tab, const Ref<Texture> &p_icon) {
+void TabContainer::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
Control *child = _get_tab(p_tab);
ERR_FAIL_COND(!child);
child->set_meta("_tab_icon", p_icon);
update();
}
-Ref<Texture> TabContainer::get_tab_icon(int p_tab) const {
+Ref<Texture2D> TabContainer::get_tab_icon(int p_tab) const {
Control *child = _get_tab(p_tab);
- ERR_FAIL_COND_V(!child, Ref<Texture>());
+ ERR_FAIL_COND_V(!child, Ref<Texture2D>());
if (child->has_meta("_tab_icon"))
return child->get_meta("_tab_icon");
else
- return Ref<Texture>();
+ return Ref<Texture2D>();
}
void TabContainer::set_tab_disabled(int p_tab, bool p_disabled) {
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index c5a9045ca6..38c029475c 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -93,8 +93,8 @@ public:
void set_tab_title(int p_tab, const String &p_title);
String get_tab_title(int p_tab) const;
- void set_tab_icon(int p_tab, const Ref<Texture> &p_icon);
- Ref<Texture> get_tab_icon(int p_tab) const;
+ void set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_tab_icon(int p_tab) const;
void set_tab_disabled(int p_tab, bool p_disabled);
bool get_tab_disabled(int p_tab) const;
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 6cd95e73fc..4aa7ea8cb1 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -46,7 +46,7 @@ Size2 Tabs::get_minimum_size() const {
for (int i = 0; i < tabs.size(); i++) {
- Ref<Texture> tex = tabs[i].icon;
+ Ref<Texture2D> tex = tabs[i].icon;
if (tex.is_valid()) {
ms.height = MAX(ms.height, tex->get_size().height);
if (tabs[i].text != "")
@@ -63,7 +63,7 @@ Size2 Tabs::get_minimum_size() const {
ms.width += tab_bg->get_minimum_size().width;
if (tabs[i].right_button.is_valid()) {
- Ref<Texture> rb = tabs[i].right_button;
+ Ref<Texture2D> rb = tabs[i].right_button;
Size2 bms = rb->get_size();
bms.width += get_constant("hseparation");
ms.width += bms.width;
@@ -71,7 +71,7 @@ Size2 Tabs::get_minimum_size() const {
}
if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
- Ref<Texture> cb = get_icon("close");
+ Ref<Texture2D> cb = get_icon("close");
Size2 bms = cb->get_size();
bms.width += get_constant("hseparation");
ms.width += bms.width;
@@ -94,8 +94,8 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
highlight_arrow = -1;
if (buttons_visible) {
- Ref<Texture> incr = get_icon("increment");
- Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture2D> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
int limit = get_size().width - incr->get_width() - decr->get_width();
@@ -163,8 +163,8 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
if (buttons_visible) {
- Ref<Texture> incr = get_icon("increment");
- Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture2D> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
int limit = get_size().width - incr->get_width() - decr->get_width();
@@ -245,7 +245,7 @@ void Tabs::_notification(int p_what) {
Color color_fg = get_color("font_color_fg");
Color color_bg = get_color("font_color_bg");
Color color_disabled = get_color("font_color_disabled");
- Ref<Texture> close = get_icon("close");
+ Ref<Texture2D> close = get_icon("close");
int h = get_size().height;
int w = 0;
@@ -267,10 +267,10 @@ void Tabs::_notification(int p_what) {
w = 0;
}
- Ref<Texture> incr = get_icon("increment");
- Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> incr_hl = get_icon("increment_highlight");
- Ref<Texture> decr_hl = get_icon("decrement_highlight");
+ Ref<Texture2D> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
+ Ref<Texture2D> incr_hl = get_icon("increment_highlight");
+ Ref<Texture2D> decr_hl = get_icon("decrement_highlight");
int limit = get_size().width - incr->get_size().width - decr->get_size().width;
@@ -313,7 +313,7 @@ void Tabs::_notification(int p_what) {
w += sb->get_margin(MARGIN_LEFT);
Size2i sb_ms = sb->get_minimum_size();
- Ref<Texture> icon = tabs[i].icon;
+ Ref<Texture2D> icon = tabs[i].icon;
if (icon.is_valid()) {
icon->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2));
@@ -328,7 +328,7 @@ void Tabs::_notification(int p_what) {
if (tabs[i].right_button.is_valid()) {
Ref<StyleBox> style = get_stylebox("button");
- Ref<Texture> rb = tabs[i].right_button;
+ Ref<Texture2D> rb = tabs[i].right_button;
w += get_constant("hseparation");
@@ -352,7 +352,7 @@ void Tabs::_notification(int p_what) {
if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
Ref<StyleBox> style = get_stylebox("button");
- Ref<Texture> cb = close;
+ Ref<Texture2D> cb = close;
w += get_constant("hseparation");
@@ -449,7 +449,7 @@ String Tabs::get_tab_title(int p_tab) const {
return tabs[p_tab].text;
}
-void Tabs::set_tab_icon(int p_tab, const Ref<Texture> &p_icon) {
+void Tabs::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].icon = p_icon;
@@ -457,9 +457,9 @@ void Tabs::set_tab_icon(int p_tab, const Ref<Texture> &p_icon) {
minimum_size_changed();
}
-Ref<Texture> Tabs::get_tab_icon(int p_tab) const {
+Ref<Texture2D> Tabs::get_tab_icon(int p_tab) const {
- ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>());
return tabs[p_tab].icon;
}
@@ -475,7 +475,7 @@ bool Tabs::get_tab_disabled(int p_tab) const {
return tabs[p_tab].disabled;
}
-void Tabs::set_tab_right_button(int p_tab, const Ref<Texture> &p_right_button) {
+void Tabs::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].right_button = p_right_button;
@@ -483,9 +483,9 @@ void Tabs::set_tab_right_button(int p_tab, const Ref<Texture> &p_right_button) {
update();
minimum_size_changed();
}
-Ref<Texture> Tabs::get_tab_right_button(int p_tab) const {
+Ref<Texture2D> Tabs::get_tab_right_button(int p_tab) const {
- ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>());
return tabs[p_tab].right_button;
}
@@ -536,8 +536,8 @@ void Tabs::_update_cache() {
Ref<StyleBox> tab_bg = get_stylebox("tab_bg");
Ref<StyleBox> tab_fg = get_stylebox("tab_fg");
Ref<Font> font = get_font("font");
- Ref<Texture> incr = get_icon("increment");
- Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture2D> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
int limit = get_size().width - incr->get_width() - decr->get_width();
int w = 0;
@@ -580,7 +580,7 @@ void Tabs::_update_cache() {
slen -= get_constant("hseparation");
}
if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
- Ref<Texture> cb = get_icon("close");
+ Ref<Texture2D> cb = get_icon("close");
slen -= cb->get_width();
slen -= get_constant("hseparation");
}
@@ -604,7 +604,7 @@ void Tabs::_on_mouse_exited() {
update();
}
-void Tabs::add_tab(const String &p_str, const Ref<Texture> &p_icon) {
+void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) {
Tab t;
t.text = p_str;
@@ -806,7 +806,7 @@ int Tabs::get_tab_width(int p_idx) const {
int x = 0;
- Ref<Texture> tex = tabs[p_idx].icon;
+ Ref<Texture2D> tex = tabs[p_idx].icon;
if (tex.is_valid()) {
x += tex->get_width();
if (tabs[p_idx].text != "")
@@ -823,13 +823,13 @@ int Tabs::get_tab_width(int p_idx) const {
x += tab_bg->get_minimum_size().width;
if (tabs[p_idx].right_button.is_valid()) {
- Ref<Texture> rb = tabs[p_idx].right_button;
+ Ref<Texture2D> rb = tabs[p_idx].right_button;
x += rb->get_width();
x += get_constant("hseparation");
}
if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_idx == current)) {
- Ref<Texture> cb = get_icon("close");
+ Ref<Texture2D> cb = get_icon("close");
x += cb->get_width();
x += get_constant("hseparation");
}
@@ -842,8 +842,8 @@ void Tabs::_ensure_no_over_offset() {
if (!is_inside_tree())
return;
- Ref<Texture> incr = get_icon("increment");
- Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture2D> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
int limit = get_size().width - incr->get_width() - decr->get_width();
@@ -885,8 +885,8 @@ void Tabs::ensure_tab_visible(int p_idx) {
}
int prev_offset = offset;
- Ref<Texture> incr = get_icon("increment");
- Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture2D> incr = get_icon("increment");
+ Ref<Texture2D> decr = get_icon("decrement");
int limit = get_size().width - incr->get_width() - decr->get_width();
for (int i = offset; i <= p_idx; i++) {
if (tabs[i].ofs_cache + tabs[i].size_cache > limit) {
@@ -967,7 +967,7 @@ void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &Tabs::set_tab_disabled);
ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &Tabs::get_tab_disabled);
ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &Tabs::remove_tab);
- ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &Tabs::add_tab, DEFVAL(""), DEFVAL(Ref<Texture>()));
+ ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &Tabs::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &Tabs::set_tab_align);
ClassDB::bind_method(D_METHOD("get_tab_align"), &Tabs::get_tab_align);
ClassDB::bind_method(D_METHOD("get_tab_offset"), &Tabs::get_tab_offset);
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index c06e47a54a..3170acb46f 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -59,7 +59,7 @@ private:
String text;
String xl_text;
- Ref<Texture> icon;
+ Ref<Texture2D> icon;
int ofs_cache;
bool disabled;
int size_cache;
@@ -67,7 +67,7 @@ private:
int x_cache;
int x_size_cache;
- Ref<Texture> right_button;
+ Ref<Texture2D> right_button;
Rect2 rb_rect;
Rect2 cb_rect;
};
@@ -115,19 +115,19 @@ protected:
int get_tab_idx_at_point(const Point2 &p_point) const;
public:
- void add_tab(const String &p_str = "", const Ref<Texture> &p_icon = Ref<Texture>());
+ void add_tab(const String &p_str = "", const Ref<Texture2D> &p_icon = Ref<Texture2D>());
void set_tab_title(int p_tab, const String &p_title);
String get_tab_title(int p_tab) const;
- void set_tab_icon(int p_tab, const Ref<Texture> &p_icon);
- Ref<Texture> get_tab_icon(int p_tab) const;
+ void set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_tab_icon(int p_tab) const;
void set_tab_disabled(int p_tab, bool p_disabled);
bool get_tab_disabled(int p_tab) const;
- void set_tab_right_button(int p_tab, const Ref<Texture> &p_right_button);
- Ref<Texture> get_tab_right_button(int p_tab) const;
+ void set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button);
+ Ref<Texture2D> get_tab_right_button(int p_tab) const;
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 6de2f0b570..a5c316848e 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1216,7 +1216,7 @@ void TextEdit::_notification(int p_what) {
int horizontal_gap = (cache.info_gutter_width * 30) / 100;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width;
- Ref<Texture> info_icon = text.get_info_icon(line);
+ Ref<Texture2D> info_icon = text.get_info_icon(line);
// Ensure the icon fits the gutter size.
Size2i icon_size = info_icon->get_size();
if (icon_size.width > cache.info_gutter_width - horizontal_gap) {
@@ -1645,7 +1645,7 @@ void TextEdit::_notification(int p_what) {
Point2 title_pos(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs);
// Draw completion icon if it is valid.
- Ref<Texture> icon = completion_options[l].icon;
+ Ref<Texture2D> icon = completion_options[l].icon;
Rect2 icon_area(completion_rect.position.x, completion_rect.position.y + i * get_row_height(), icon_area_size.width, icon_area_size.height);
if (icon.is_valid()) {
const real_t max_scale = 0.7f;
@@ -4480,7 +4480,7 @@ void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport, bool p_can_be_
if (p_row - move_up > 0 && !is_line_hidden(p_row - move_up)) {
p_row -= move_up;
} else {
- WARN_PRINTS(("Cursor set to hidden line " + itos(p_row) + " and there are no nonhidden lines."));
+ WARN_PRINT(("Cursor set to hidden line " + itos(p_row) + " and there are no nonhidden lines."));
}
}
}
@@ -5690,7 +5690,7 @@ void TextEdit::remove_breakpoints() {
}
}
-void TextEdit::set_line_info_icon(int p_line, Ref<Texture> p_icon, String p_info) {
+void TextEdit::set_line_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info) {
ERR_FAIL_INDEX(p_line, text.size());
text.set_info_icon(p_line, p_icon, p_info);
update();
@@ -6530,6 +6530,10 @@ void TextEdit::_update_completion_candidates() {
Vector<float> sim_cache;
bool single_quote = s.begins_with("'");
Vector<ScriptCodeCompletionOption> completion_options_casei;
+ Vector<ScriptCodeCompletionOption> completion_options_subseq;
+ Vector<ScriptCodeCompletionOption> completion_options_subseq_casei;
+
+ String s_lower = s.to_lower();
for (List<ScriptCodeCompletionOption>::Element *E = completion_sources.front(); E; E = E->next()) {
ScriptCodeCompletionOption &option = E->get();
@@ -6544,31 +6548,68 @@ void TextEdit::_update_completion_candidates() {
option.insert_text = option.insert_text.quote(quote);
}
- if (option.display.begins_with(s)) {
+ if (option.display.length() == 0) {
+ continue;
+ } else if (s.length() == 0) {
completion_options.push_back(option);
- } else if (option.display.to_lower().begins_with(s.to_lower())) {
- completion_options_casei.push_back(option);
- }
- }
+ } else {
- completion_options.append_array(completion_options_casei);
+ // This code works the same as:
+ /*
+ if (option.display.begins_with(s)) {
+ completion_options.push_back(option);
+ } else if (option.display.to_lower().begins_with(s.to_lower())) {
+ completion_options_casei.push_back(option);
+ } else if (s.is_subsequence_of(option.display)) {
+ completion_options_subseq.push_back(option);
+ } else if (s.is_subsequence_ofi(option.display)) {
+ completion_options_subseq_casei.push_back(option);
+ }
+ */
+ // But is more performant due to being inlined and looping over the characters only once
- if (completion_options.size() == 0) {
- for (int i = 0; i < completion_sources.size(); i++) {
- if (s.is_subsequence_of(completion_sources[i].display)) {
- completion_options.push_back(completion_sources[i]);
+ String display_lower = option.display.to_lower();
+
+ const CharType *ssq = &s[0];
+ const CharType *ssq_lower = &s_lower[0];
+
+ const CharType *tgt = &option.display[0];
+ const CharType *tgt_lower = &display_lower[0];
+
+ const CharType *ssq_last_tgt = NULL;
+ const CharType *ssq_lower_last_tgt = NULL;
+
+ for (; *tgt; tgt++, tgt_lower++) {
+ if (*ssq == *tgt) {
+ ssq++;
+ ssq_last_tgt = tgt;
+ }
+ if (*ssq_lower == *tgt_lower) {
+ ssq_lower++;
+ ssq_lower_last_tgt = tgt;
+ }
}
- }
- }
- if (completion_options.size() == 0) {
- for (int i = 0; i < completion_sources.size(); i++) {
- if (s.is_subsequence_ofi(completion_sources[i].display)) {
- completion_options.push_back(completion_sources[i]);
+ if (!*ssq) { // Matched the whole subsequence in s
+ if (ssq_last_tgt == &option.display[s.length() - 1]) { // Finished matching in the first s.length() characters
+ completion_options.push_back(option);
+ } else {
+ completion_options_subseq.push_back(option);
+ }
+ } else if (!*ssq_lower) { // Matched the whole subsequence in s_lower
+ if (ssq_lower_last_tgt == &option.display[s.length() - 1]) { // Finished matching in the first s.length() characters
+ completion_options_casei.push_back(option);
+ } else {
+ completion_options_subseq_casei.push_back(option);
+ }
}
}
}
+ completion_options.append_array(completion_options_casei);
+ completion_options.append_array(completion_options_subseq);
+ completion_options.append_array(completion_options_subseq_casei);
+
if (completion_options.size() == 0) {
// No options to complete, cancel.
_cancel_completion();
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index b4e7dcfebb..a849f62bc5 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -85,7 +85,7 @@ public:
bool has_info : 1;
int wrap_amount_cache : 24;
Map<int, ColorRegionInfo> region_info;
- Ref<Texture> info_icon;
+ Ref<Texture2D> info_icon;
String info;
String data;
Line() {
@@ -129,7 +129,7 @@ public:
bool is_hidden(int p_line) const { return text[p_line].hidden; }
void set_safe(int p_line, bool p_safe) { text.write[p_line].safe = p_safe; }
bool is_safe(int p_line) const { return text[p_line].safe; }
- void set_info_icon(int p_line, Ref<Texture> p_icon, String p_info) {
+ void set_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info) {
if (p_icon.is_null()) {
text.write[p_line].has_info = false;
return;
@@ -139,7 +139,7 @@ public:
text.write[p_line].has_info = true;
}
bool has_info_icon(int p_line) const { return text[p_line].has_info; }
- const Ref<Texture> &get_info_icon(int p_line) const { return text[p_line].info_icon; }
+ const Ref<Texture2D> &get_info_icon(int p_line) const { return text[p_line].info_icon; }
const String &get_info(int p_line) const { return text[p_line].info; }
void insert(int p_at, const String &p_text);
void remove(int p_at);
@@ -208,12 +208,12 @@ private:
struct Cache {
- Ref<Texture> tab_icon;
- Ref<Texture> space_icon;
- Ref<Texture> can_fold_icon;
- Ref<Texture> folded_icon;
- Ref<Texture> folded_eol_icon;
- Ref<Texture> executing_icon;
+ Ref<Texture2D> tab_icon;
+ Ref<Texture2D> space_icon;
+ Ref<Texture2D> can_fold_icon;
+ Ref<Texture2D> folded_icon;
+ Ref<Texture2D> folded_eol_icon;
+ Ref<Texture2D> executing_icon;
Ref<StyleBox> style_normal;
Ref<StyleBox> style_focus;
Ref<StyleBox> style_readonly;
@@ -603,7 +603,7 @@ public:
Array get_breakpoints_array() const;
void remove_breakpoints();
- void set_line_info_icon(int p_line, Ref<Texture> p_icon, String p_info = "");
+ void set_line_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info = "");
void clear_info_icons();
void set_line_as_hidden(int p_line, bool p_hidden);
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index 9ffb69037a..5f2e4cf58e 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -122,7 +122,7 @@ void TextureButton::_notification(int p_what) {
case NOTIFICATION_DRAW: {
DrawMode draw_mode = get_draw_mode();
- Ref<Texture> texdraw;
+ Ref<Texture2D> texdraw;
switch (draw_mode) {
case DRAW_NORMAL: {
@@ -252,11 +252,11 @@ void TextureButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureButton::get_stretch_mode);
ADD_GROUP("Textures", "texture_");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_texture", "get_normal_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_pressed_texture", "get_pressed_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_hover", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_hover_texture", "get_hover_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_disabled", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_disabled_texture", "get_disabled_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_focused", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_focused_texture", "get_focused_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_texture", "get_normal_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_pressed_texture", "get_pressed_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_hover", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_hover_texture", "get_hover_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_disabled", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_disabled_texture", "get_disabled_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_focused", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_focused_texture", "get_focused_texture");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_click_mask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_click_mask", "get_click_mask");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand", PROPERTY_HINT_RESOURCE_TYPE, "bool"), "set_expand", "get_expand");
ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode");
@@ -270,24 +270,24 @@ void TextureButton::_bind_methods() {
BIND_ENUM_CONSTANT(STRETCH_KEEP_ASPECT_COVERED);
}
-void TextureButton::set_normal_texture(const Ref<Texture> &p_normal) {
+void TextureButton::set_normal_texture(const Ref<Texture2D> &p_normal) {
normal = p_normal;
update();
minimum_size_changed();
}
-void TextureButton::set_pressed_texture(const Ref<Texture> &p_pressed) {
+void TextureButton::set_pressed_texture(const Ref<Texture2D> &p_pressed) {
pressed = p_pressed;
update();
}
-void TextureButton::set_hover_texture(const Ref<Texture> &p_hover) {
+void TextureButton::set_hover_texture(const Ref<Texture2D> &p_hover) {
hover = p_hover;
update();
}
-void TextureButton::set_disabled_texture(const Ref<Texture> &p_disabled) {
+void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) {
disabled = p_disabled;
update();
@@ -298,19 +298,19 @@ void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
update();
}
-Ref<Texture> TextureButton::get_normal_texture() const {
+Ref<Texture2D> TextureButton::get_normal_texture() const {
return normal;
}
-Ref<Texture> TextureButton::get_pressed_texture() const {
+Ref<Texture2D> TextureButton::get_pressed_texture() const {
return pressed;
}
-Ref<Texture> TextureButton::get_hover_texture() const {
+Ref<Texture2D> TextureButton::get_hover_texture() const {
return hover;
}
-Ref<Texture> TextureButton::get_disabled_texture() const {
+Ref<Texture2D> TextureButton::get_disabled_texture() const {
return disabled;
}
@@ -319,12 +319,12 @@ Ref<BitMap> TextureButton::get_click_mask() const {
return click_mask;
}
-Ref<Texture> TextureButton::get_focused_texture() const {
+Ref<Texture2D> TextureButton::get_focused_texture() const {
return focused;
};
-void TextureButton::set_focused_texture(const Ref<Texture> &p_focused) {
+void TextureButton::set_focused_texture(const Ref<Texture2D> &p_focused) {
focused = p_focused;
};
diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h
index e39b94abf0..43b10a8e8b 100644
--- a/scene/gui/texture_button.h
+++ b/scene/gui/texture_button.h
@@ -49,11 +49,11 @@ public:
};
private:
- Ref<Texture> normal;
- Ref<Texture> pressed;
- Ref<Texture> hover;
- Ref<Texture> disabled;
- Ref<Texture> focused;
+ Ref<Texture2D> normal;
+ Ref<Texture2D> pressed;
+ Ref<Texture2D> hover;
+ Ref<Texture2D> disabled;
+ Ref<Texture2D> focused;
Ref<BitMap> click_mask;
bool expand;
StretchMode stretch_mode;
@@ -69,18 +69,18 @@ protected:
static void _bind_methods();
public:
- void set_normal_texture(const Ref<Texture> &p_normal);
- void set_pressed_texture(const Ref<Texture> &p_pressed);
- void set_hover_texture(const Ref<Texture> &p_hover);
- void set_disabled_texture(const Ref<Texture> &p_disabled);
- void set_focused_texture(const Ref<Texture> &p_focused);
+ void set_normal_texture(const Ref<Texture2D> &p_normal);
+ void set_pressed_texture(const Ref<Texture2D> &p_pressed);
+ void set_hover_texture(const Ref<Texture2D> &p_hover);
+ void set_disabled_texture(const Ref<Texture2D> &p_disabled);
+ void set_focused_texture(const Ref<Texture2D> &p_focused);
void set_click_mask(const Ref<BitMap> &p_click_mask);
- Ref<Texture> get_normal_texture() const;
- Ref<Texture> get_pressed_texture() const;
- Ref<Texture> get_hover_texture() const;
- Ref<Texture> get_disabled_texture() const;
- Ref<Texture> get_focused_texture() const;
+ Ref<Texture2D> get_normal_texture() const;
+ Ref<Texture2D> get_pressed_texture() const;
+ Ref<Texture2D> get_hover_texture() const;
+ Ref<Texture2D> get_disabled_texture() const;
+ Ref<Texture2D> get_focused_texture() const;
Ref<BitMap> get_click_mask() const;
bool get_expand() const;
diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp
index 2d30ff7334..c5650b1795 100644
--- a/scene/gui/texture_progress.cpp
+++ b/scene/gui/texture_progress.cpp
@@ -32,19 +32,19 @@
#include "core/engine.h"
-void TextureProgress::set_under_texture(const Ref<Texture> &p_texture) {
+void TextureProgress::set_under_texture(const Ref<Texture2D> &p_texture) {
under = p_texture;
update();
minimum_size_changed();
}
-Ref<Texture> TextureProgress::get_under_texture() const {
+Ref<Texture2D> TextureProgress::get_under_texture() const {
return under;
}
-void TextureProgress::set_over_texture(const Ref<Texture> &p_texture) {
+void TextureProgress::set_over_texture(const Ref<Texture2D> &p_texture) {
over = p_texture;
update();
@@ -53,7 +53,7 @@ void TextureProgress::set_over_texture(const Ref<Texture> &p_texture) {
}
}
-Ref<Texture> TextureProgress::get_over_texture() const {
+Ref<Texture2D> TextureProgress::get_over_texture() const {
return over;
}
@@ -94,14 +94,14 @@ Size2 TextureProgress::get_minimum_size() const {
return Size2(1, 1);
}
-void TextureProgress::set_progress_texture(const Ref<Texture> &p_texture) {
+void TextureProgress::set_progress_texture(const Ref<Texture2D> &p_texture) {
progress = p_texture;
update();
minimum_size_changed();
}
-Ref<Texture> TextureProgress::get_progress_texture() const {
+Ref<Texture2D> TextureProgress::get_progress_texture() const {
return progress;
}
@@ -201,7 +201,7 @@ Point2 TextureProgress::get_relative_center() {
return p;
}
-void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate) {
+void TextureProgress::draw_nine_patch_stretched(const Ref<Texture2D> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate) {
Vector2 texture_size = p_texture->get_size();
Vector2 topleft = Vector2(stretch_margin[MARGIN_LEFT], stretch_margin[MARGIN_TOP]);
Vector2 bottomright = Vector2(stretch_margin[MARGIN_RIGHT], stretch_margin[MARGIN_BOTTOM]);
@@ -501,9 +501,9 @@ void TextureProgress::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_nine_patch_stretch"), &TextureProgress::get_nine_patch_stretch);
ADD_GROUP("Textures", "texture_");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_under", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_under_texture", "get_under_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_over_texture", "get_over_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_progress_texture", "get_progress_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_under", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_under_texture", "get_under_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_over_texture", "get_over_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_progress_texture", "get_progress_texture");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise,Bilinear (Left and Right),Bilinear (Top and Bottom), Clockwise and Counter Clockwise"), "set_fill_mode", "get_fill_mode");
ADD_GROUP("Tint", "tint_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_under"), "set_tint_under", "get_tint_under");
diff --git a/scene/gui/texture_progress.h b/scene/gui/texture_progress.h
index e4a40fd6a3..e05f89aa3e 100644
--- a/scene/gui/texture_progress.h
+++ b/scene/gui/texture_progress.h
@@ -37,9 +37,9 @@ class TextureProgress : public Range {
GDCLASS(TextureProgress, Range);
- Ref<Texture> under;
- Ref<Texture> progress;
- Ref<Texture> over;
+ Ref<Texture2D> under;
+ Ref<Texture2D> progress;
+ Ref<Texture2D> over;
protected:
static void _bind_methods();
@@ -70,14 +70,14 @@ public:
void set_radial_center_offset(const Point2 &p_off);
Point2 get_radial_center_offset();
- void set_under_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_under_texture() const;
+ void set_under_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_under_texture() const;
- void set_progress_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_progress_texture() const;
+ void set_progress_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_progress_texture() const;
- void set_over_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_over_texture() const;
+ void set_over_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_over_texture() const;
void set_stretch_margin(Margin p_margin, int p_size);
int get_stretch_margin(Margin p_margin) const;
@@ -109,7 +109,7 @@ private:
Point2 unit_val_to_uv(float val);
Point2 get_relative_center();
- void draw_nine_patch_stretched(const Ref<Texture> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate);
+ void draw_nine_patch_stretched(const Ref<Texture2D> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate);
};
VARIANT_ENUM_CAST(TextureProgress::FillMode);
diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp
index 514eff358e..64693e2531 100644
--- a/scene/gui/texture_rect.cpp
+++ b/scene/gui/texture_rect.cpp
@@ -129,7 +129,7 @@ void TextureRect::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureRect::get_stretch_mode);
ClassDB::bind_method(D_METHOD("_texture_changed"), &TextureRect::_texture_changed);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand");
ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h");
@@ -153,7 +153,7 @@ void TextureRect::_texture_changed() {
}
}
-void TextureRect::set_texture(const Ref<Texture> &p_tex) {
+void TextureRect::set_texture(const Ref<Texture2D> &p_tex) {
if (p_tex == texture) {
return;
@@ -173,7 +173,7 @@ void TextureRect::set_texture(const Ref<Texture> &p_tex) {
minimum_size_changed();
}
-Ref<Texture> TextureRect::get_texture() const {
+Ref<Texture2D> TextureRect::get_texture() const {
return texture;
}
diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h
index ef970fa051..77a2828fd4 100644
--- a/scene/gui/texture_rect.h
+++ b/scene/gui/texture_rect.h
@@ -53,7 +53,7 @@ private:
bool expand;
bool hflip;
bool vflip;
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
StretchMode stretch_mode;
void _texture_changed();
@@ -64,8 +64,8 @@ protected:
static void _bind_methods();
public:
- void set_texture(const Ref<Texture> &p_tex);
- Ref<Texture> get_texture() const;
+ void set_texture(const Ref<Texture2D> &p_tex);
+ Ref<Texture2D> get_texture() const;
void set_expand(bool p_expand);
bool has_expand() const;
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 964f376dbd..08835be9fd 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -129,7 +129,7 @@ void TreeItem::set_cell_mode(int p_column, TreeCellMode p_mode) {
c.step = 1;
c.val = 0;
c.checked = false;
- c.icon = Ref<Texture>();
+ c.icon = Ref<Texture2D>();
c.text = "";
c.icon_max_w = 0;
_changed_notify(p_column);
@@ -198,16 +198,16 @@ String TreeItem::get_suffix(int p_column) const {
return cells[p_column].suffix;
}
-void TreeItem::set_icon(int p_column, const Ref<Texture> &p_icon) {
+void TreeItem::set_icon(int p_column, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].icon = p_icon;
_changed_notify(p_column);
}
-Ref<Texture> TreeItem::get_icon(int p_column) const {
+Ref<Texture2D> TreeItem::get_icon(int p_column) const {
- ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture2D>());
return cells[p_column].icon;
}
@@ -522,7 +522,7 @@ void TreeItem::deselect(int p_column) {
_cell_deselected(p_column);
}
-void TreeItem::add_button(int p_column, const Ref<Texture> &p_button, int p_id, bool p_disabled, const String &p_tooltip) {
+void TreeItem::add_button(int p_column, const Ref<Texture2D> &p_button, int p_id, bool p_disabled, const String &p_tooltip) {
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_COND(!p_button.is_valid());
@@ -542,9 +542,9 @@ int TreeItem::get_button_count(int p_column) const {
ERR_FAIL_INDEX_V(p_column, cells.size(), -1);
return cells[p_column].buttons.size();
}
-Ref<Texture> TreeItem::get_button(int p_column, int p_idx) const {
- ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture>());
- ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), Ref<Texture>());
+Ref<Texture2D> TreeItem::get_button(int p_column, int p_idx) const {
+ ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture2D>());
+ ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), Ref<Texture2D>());
return cells[p_column].buttons[p_idx].texture;
}
String TreeItem::get_button_tooltip(int p_column, int p_idx) const {
@@ -577,7 +577,7 @@ int TreeItem::get_button_by_id(int p_column, int p_id) const {
return -1;
}
-void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture> &p_button) {
+void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture2D> &p_button) {
ERR_FAIL_COND(p_button.is_null());
ERR_FAIL_INDEX(p_column, cells.size());
@@ -1026,7 +1026,7 @@ int Tree::compute_item_height(TreeItem *p_item) const {
case TreeItem::CELL_MODE_CUSTOM:
case TreeItem::CELL_MODE_ICON: {
- Ref<Texture> icon = p_item->cells[i].icon;
+ Ref<Texture2D> icon = p_item->cells[i].icon;
if (!icon.is_null()) {
Size2i s = p_item->cells[i].get_icon_size();
@@ -1121,7 +1121,7 @@ void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, co
}
rect.position.y += Math::floor((rect.size.y - font->get_height()) / 2.0) + font->get_ascent();
- font->draw(ci, rect.position, text, p_color, rect.size.x);
+ font->draw(ci, rect.position, text, p_color, MAX(0, rect.size.width));
}
int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item) {
@@ -1190,7 +1190,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
int bw = 0;
for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) {
- Ref<Texture> b = p_item->cells[i].buttons[j].texture;
+ Ref<Texture2D> b = p_item->cells[i].buttons[j].texture;
Size2 s = b->get_size() + cache.button_pressed->get_minimum_size();
if (s.height < label_h)
s.height = label_h;
@@ -1305,8 +1305,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
} break;
case TreeItem::CELL_MODE_CHECK: {
- Ref<Texture> checked = cache.checked;
- Ref<Texture> unchecked = cache.unchecked;
+ Ref<Texture2D> checked = cache.checked;
+ Ref<Texture2D> unchecked = cache.unchecked;
Point2i check_ofs = item_rect.position;
check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2);
@@ -1350,7 +1350,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (p_item->cells[i].suffix != String())
s += " " + p_item->cells[i].suffix;
- Ref<Texture> downarrow = cache.select_arrow;
+ Ref<Texture2D> downarrow = cache.select_arrow;
font->draw(ci, text_pos, s, col, item_rect.size.x - downarrow->get_width());
@@ -1361,7 +1361,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
downarrow->draw(ci, arrow_pos);
} else {
- Ref<Texture> updown = cache.updown;
+ Ref<Texture2D> updown = cache.updown;
String valtext = String::num(p_item->cells[i].val, Math::range_step_decimals(p_item->cells[i].step));
@@ -1399,7 +1399,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
} break;
case TreeItem::CELL_MODE_CUSTOM: {
- if (p_item->cells[i].custom_draw_obj) {
+ if (p_item->cells[i].custom_draw_obj.is_valid()) {
Object *cdo = ObjectDB::get_instance(p_item->cells[i].custom_draw_obj);
if (cdo)
@@ -1412,7 +1412,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
break;
}
- Ref<Texture> downarrow = cache.select_arrow;
+ Ref<Texture2D> downarrow = cache.select_arrow;
Rect2i ir = item_rect;
@@ -1462,7 +1462,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (!p_item->disable_folding && !hide_folding && p_item->children) { //has children, draw the guide box
- Ref<Texture> arrow;
+ Ref<Texture2D> arrow;
if (p_item->collapsed) {
@@ -1775,7 +1775,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
bool already_cursor = (p_item == selected_item) && col == selected_col;
for (int j = c.buttons.size() - 1; j >= 0; j--) {
- Ref<Texture> b = c.buttons[j].texture;
+ Ref<Texture2D> b = c.buttons[j].texture;
int w = b->get_size().width + cache.button_pressed->get_minimum_size().width;
if (x > col_width - w) {
@@ -3630,6 +3630,17 @@ TreeItem *Tree::search_item_text(const String &p_find, int *r_col, bool p_select
return _search_item_text(from->get_next_visible(true), p_find, r_col, p_selectable);
}
+TreeItem *Tree::get_item_with_text(const String &p_find) const {
+ for (TreeItem *current = root; current; current = current->get_next_visible()) {
+ for (int i = 0; i < columns.size(); i++) {
+ if (current->get_text(i) == p_find) {
+ return current;
+ }
+ }
+ }
+ return NULL;
+}
+
void Tree::_do_incr_search(const String &p_add) {
uint64_t time = OS::get_singleton()->get_ticks_usec() / 1000; // convert to msec
@@ -3814,7 +3825,7 @@ String Tree::get_tooltip(const Point2 &p_pos) const {
pos.x -= get_column_width(i);
for (int j = c.buttons.size() - 1; j >= 0; j--) {
- Ref<Texture> b = c.buttons[j].texture;
+ Ref<Texture2D> b = c.buttons[j].texture;
Size2 size = b->get_size() + cache.button_pressed->get_minimum_size();
if (pos.x > col_width - size.width) {
String tooltip = c.buttons[j].tooltip;
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index d87de6e773..b58f937c57 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -66,7 +66,7 @@ private:
TreeCellMode mode;
- Ref<Texture> icon;
+ Ref<Texture2D> icon;
Rect2i icon_region;
String text;
String suffix;
@@ -97,7 +97,7 @@ private:
struct Button {
int id;
bool disabled;
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
Color color;
String tooltip;
Button() {
@@ -112,7 +112,7 @@ private:
Cell() {
- custom_draw_obj = 0;
+ custom_draw_obj = ObjectID();
custom_button = false;
mode = TreeItem::CELL_MODE_STRING;
min = 0;
@@ -189,8 +189,8 @@ public:
void set_suffix(int p_column, String p_suffix);
String get_suffix(int p_column) const;
- void set_icon(int p_column, const Ref<Texture> &p_icon);
- Ref<Texture> get_icon(int p_column) const;
+ void set_icon(int p_column, const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_icon(int p_column) const;
void set_icon_region(int p_column, const Rect2 &p_icon_region);
Rect2 get_icon_region(int p_column) const;
@@ -201,14 +201,14 @@ public:
void set_icon_max_width(int p_column, int p_max);
int get_icon_max_width(int p_column) const;
- void add_button(int p_column, const Ref<Texture> &p_button, int p_id = -1, bool p_disabled = false, const String &p_tooltip = "");
+ void add_button(int p_column, const Ref<Texture2D> &p_button, int p_id = -1, bool p_disabled = false, const String &p_tooltip = "");
int get_button_count(int p_column) const;
String get_button_tooltip(int p_column, int p_idx) const;
- Ref<Texture> get_button(int p_column, int p_idx) const;
+ Ref<Texture2D> get_button(int p_column, int p_idx) const;
int get_button_id(int p_column, int p_idx) const;
void erase_button(int p_column, int p_idx);
int get_button_by_id(int p_column, int p_id) const;
- void set_button(int p_column, int p_idx, const Ref<Texture> &p_button);
+ void set_button(int p_column, int p_idx, const Ref<Texture2D> &p_button);
void set_button_color(int p_column, int p_idx, const Color &p_color);
void set_button_disabled(int p_column, int p_idx, bool p_disabled);
bool is_button_disabled(int p_column, int p_idx) const;
@@ -374,7 +374,7 @@ private:
int compute_item_height(TreeItem *p_item) const;
int get_item_height(TreeItem *p_item) const;
- //void draw_item_text(String p_text,const Ref<Texture>& p_icon,int p_icon_max_w,bool p_tool,Rect2i p_rect,const Color& p_color);
+ //void draw_item_text(String p_text,const Ref<Texture2D>& p_icon,int p_icon_max_w,bool p_tool,Rect2i p_rect,const Color& p_color);
void draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color);
int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item);
void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = NULL, bool *r_in_range = NULL, bool p_force_deselect = false);
@@ -416,12 +416,12 @@ private:
Color title_button_color;
- Ref<Texture> checked;
- Ref<Texture> unchecked;
- Ref<Texture> arrow_collapsed;
- Ref<Texture> arrow;
- Ref<Texture> select_arrow;
- Ref<Texture> updown;
+ Ref<Texture2D> checked;
+ Ref<Texture2D> unchecked;
+ Ref<Texture2D> arrow_collapsed;
+ Ref<Texture2D> arrow;
+ Ref<Texture2D> select_arrow;
+ Ref<Texture2D> updown;
Color font_color;
Color font_color_selected;
@@ -577,7 +577,10 @@ public:
Rect2 get_item_rect(TreeItem *p_item, int p_column = -1) const;
bool edit_selected();
+ // First item that starts with the text, from the current focused item down and wraps around.
TreeItem *search_item_text(const String &p_find, int *r_col = NULL, bool p_selectable = false);
+ // First item that matches the whole text, from the first item down.
+ TreeItem *get_item_with_text(const String &p_find) const;
Point2 get_scroll() const;
void scroll_to_item(TreeItem *p_item);
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index 0a693d4023..3d8112b986 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -375,12 +375,12 @@ void VideoPlayer::set_stream_position(float p_position) {
playback->seek(p_position);
}
-Ref<Texture> VideoPlayer::get_video_texture() const {
+Ref<Texture2D> VideoPlayer::get_video_texture() const {
if (playback.is_valid())
return playback->get_texture();
- return Ref<Texture>();
+ return Ref<Texture2D>();
}
void VideoPlayer::set_autoplay(bool p_enable) {
diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h
index e740e3e4ed..78e7fa05f8 100644
--- a/scene/gui/video_player.h
+++ b/scene/gui/video_player.h
@@ -86,7 +86,7 @@ public:
void set_expand(bool p_expand);
bool has_expand() const;
- Ref<Texture> get_video_texture() const;
+ Ref<Texture2D> get_video_texture() const;
void set_stream(const Ref<VideoStream> &p_stream);
Ref<VideoStream> get_stream() const;
diff --git a/scene/gui/viewport_container.cpp b/scene/gui/viewport_container.cpp
index 4565b4b538..a76f2924d3 100644
--- a/scene/gui/viewport_container.cpp
+++ b/scene/gui/viewport_container.cpp
@@ -135,9 +135,9 @@ void ViewportContainer::_notification(int p_what) {
continue;
if (stretch)
- draw_texture_rect(c->get_texture(), Rect2(Vector2(), get_size() * Size2(1, -1)));
+ draw_texture_rect(c->get_texture(), Rect2(Vector2(), get_size()));
else
- draw_texture_rect(c->get_texture(), Rect2(Vector2(), c->get_size() * Size2(1, -1)));
+ draw_texture_rect(c->get_texture(), Rect2(Vector2(), c->get_size()));
}
}
}
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index 4ae018a79a..04cf5c6338 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -200,7 +200,7 @@ void CanvasLayer::set_custom_viewport(Node *p_viewport) {
if (custom_viewport) {
custom_viewport_id = custom_viewport->get_instance_id();
} else {
- custom_viewport_id = 0;
+ custom_viewport_id = ObjectID();
}
if (is_inside_tree()) {
@@ -327,7 +327,7 @@ CanvasLayer::CanvasLayer() {
layer = 1;
canvas = VS::get_singleton()->canvas_create();
custom_viewport = NULL;
- custom_viewport_id = 0;
+
sort_index = 0;
follow_viewport = false;
follow_viewport_scale = 1.0;
diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp
index 0128d1a218..f1b3f91920 100644
--- a/scene/main/instance_placeholder.cpp
+++ b/scene/main/instance_placeholder.cpp
@@ -112,11 +112,6 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene
return scene;
}
-void InstancePlaceholder::replace_by_instance(const Ref<PackedScene> &p_custom_scene) {
- //Deprecated by
- create_instance(true, p_custom_scene);
-}
-
Dictionary InstancePlaceholder::get_stored_values(bool p_with_order) {
Dictionary ret;
@@ -138,7 +133,6 @@ void InstancePlaceholder::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_stored_values", "with_order"), &InstancePlaceholder::get_stored_values, DEFVAL(false));
ClassDB::bind_method(D_METHOD("create_instance", "replace", "custom_scene"), &InstancePlaceholder::create_instance, DEFVAL(false), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("replace_by_instance", "custom_scene"), &InstancePlaceholder::replace_by_instance, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("get_instance_path"), &InstancePlaceholder::get_instance_path);
}
diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h
index d570b8c247..9f7b84716d 100644
--- a/scene/main/instance_placeholder.h
+++ b/scene/main/instance_placeholder.h
@@ -61,7 +61,6 @@ public:
Dictionary get_stored_values(bool p_with_order = false);
Node *create_instance(bool p_replace = false, const Ref<PackedScene> &p_custom_scene = Ref<PackedScene>());
- void replace_by_instance(const Ref<PackedScene> &p_custom_scene = Ref<PackedScene>());
InstancePlaceholder();
};
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 350959dcc3..8ceac74bb8 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -30,6 +30,8 @@
#include "node.h"
+#include <stdint.h>
+
#include "core/core_string_names.h"
#include "core/io/resource_loader.h"
#include "core/message_queue.h"
@@ -498,22 +500,38 @@ bool Node::is_network_master() const {
/***** RPC CONFIG ********/
-void Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) {
+uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) {
- if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) {
- data.rpc_methods.erase(p_method);
+ uint16_t mid = get_node_rpc_method_id(p_method);
+ if (mid == UINT16_MAX) {
+ // It's new
+ NetData nd;
+ nd.name = p_method;
+ nd.mode = p_mode;
+ data.rpc_methods.push_back(nd);
+ return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15);
} else {
- data.rpc_methods[p_method] = p_mode;
- };
+ int c_mid = (~(1 << 15)) & mid;
+ data.rpc_methods.write[c_mid].mode = p_mode;
+ return mid;
+ }
}
-void Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) {
+uint16_t Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) {
- if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) {
- data.rpc_properties.erase(p_property);
+ uint16_t pid = get_node_rset_property_id(p_property);
+ if (pid == UINT16_MAX) {
+ // It's new
+ NetData nd;
+ nd.name = p_property;
+ nd.mode = p_mode;
+ data.rpc_properties.push_back(nd);
+ return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15);
} else {
- data.rpc_properties[p_property] = p_mode;
- };
+ int c_pid = (~(1 << 15)) & pid;
+ data.rpc_properties.write[c_pid].mode = p_mode;
+ return pid;
+ }
}
/***** RPC FUNCTIONS ********/
@@ -731,12 +749,94 @@ void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
multiplayer = p_multiplayer;
}
-const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) {
- return data.rpc_methods.find(p_method);
+uint16_t Node::get_node_rpc_method_id(const StringName &p_method) const {
+ for (int i = 0; i < data.rpc_methods.size(); i++) {
+ if (data.rpc_methods[i].name == p_method) {
+ // Returns `i` with the high bit set to 1 so we know that this id comes
+ // from the node and not the script.
+ return i | (1 << 15);
+ }
+ }
+ return UINT16_MAX;
}
-const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) {
- return data.rpc_properties.find(p_property);
+StringName Node::get_node_rpc_method(const uint16_t p_rpc_method_id) const {
+ // Make sure this is a node generated ID.
+ if (((1 << 15) & p_rpc_method_id) > 0) {
+ int mid = (~(1 << 15)) & p_rpc_method_id;
+ if (mid < data.rpc_methods.size())
+ return data.rpc_methods[mid].name;
+ }
+ return StringName();
+}
+
+MultiplayerAPI::RPCMode Node::get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ // Make sure this is a node generated ID.
+ if (((1 << 15) & p_rpc_method_id) > 0) {
+ int mid = (~(1 << 15)) & p_rpc_method_id;
+ if (mid < data.rpc_methods.size())
+ return data.rpc_methods[mid].mode;
+ }
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+MultiplayerAPI::RPCMode Node::get_node_rpc_mode(const StringName &p_method) const {
+ return get_node_rpc_mode_by_id(get_node_rpc_method_id(p_method));
+}
+
+uint16_t Node::get_node_rset_property_id(const StringName &p_property) const {
+ for (int i = 0; i < data.rpc_properties.size(); i++) {
+ if (data.rpc_properties[i].name == p_property) {
+ // Returns `i` with the high bit set to 1 so we know that this id comes
+ // from the node and not the script.
+ return i | (1 << 15);
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName Node::get_node_rset_property(const uint16_t p_rset_property_id) const {
+ // Make sure this is a node generated ID.
+ if (((1 << 15) & p_rset_property_id) > 0) {
+ int mid = (~(1 << 15)) & p_rset_property_id;
+ if (mid < data.rpc_properties.size())
+ return data.rpc_properties[mid].name;
+ }
+ return StringName();
+}
+
+MultiplayerAPI::RPCMode Node::get_node_rset_mode_by_id(const uint16_t p_rset_property_id) const {
+ if (((1 << 15) & p_rset_property_id) > 0) {
+ int mid = (~(1 << 15)) & p_rset_property_id;
+ if (mid < data.rpc_properties.size())
+ return data.rpc_properties[mid].mode;
+ }
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+MultiplayerAPI::RPCMode Node::get_node_rset_mode(const StringName &p_property) const {
+ return get_node_rset_mode_by_id(get_node_rset_property_id(p_property));
+}
+
+String Node::get_rpc_md5() const {
+ String rpc_list;
+ for (int i = 0; i < data.rpc_methods.size(); i += 1) {
+ rpc_list += String(data.rpc_methods[i].name);
+ }
+ for (int i = 0; i < data.rpc_properties.size(); i += 1) {
+ rpc_list += String(data.rpc_properties[i].name);
+ }
+ if (get_script_instance()) {
+ Vector<ScriptNetData> rpc = get_script_instance()->get_rpc_methods();
+ for (int i = 0; i < rpc.size(); i += 1) {
+ rpc_list += String(rpc[i].name);
+ }
+ rpc = get_script_instance()->get_rset_properties();
+ for (int i = 0; i < rpc.size(); i += 1) {
+ rpc_list += String(rpc[i].name);
+ }
+ }
+ return rpc_list.md5_text();
}
bool Node::can_process_notification(int p_what) const {
@@ -1192,7 +1292,7 @@ void Node::add_child_below_node(Node *p_node, Node *p_child, bool p_legible_uniq
if (is_a_parent_of(p_node)) {
move_child(p_child, p_node->get_position_in_parent() + 1);
} else {
- WARN_PRINTS("Cannot move under node " + p_node->get_name() + " as " + p_child->get_name() + " does not share a parent.");
+ WARN_PRINT("Cannot move under node " + p_node->get_name() + " as " + p_child->get_name() + " does not share a parent.");
}
}
@@ -2898,11 +2998,6 @@ void Node::_bind_methods() {
ADD_GROUP("Pause", "pause_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode");
-#ifdef ENABLE_DEPRECATED
- //no longer exists, but remains for compatibility (keep previous scenes folded
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor/display_folded", PROPERTY_HINT_NONE, "", 0), "set_display_folded", "is_displayed_folded");
-#endif
-
ADD_PROPERTY(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner");
diff --git a/scene/main/node.h b/scene/main/node.h
index 6f5544d654..02c828e8ff 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -85,6 +85,11 @@ private:
GroupData() { persistent = false; }
};
+ struct NetData {
+ StringName name;
+ MultiplayerAPI::RPCMode mode;
+ };
+
struct Data {
String filename;
@@ -118,8 +123,8 @@ private:
Node *pause_owner;
int network_master;
- Map<StringName, MultiplayerAPI::RPCMode> rpc_methods;
- Map<StringName, MultiplayerAPI::RPCMode> rpc_properties;
+ Vector<NetData> rpc_methods;
+ Vector<NetData> rpc_properties;
// variables used to properly sort the node when processing, ignored otherwise
//should move all the stuff below to bits
@@ -427,8 +432,8 @@ public:
int get_network_master() const;
bool is_network_master() const;
- void rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC
- void rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC
+ uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC
+ uint16_t rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC
void rpc(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode
void rpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode
@@ -446,8 +451,22 @@ public:
Ref<MultiplayerAPI> get_multiplayer() const;
Ref<MultiplayerAPI> get_custom_multiplayer() const;
void set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
- const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rpc_mode(const StringName &p_method);
- const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rset_mode(const StringName &p_property);
+
+ /// Returns the rpc method ID, otherwise UINT32_MAX
+ uint16_t get_node_rpc_method_id(const StringName &p_method) const;
+ StringName get_node_rpc_method(const uint16_t p_rpc_method_id) const;
+ MultiplayerAPI::RPCMode get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ MultiplayerAPI::RPCMode get_node_rpc_mode(const StringName &p_method) const;
+
+ /// Returns the rpc property ID, otherwise UINT32_MAX
+ uint16_t get_node_rset_property_id(const StringName &p_property) const;
+ StringName get_node_rset_property(const uint16_t p_rset_property_id) const;
+ MultiplayerAPI::RPCMode get_node_rset_mode_by_id(const uint16_t p_rpc_method_id) const;
+ MultiplayerAPI::RPCMode get_node_rset_mode(const StringName &p_property) const;
+
+ /// Can be used to check if the rpc methods and the rset properties are the
+ /// same across the peers.
+ String get_rpc_md5() const;
Node();
~Node();
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 238d6c20cc..a27f8c4d94 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -46,6 +46,7 @@
#include "scene/resources/mesh.h"
#include "scene/resources/packed_scene.h"
#include "scene/scene_string_names.h"
+#include "servers/navigation_server.h"
#include "servers/physics_2d_server.h"
#include "servers/physics_server.h"
#include "viewport.h"
@@ -791,11 +792,11 @@ Ref<Material> SceneTree::get_debug_navigation_material() {
if (navigation_material.is_valid())
return navigation_material;
- 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_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+ line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
line_material->set_albedo(get_debug_navigation_color());
navigation_material = line_material;
@@ -808,11 +809,11 @@ Ref<Material> SceneTree::get_debug_navigation_disabled_material() {
if (navigation_disabled_material.is_valid())
return navigation_disabled_material;
- 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_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+ line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
line_material->set_albedo(get_debug_navigation_disabled_color());
navigation_disabled_material = line_material;
@@ -824,11 +825,11 @@ Ref<Material> SceneTree::get_debug_collision_material() {
if (collision_material.is_valid())
return collision_material;
- 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_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+ line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
line_material->set_albedo(get_debug_collisions_color());
collision_material = line_material;
@@ -843,11 +844,11 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() {
debug_contact_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
- Ref<SpatialMaterial> mat = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ Ref<StandardMaterial3D> mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+ mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
mat->set_albedo(get_debug_collision_contact_color());
Vector3 diamond[6] = {
@@ -896,6 +897,7 @@ void SceneTree::set_pause(bool p_enabled) {
if (p_enabled == pause)
return;
pause = p_enabled;
+ NavigationServer::get_singleton()->set_active(!p_enabled);
PhysicsServer::get_singleton()->set_active(!p_enabled);
Physics2DServer::get_singleton()->set_active(!p_enabled);
if (get_root())
@@ -2073,20 +2075,10 @@ SceneTree::SceneTree() {
int ref_atlas_size = GLOBAL_DEF("rendering/quality/reflections/atlas_size", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_size", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_size", PROPERTY_HINT_RANGE, "0,8192,or_greater")); //next_power_of_2 will return a 0 as min value
- int ref_atlas_subdiv = GLOBAL_DEF("rendering/quality/reflections/atlas_subdiv", 8);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_subdiv", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_subdiv", PROPERTY_HINT_RANGE, "0,32,or_greater")); //next_power_of_2 will return a 0 as min value
int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"));
root->set_msaa(Viewport::MSAA(msaa_mode));
- GLOBAL_DEF("rendering/quality/depth/hdr", true);
- GLOBAL_DEF("rendering/quality/depth/hdr.mobile", false);
-
- bool hdr = GLOBAL_GET("rendering/quality/depth/hdr");
- root->set_hdr(hdr);
-
- VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(), ref_atlas_size, ref_atlas_subdiv);
-
{ //load default fallback environment
//get possible extensions
List<String> exts;
@@ -2112,7 +2104,7 @@ SceneTree::SceneTree() {
ProjectSettings::get_singleton()->set("rendering/environment/default_environment", "");
} else {
//file was erased, notify user.
- ERR_PRINTS(RTR("Default Environment as specified in Project Settings (Rendering -> Environment -> Default Environment) could not be loaded."));
+ ERR_PRINT(RTR("Default Environment as specified in Project Settings (Rendering -> Environment -> Default Environment) could not be loaded."));
}
}
}
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 55304fb12d..565c58fac1 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -411,6 +411,9 @@ public:
bool is_refusing_new_network_connections() const;
static void add_idle_callback(IdleCallback p_callback);
+
+ //default texture settings
+
SceneTree();
~SceneTree();
};
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index a56903636f..748a713110 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -74,10 +74,13 @@ void ViewportTexture::setup_local_to_scene() {
vp->viewport_textures.insert(this);
- VS::get_singleton()->texture_set_proxy(proxy, vp->texture_rid);
-
- vp->texture_flags = flags;
- VS::get_singleton()->texture_set_flags(vp->texture_rid, flags);
+ if (proxy_ph.is_valid()) {
+ VS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid);
+ VS::get_singleton()->free(proxy_ph);
+ } else {
+ ERR_FAIL_COND(proxy.is_valid()); //should be invalid
+ proxy = VS::get_singleton()->texture_proxy_create(vp->texture_rid);
+ }
}
void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) {
@@ -115,6 +118,10 @@ Size2 ViewportTexture::get_size() const {
RID ViewportTexture::get_rid() const {
//ERR_FAIL_COND_V_MSG(!vp, RID(), "Viewport Texture must be set to use it.");
+ if (proxy.is_null()) {
+ proxy_ph = VS::get_singleton()->texture_2d_placeholder_create();
+ proxy = VS::get_singleton()->texture_proxy_create(proxy_ph);
+ }
return proxy;
}
@@ -125,21 +132,7 @@ bool ViewportTexture::has_alpha() const {
Ref<Image> ViewportTexture::get_data() const {
ERR_FAIL_COND_V_MSG(!vp, Ref<Image>(), "Viewport Texture must be set to use it.");
- return VS::get_singleton()->texture_get_data(vp->texture_rid);
-}
-void ViewportTexture::set_flags(uint32_t p_flags) {
- flags = p_flags;
-
- if (!vp)
- return;
-
- vp->texture_flags = flags;
- VS::get_singleton()->texture_set_flags(vp->texture_rid, flags);
-}
-
-uint32_t ViewportTexture::get_flags() const {
-
- return flags;
+ return VS::get_singleton()->texture_2d_get(vp->texture_rid);
}
void ViewportTexture::_bind_methods() {
@@ -153,9 +146,7 @@ void ViewportTexture::_bind_methods() {
ViewportTexture::ViewportTexture() {
vp = NULL;
- flags = 0;
set_local_to_scene(true);
- proxy = VS::get_singleton()->texture_create();
}
ViewportTexture::~ViewportTexture() {
@@ -164,7 +155,12 @@ ViewportTexture::~ViewportTexture() {
vp->viewport_textures.erase(this);
}
- VS::get_singleton()->free(proxy);
+ if (proxy_ph.is_valid()) {
+ VS::get_singleton()->free(proxy_ph);
+ }
+ if (proxy.is_valid()) {
+ VS::get_singleton()->free(proxy);
+ }
}
/////////////////////////////////////
@@ -304,7 +300,7 @@ void Viewport::_notification(int p_what) {
//3D
PhysicsServer::get_singleton()->space_set_debug_contacts(find_world()->get_space(), get_tree()->get_collision_debug_contact_count());
contact_3d_debug_multimesh = VisualServer::get_singleton()->multimesh_create();
- VisualServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_8BIT);
+ VisualServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), VS::MULTIMESH_TRANSFORM_3D, true);
VisualServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0);
VisualServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid());
contact_3d_debug_instance = VisualServer::get_singleton()->instance_create();
@@ -416,7 +412,7 @@ void Viewport::_notification(int p_what) {
#ifndef _3D_DISABLED
Vector2 last_pos(1e20, 1e20);
CollisionObject *last_object = NULL;
- ObjectID last_id = 0;
+ ObjectID last_id;
#endif
PhysicsDirectSpaceState::RayResult result;
Physics2DDirectSpaceState *ss2d = Physics2DServer::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
@@ -536,7 +532,7 @@ void Viewport::_notification(int p_what) {
} else {
// This Viewport's builtin canvas
canvas_transform = get_canvas_transform();
- canvas_layer_id = 0;
+ canvas_layer_id = ObjectID();
}
Vector2 point = canvas_transform.affine_inverse().xform(pos);
@@ -544,7 +540,7 @@ void Viewport::_notification(int p_what) {
int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true);
for (int i = 0; i < rc; i++) {
- if (res[i].collider_id && res[i].collider) {
+ if (res[i].collider_id.is_valid() && res[i].collider) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
if (co) {
bool send_event = true;
@@ -598,18 +594,18 @@ void Viewport::_notification(int p_what) {
#ifndef _3D_DISABLED
bool captured = false;
- if (physics_object_capture != 0) {
+ if (physics_object_capture.is_valid()) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_capture));
if (co && camera) {
_collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0);
captured = true;
if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
- physics_object_capture = 0;
+ physics_object_capture = ObjectID();
}
} else {
- physics_object_capture = 0;
+ physics_object_capture = ObjectID();
}
}
@@ -617,7 +613,7 @@ void Viewport::_notification(int p_what) {
//none
} else if (pos == last_pos) {
- if (last_id) {
+ if (last_id.is_valid()) {
if (ObjectDB::get_instance(last_id) && last_object) {
//good, exists
_collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape);
@@ -637,7 +633,7 @@ void Viewport::_notification(int p_what) {
if (space) {
bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true);
- ObjectID new_collider = 0;
+ ObjectID new_collider;
if (col) {
CollisionObject *co = Object::cast_to<CollisionObject>(result.collider);
@@ -655,7 +651,7 @@ void Viewport::_notification(int p_what) {
if (is_mouse && new_collider != physics_object_over) {
- if (physics_object_over) {
+ if (physics_object_over.is_valid()) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_over));
if (co) {
@@ -663,7 +659,7 @@ void Viewport::_notification(int p_what) {
}
}
- if (new_collider) {
+ if (new_collider.is_valid()) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(new_collider));
if (co) {
@@ -1334,17 +1330,6 @@ Ref<ViewportTexture> Viewport::get_texture() const {
return default_texture;
}
-void Viewport::set_vflip(bool p_enable) {
-
- vflip = p_enable;
- VisualServer::get_singleton()->viewport_set_vflip(viewport, p_enable);
-}
-
-bool Viewport::get_vflip() const {
-
- return vflip;
-}
-
void Viewport::set_clear_mode(ClearMode p_mode) {
clear_mode = p_mode;
@@ -1845,7 +1830,7 @@ bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_che
void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
- ERR_FAIL_COND(p_event.is_null())
+ ERR_FAIL_COND(p_event.is_null());
//?
/*
@@ -2519,7 +2504,7 @@ void Viewport::_gui_remove_from_modal_stack(List<Control *>::Element *MI, Object
gui.modal_stack.erase(MI);
- if (p_prev_focus_owner) {
+ if (p_prev_focus_owner.is_valid()) {
// for previous window in stack, pass the focus so it feels more
// natural
@@ -2716,14 +2701,15 @@ void Viewport::_drop_physics_mouseover() {
}
#ifndef _3D_DISABLED
- if (physics_object_over) {
+ if (physics_object_over.is_valid()) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_over));
if (co) {
co->_mouse_exit();
}
}
- physics_object_over = physics_object_capture = 0;
+ physics_object_over = ObjectID();
+ physics_object_capture = ObjectID();
#endif
}
@@ -2733,7 +2719,7 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) {
if (gui.key_focus)
p_control->_modal_set_prev_focus_owner(gui.key_focus->get_instance_id());
else
- p_control->_modal_set_prev_focus_owner(0);
+ p_control->_modal_set_prev_focus_owner(ObjectID());
if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus) && !gui.mouse_click_grabber) {
@@ -2952,26 +2938,6 @@ bool Viewport::is_input_disabled() const {
return disable_input;
}
-void Viewport::set_disable_3d(bool p_disable) {
- disable_3d = p_disable;
- VS::get_singleton()->viewport_set_disable_3d(viewport, p_disable);
-}
-
-bool Viewport::is_3d_disabled() const {
-
- return disable_3d;
-}
-
-void Viewport::set_keep_3d_linear(bool p_keep_3d_linear) {
- keep_3d_linear = p_keep_3d_linear;
- VS::get_singleton()->viewport_set_keep_3d_linear(viewport, keep_3d_linear);
-}
-
-bool Viewport::get_keep_3d_linear() const {
-
- return keep_3d_linear;
-}
-
Variant Viewport::gui_get_drag_data() const {
return gui.drag_data;
}
@@ -3012,30 +2978,6 @@ Viewport::MSAA Viewport::get_msaa() const {
return msaa;
}
-void Viewport::set_hdr(bool p_hdr) {
-
- if (hdr == p_hdr)
- return;
-
- hdr = p_hdr;
- VS::get_singleton()->viewport_set_hdr(viewport, p_hdr);
-}
-
-bool Viewport::get_hdr() const {
-
- return hdr;
-}
-
-void Viewport::set_usage(Usage p_usage) {
-
- usage = p_usage;
- VS::get_singleton()->viewport_set_usage(viewport, VS::ViewportUsage(p_usage));
-}
-
-Viewport::Usage Viewport::get_usage() const {
- return usage;
-}
-
void Viewport::set_debug_draw(DebugDraw p_debug_draw) {
debug_draw = p_debug_draw;
@@ -3094,9 +3036,50 @@ bool Viewport::is_handling_input_locally() const {
}
void Viewport::_validate_property(PropertyInfo &property) const {
+}
+
+void Viewport::set_default_canvas_item_texture_filter(DefaultCanvasItemTextureFilter p_filter) {
+ if (default_canvas_item_texture_filter == p_filter) {
+ return;
+ }
+ default_canvas_item_texture_filter = p_filter;
+ _propagate_update_default_filter(this);
+}
+
+Viewport::DefaultCanvasItemTextureFilter Viewport::get_default_canvas_item_texture_filter() const {
+ return default_canvas_item_texture_filter;
+}
+
+void Viewport::set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRepeat p_repeat) {
+ if (default_canvas_item_texture_repeat == p_repeat) {
+ return;
+ }
+ default_canvas_item_texture_repeat = p_repeat;
+ _propagate_update_default_repeat(this);
+}
+Viewport::DefaultCanvasItemTextureRepeat Viewport::get_default_canvas_item_texture_repeat() const {
+ return default_canvas_item_texture_repeat;
+}
+
+void Viewport::_propagate_update_default_filter(Node *p_node) {
+ CanvasItem *ci = Object::cast_to<CanvasItem>(p_node);
+ if (ci) {
+ ci->_update_texture_filter_changed(false);
+ }
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _propagate_update_default_filter(p_node->get_child(i));
+ }
+}
+
+void Viewport::_propagate_update_default_repeat(Node *p_node) {
+ CanvasItem *ci = Object::cast_to<CanvasItem>(p_node);
+ if (ci) {
+ ci->_update_texture_repeat_changed(false);
+ }
- if (VisualServer::get_singleton()->is_low_end() && property.name == "hdr") {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _propagate_update_default_repeat(p_node->get_child(i));
}
}
@@ -3135,9 +3118,6 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size_override_stretch", "enabled"), &Viewport::set_size_override_stretch);
ClassDB::bind_method(D_METHOD("is_size_override_stretch_enabled"), &Viewport::is_size_override_stretch_enabled);
- ClassDB::bind_method(D_METHOD("set_vflip", "enable"), &Viewport::set_vflip);
- ClassDB::bind_method(D_METHOD("get_vflip"), &Viewport::get_vflip);
-
ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &Viewport::set_clear_mode);
ClassDB::bind_method(D_METHOD("get_clear_mode"), &Viewport::get_clear_mode);
@@ -3147,12 +3127,6 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa);
ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa);
- ClassDB::bind_method(D_METHOD("set_hdr", "enable"), &Viewport::set_hdr);
- ClassDB::bind_method(D_METHOD("get_hdr"), &Viewport::get_hdr);
-
- ClassDB::bind_method(D_METHOD("set_usage", "usage"), &Viewport::set_usage);
- ClassDB::bind_method(D_METHOD("get_usage"), &Viewport::get_usage);
-
ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw);
ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw);
@@ -3195,12 +3169,6 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input);
ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled);
- ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d);
- ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled);
-
- ClassDB::bind_method(D_METHOD("set_keep_3d_linear", "keep_3d_linear"), &Viewport::set_keep_3d_linear);
- ClassDB::bind_method(D_METHOD("get_keep_3d_linear"), &Viewport::get_keep_3d_linear);
-
ClassDB::bind_method(D_METHOD("_gui_show_tooltip"), &Viewport::_gui_show_tooltip);
ClassDB::bind_method(D_METHOD("_gui_remove_focus"), &Viewport::_gui_remove_focus);
ClassDB::bind_method(D_METHOD("_post_gui_grab_click_focus"), &Viewport::_post_gui_grab_click_focus);
@@ -3220,6 +3188,12 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_handle_input_locally", "enable"), &Viewport::set_handle_input_locally);
ClassDB::bind_method(D_METHOD("is_handling_input_locally"), &Viewport::is_handling_input_locally);
+ ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_filter", "mode"), &Viewport::set_default_canvas_item_texture_filter);
+ ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_filter"), &Viewport::get_default_canvas_item_texture_filter);
+
+ ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_repeat", "mode"), &Viewport::set_default_canvas_item_texture_repeat);
+ ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_repeat"), &Viewport::get_default_canvas_item_texture_repeat);
+
ClassDB::bind_method(D_METHOD("_subwindow_visibility_changed"), &Viewport::_subwindow_visibility_changed);
ClassDB::bind_method(D_METHOD("_own_world_changed"), &Viewport::_own_world_changed);
@@ -3235,16 +3209,14 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
ADD_GROUP("Rendering", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_3d_linear"), "set_keep_3d_linear", "get_keep_3d_linear");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_ENUM, "2D,2D No-Sampling,3D,3D No-Effects"), "set_usage", "get_usage");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_direct_to_screen"), "set_use_render_direct_to_screen", "is_using_render_direct_to_screen");
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw");
ADD_GROUP("Render Target", "render_target_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode");
+ ADD_GROUP("Canvas Items", "canvas_item_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirror"), "set_default_canvas_item_texture_repeat", "get_default_canvas_item_texture_repeat");
ADD_GROUP("Audio Listener", "audio_listener_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_2d"), "set_as_audio_listener_2d", "is_audio_listener_2d");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener", "is_audio_listener");
@@ -3292,20 +3264,34 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(DEBUG_DRAW_OVERDRAW);
BIND_ENUM_CONSTANT(DEBUG_DRAW_WIREFRAME);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_ALBEDO);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_LIGHTING);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_EMISSION);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_SHADOW_ATLAS);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_SCENE_LUMINANCE);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_SSAO);
+
BIND_ENUM_CONSTANT(MSAA_DISABLED);
BIND_ENUM_CONSTANT(MSAA_2X);
BIND_ENUM_CONSTANT(MSAA_4X);
BIND_ENUM_CONSTANT(MSAA_8X);
BIND_ENUM_CONSTANT(MSAA_16X);
- BIND_ENUM_CONSTANT(USAGE_2D);
- BIND_ENUM_CONSTANT(USAGE_2D_NO_SAMPLING);
- BIND_ENUM_CONSTANT(USAGE_3D);
- BIND_ENUM_CONSTANT(USAGE_3D_NO_EFFECTS);
-
BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS);
BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER);
BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME);
+
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR);
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS);
+
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX);
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
+ BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX);
}
void Viewport::_subwindow_visibility_changed() {
@@ -3321,14 +3307,13 @@ Viewport::Viewport() {
viewport = VisualServer::get_singleton()->viewport_create();
texture_rid = VisualServer::get_singleton()->viewport_get_texture(viewport);
- texture_flags = 0;
render_direct_to_screen = false;
default_texture.instance();
default_texture->vp = const_cast<Viewport *>(this);
viewport_textures.insert(default_texture.ptr());
- VS::get_singleton()->texture_set_proxy(default_texture->proxy, texture_rid);
+ default_texture->proxy = VS::get_singleton()->texture_proxy_create(texture_rid);
//internal_listener = SpatialSoundServer::get_singleton()->listener_create();
audio_listener = false;
@@ -3346,14 +3331,10 @@ Viewport::Viewport() {
size_override_size = Size2(1, 1);
gen_mipmaps = false;
- vflip = false;
-
//clear=true;
update_mode = UPDATE_WHEN_VISIBLE;
physics_object_picking = false;
- physics_object_capture = 0;
- physics_object_over = 0;
physics_has_last_mousepos = false;
physics_last_mousepos = Vector2(Math_INF, Math_INF);
@@ -3373,8 +3354,6 @@ Viewport::Viewport() {
unhandled_key_input_group = "_vp_unhandled_key_input" + id;
disable_input = false;
- disable_3d = false;
- keep_3d_linear = false;
//window tooltip
gui.tooltip_timer = -1;
@@ -3393,9 +3372,7 @@ Viewport::Viewport() {
gui.last_mouse_focus = NULL;
msaa = MSAA_DISABLED;
- hdr = true;
- usage = USAGE_3D;
debug_draw = DEBUG_DRAW_DISABLED;
clear_mode = CLEAR_MODE_ALWAYS;
@@ -3407,7 +3384,9 @@ Viewport::Viewport() {
physics_last_mouse_state.mouse_mask = 0;
local_input_handled = false;
handle_input_locally = true;
- physics_last_id = 0; //ensures first time there will be a check
+
+ default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
+ default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
}
Viewport::~Viewport() {
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 79b606cda3..44d4c89ed1 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -49,17 +49,17 @@ class Timer;
class Viewport;
class CollisionObject;
-class ViewportTexture : public Texture {
+class ViewportTexture : public Texture2D {
- GDCLASS(ViewportTexture, Texture);
+ GDCLASS(ViewportTexture, Texture2D);
NodePath path;
friend class Viewport;
Viewport *vp;
- uint32_t flags;
- RID proxy;
+ mutable RID proxy_ph;
+ mutable RID proxy;
protected:
static void _bind_methods();
@@ -77,9 +77,6 @@ public:
virtual bool has_alpha() const;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
virtual Ref<Image> get_data() const;
ViewportTexture();
@@ -107,7 +104,6 @@ public:
SHADOW_ATLAS_QUADRANT_SUBDIV_256,
SHADOW_ATLAS_QUADRANT_SUBDIV_1024,
SHADOW_ATLAS_QUADRANT_SUBDIV_MAX,
-
};
enum MSAA {
@@ -118,13 +114,6 @@ public:
MSAA_16X,
};
- enum Usage {
- USAGE_2D,
- USAGE_2D_NO_SAMPLING,
- USAGE_3D,
- USAGE_3D_NO_EFFECTS,
- };
-
enum RenderInfo {
RENDER_INFO_OBJECTS_IN_FRAME,
@@ -139,8 +128,18 @@ public:
enum DebugDraw {
DEBUG_DRAW_DISABLED,
DEBUG_DRAW_UNSHADED,
+ DEBUG_DRAW_LIGHTING,
DEBUG_DRAW_OVERDRAW,
DEBUG_DRAW_WIREFRAME,
+ DEBUG_DRAW_NORMAL_BUFFER,
+ DEBUG_DRAW_GI_PROBE_ALBEDO,
+ DEBUG_DRAW_GI_PROBE_LIGHTING,
+ DEBUG_DRAW_GI_PROBE_EMISSION,
+ DEBUG_DRAW_SHADOW_ATLAS,
+ DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS,
+ DEBUG_DRAW_SCENE_LUMINANCE,
+ DEBUG_DRAW_SSAO,
+ DEBUG_DRAW_ROUGHNESS_LIMITER
};
enum ClearMode {
@@ -150,6 +149,21 @@ public:
CLEAR_MODE_ONLY_NEXT_FRAME
};
+ enum DefaultCanvasItemTextureFilter {
+ DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST,
+ DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR,
+ DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS,
+ DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS,
+ DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX
+ };
+
+ enum DefaultCanvasItemTextureRepeat {
+ DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED,
+ DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED,
+ DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR,
+ DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX,
+ };
+
private:
friend class ViewportTexture;
@@ -214,7 +228,6 @@ private:
Rect2 last_vp_rect;
bool transparent_bg;
- bool vflip;
ClearMode clear_mode;
bool filter;
bool gen_mipmaps;
@@ -266,22 +279,15 @@ private:
void _update_stretch_transform();
void _update_global_transform();
- bool disable_3d;
- bool keep_3d_linear;
UpdateMode update_mode;
RID texture_rid;
- uint32_t texture_flags;
DebugDraw debug_draw;
- Usage usage;
-
int shadow_atlas_size;
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
MSAA msaa;
- bool hdr;
-
Ref<ViewportTexture> default_texture;
Set<ViewportTexture *> viewport_textures;
@@ -320,6 +326,12 @@ private:
GUI();
} gui;
+ DefaultCanvasItemTextureFilter default_canvas_item_texture_filter;
+ DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat;
+
+ void _propagate_update_default_filter(Node *p_node);
+ void _propagate_update_default_repeat(Node *p_node);
+
bool disable_input;
void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input);
@@ -474,9 +486,6 @@ public:
void set_size_override_stretch(bool p_enable);
bool is_size_override_stretch_enabled() const;
- void set_vflip(bool p_enable);
- bool get_vflip() const;
-
void set_clear_mode(ClearMode p_mode);
ClearMode get_clear_mode() const;
@@ -493,9 +502,6 @@ public:
void set_msaa(MSAA p_msaa);
MSAA get_msaa() const;
- void set_hdr(bool p_hdr);
- bool get_hdr() const;
-
Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const;
Vector2 get_camera_rect_size() const;
@@ -508,12 +514,6 @@ public:
void set_disable_input(bool p_disable);
bool is_input_disabled() const;
- void set_disable_3d(bool p_disable);
- bool is_3d_disabled() const;
-
- void set_keep_3d_linear(bool p_keep_3d_linear);
- bool get_keep_3d_linear() const;
-
void set_attach_to_screen_rect(const Rect2 &p_rect);
Rect2 get_attach_to_screen_rect() const;
@@ -536,9 +536,6 @@ public:
virtual String get_configuration_warning() const;
- void set_usage(Usage p_usage);
- Usage get_usage() const;
-
void set_debug_draw(DebugDraw p_debug_draw);
DebugDraw get_debug_draw() const;
@@ -557,6 +554,12 @@ public:
bool gui_is_dragging() const;
+ void set_default_canvas_item_texture_filter(DefaultCanvasItemTextureFilter p_filter);
+ DefaultCanvasItemTextureFilter get_default_canvas_item_texture_filter() const;
+
+ void set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRepeat p_repeat);
+ DefaultCanvasItemTextureRepeat get_default_canvas_item_texture_repeat() const;
+
Viewport();
~Viewport();
};
@@ -564,9 +567,10 @@ public:
VARIANT_ENUM_CAST(Viewport::UpdateMode);
VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
VARIANT_ENUM_CAST(Viewport::MSAA);
-VARIANT_ENUM_CAST(Viewport::Usage);
VARIANT_ENUM_CAST(Viewport::DebugDraw);
VARIANT_ENUM_CAST(Viewport::ClearMode);
VARIANT_ENUM_CAST(Viewport::RenderInfo);
+VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureFilter);
+VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureRepeat);
#endif
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index c0c6b864a5..40f24ece87 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -50,6 +50,8 @@
#include "scene/2d/mesh_instance_2d.h"
#include "scene/2d/multimesh_instance_2d.h"
#include "scene/2d/navigation_2d.h"
+#include "scene/2d/navigation_agent_2d.h"
+#include "scene/2d/navigation_obstacle_2d.h"
#include "scene/2d/parallax_background.h"
#include "scene/2d/parallax_layer.h"
#include "scene/2d/particles_2d.h"
@@ -71,7 +73,6 @@
#include "scene/animation/animation_node_state_machine.h"
#include "scene/animation/animation_player.h"
#include "scene/animation/animation_tree.h"
-#include "scene/animation/animation_tree_player.h"
#include "scene/animation/root_motion_view.h"
#include "scene/animation/tween.h"
#include "scene/audio/audio_stream_player.h"
@@ -145,6 +146,7 @@
#include "scene/resources/material.h"
#include "scene/resources/mesh.h"
#include "scene/resources/mesh_data_tool.h"
+#include "scene/resources/navigation_mesh.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/particles_material.h"
#include "scene/resources/physics_material.h"
@@ -168,9 +170,6 @@
#include "scene/resources/world_2d.h"
#include "scene/scene_string_names.h"
-#include "scene/3d/spatial.h"
-#include "scene/3d/world_environment.h"
-
#ifndef _3D_DISABLED
#include "scene/3d/area.h"
#include "scene/3d/arvr_nodes.h"
@@ -189,7 +188,9 @@
#include "scene/3d/mesh_instance.h"
#include "scene/3d/multimesh_instance.h"
#include "scene/3d/navigation.h"
-#include "scene/3d/navigation_mesh.h"
+#include "scene/3d/navigation_agent.h"
+#include "scene/3d/navigation_mesh_instance.h"
+#include "scene/3d/navigation_obstacle.h"
#include "scene/3d/particles.h"
#include "scene/3d/path.h"
#include "scene/3d/physics_body.h"
@@ -201,10 +202,12 @@
#include "scene/3d/remote_transform.h"
#include "scene/3d/skeleton.h"
#include "scene/3d/soft_body.h"
+#include "scene/3d/spatial.h"
#include "scene/3d/spring_arm.h"
#include "scene/3d/sprite_3d.h"
#include "scene/3d/vehicle_body.h"
#include "scene/3d/visibility_notifier.h"
+#include "scene/3d/world_environment.h"
#include "scene/animation/skeleton_ik.h"
#include "scene/resources/environment.h"
#include "scene/resources/mesh_library.h"
@@ -370,7 +373,6 @@ void register_scene_types() {
ClassDB::register_class<AnimationPlayer>();
ClassDB::register_class<Tween>();
- ClassDB::register_class<AnimationTreePlayer>();
ClassDB::register_class<AnimationTree>();
ClassDB::register_class<AnimationNode>();
ClassDB::register_class<AnimationRootNode>();
@@ -417,14 +419,11 @@ void register_scene_types() {
ClassDB::register_class<ReflectionProbe>();
ClassDB::register_class<GIProbe>();
ClassDB::register_class<GIProbeData>();
- ClassDB::register_class<BakedLightmap>();
- ClassDB::register_class<BakedLightmapData>();
+ //ClassDB::register_class<BakedLightmap>();
+ //ClassDB::register_class<BakedLightmapData>();
ClassDB::register_class<Particles>();
ClassDB::register_class<CPUParticles>();
ClassDB::register_class<Position3D>();
- ClassDB::register_class<NavigationMeshInstance>();
- ClassDB::register_class<NavigationMesh>();
- ClassDB::register_class<Navigation>();
ClassDB::register_class<RootMotionView>();
ClassDB::set_class_enabled("RootMotionView", false); //disabled by default, enabled by editor
@@ -469,9 +468,15 @@ void register_scene_types() {
ClassDB::register_class<ConeTwistJoint>();
ClassDB::register_class<Generic6DOFJoint>();
+ ClassDB::register_class<Navigation>();
+ ClassDB::register_class<NavigationMeshInstance>();
+ ClassDB::register_class<NavigationAgent>();
+ ClassDB::register_class<NavigationObstacle>();
+
OS::get_singleton()->yield(); //may take time to init
#endif
+ ClassDB::register_class<NavigationMesh>();
AcceptDialog::set_swap_ok_cancel(GLOBAL_DEF("gui/common/swap_ok_cancel", bool(OS::get_singleton()->get_swap_ok_cancel())));
@@ -519,7 +524,7 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeVectorDecompose>();
ClassDB::register_class<VisualShaderNodeTransformDecompose>();
ClassDB::register_class<VisualShaderNodeTexture>();
- ClassDB::register_class<VisualShaderNodeCubeMap>();
+ ClassDB::register_class<VisualShaderNodeCubemap>();
ClassDB::register_virtual_class<VisualShaderNodeUniform>();
ClassDB::register_class<VisualShaderNodeScalarUniform>();
ClassDB::register_class<VisualShaderNodeBooleanUniform>();
@@ -528,7 +533,7 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeTransformUniform>();
ClassDB::register_class<VisualShaderNodeTextureUniform>();
ClassDB::register_class<VisualShaderNodeTextureUniformTriplanar>();
- ClassDB::register_class<VisualShaderNodeCubeMapUniform>();
+ ClassDB::register_class<VisualShaderNodeCubemapUniform>();
ClassDB::register_class<VisualShaderNodeIf>();
ClassDB::register_class<VisualShaderNodeSwitch>();
ClassDB::register_class<VisualShaderNodeScalarSwitch>();
@@ -616,9 +621,11 @@ void register_scene_types() {
ClassDB::register_class<SphereMesh>();
ClassDB::register_class<PointMesh>();
ClassDB::register_virtual_class<Material>();
- ClassDB::register_class<SpatialMaterial>();
- SceneTree::add_idle_callback(SpatialMaterial::flush_changes);
- SpatialMaterial::init_shaders();
+ ClassDB::register_virtual_class<BaseMaterial3D>();
+ ClassDB::register_class<StandardMaterial3D>();
+ ClassDB::register_class<ORMMaterial3D>();
+ SceneTree::add_idle_callback(BaseMaterial3D::flush_changes);
+ BaseMaterial3D::init_shaders();
ClassDB::register_class<MeshLibrary>();
@@ -643,8 +650,10 @@ void register_scene_types() {
ClassDB::register_class<PhysicsMaterial>();
ClassDB::register_class<World>();
ClassDB::register_class<Environment>();
+ ClassDB::register_class<CameraEffects>();
ClassDB::register_class<World2D>();
ClassDB::register_virtual_class<Texture>();
+ ClassDB::register_virtual_class<Texture2D>();
ClassDB::register_virtual_class<Sky>();
ClassDB::register_class<PanoramaSky>();
ClassDB::register_class<ProceduralSky>();
@@ -658,10 +667,10 @@ void register_scene_types() {
ClassDB::register_class<ProxyTexture>();
ClassDB::register_class<AnimatedTexture>();
ClassDB::register_class<CameraTexture>();
- ClassDB::register_class<CubeMap>();
ClassDB::register_virtual_class<TextureLayered>();
- ClassDB::register_class<Texture3D>();
- ClassDB::register_class<TextureArray>();
+ ClassDB::register_class<Cubemap>();
+ ClassDB::register_class<CubemapArray>();
+ ClassDB::register_class<Texture2DArray>();
ClassDB::register_class<Animation>();
ClassDB::register_virtual_class<Font>();
ClassDB::register_class<BitmapFont>();
@@ -713,6 +722,8 @@ void register_scene_types() {
ClassDB::register_class<Navigation2D>();
ClassDB::register_class<NavigationPolygon>();
ClassDB::register_class<NavigationPolygonInstance>();
+ ClassDB::register_class<NavigationAgent2D>();
+ ClassDB::register_class<NavigationObstacle2D>();
OS::get_singleton()->yield(); //may take time to init
@@ -723,10 +734,9 @@ void register_scene_types() {
ClassDB::register_virtual_class<SceneTreeTimer>(); //sorry, you can't create it
#ifndef DISABLE_DEPRECATED
- ClassDB::add_compatibility_class("ImageSkyBox", "PanoramaSky");
- ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial");
+ ClassDB::add_compatibility_class("SpatialMaterial", "StandardMaterial3D");
ClassDB::add_compatibility_class("Mesh", "ArrayMesh");
-
+ ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree");
#endif
OS::get_singleton()->yield(); //may take time to init
@@ -749,7 +759,7 @@ void register_scene_types() {
if (font_path != String()) {
font = ResourceLoader::load(font_path);
if (!font.is_valid()) {
- ERR_PRINTS("Error loading custom font '" + font_path + "'");
+ ERR_PRINT("Error loading custom font '" + font_path + "'");
}
}
@@ -764,7 +774,7 @@ void register_scene_types() {
Theme::set_default_font(font);
}
} else {
- ERR_PRINTS("Error loading custom theme '" + theme_path + "'");
+ ERR_PRINT("Error loading custom theme '" + theme_path + "'");
}
}
}
@@ -799,9 +809,9 @@ void unregister_scene_types() {
ResourceLoader::remove_resource_format_loader(resource_loader_bmfont);
resource_loader_bmfont.unref();
- //SpatialMaterial is not initialised when 3D is disabled, so it shouldn't be cleaned up either
+ //StandardMaterial3D is not initialised when 3D is disabled, so it shouldn't be cleaned up either
#ifndef _3D_DISABLED
- SpatialMaterial::finish_shaders();
+ BaseMaterial3D::finish_shaders();
#endif // _3D_DISABLED
ParticlesMaterial::finish_shaders();
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index e8cb40154e..a412d8a5e2 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -519,7 +519,7 @@ PoolVector<uint8_t> AudioStreamSample::get_data() const {
Error AudioStreamSample::save_to_wav(const String &p_path) {
if (format == AudioStreamSample::FORMAT_IMA_ADPCM) {
- WARN_PRINTS("Saving IMA_ADPC samples are not supported yet");
+ WARN_PRINT("Saving IMA_ADPC samples are not supported yet");
return ERR_UNAVAILABLE;
}
diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp
index dee3943b8e..e1f485bae6 100644
--- a/scene/resources/box_shape.cpp
+++ b/scene/resources/box_shape.cpp
@@ -48,6 +48,10 @@ Vector<Vector3> BoxShape::get_debug_mesh_lines() {
return lines;
}
+real_t BoxShape::get_enclosing_radius() const {
+ return extents.length();
+}
+
void BoxShape::_update_shape() {
PhysicsServer::get_singleton()->shape_set_data(get_shape(), extents);
diff --git a/scene/resources/box_shape.h b/scene/resources/box_shape.h
index b577a70e1e..fb164cc300 100644
--- a/scene/resources/box_shape.h
+++ b/scene/resources/box_shape.h
@@ -48,6 +48,7 @@ public:
Vector3 get_extents() const;
virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const;
BoxShape();
};
diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp
index 61331a336d..933129936a 100644
--- a/scene/resources/capsule_shape.cpp
+++ b/scene/resources/capsule_shape.cpp
@@ -69,6 +69,10 @@ Vector<Vector3> CapsuleShape::get_debug_mesh_lines() {
return points;
}
+real_t CapsuleShape::get_enclosing_radius() const {
+ return radius + height * 0.5;
+}
+
void CapsuleShape::_update_shape() {
Dictionary d;
diff --git a/scene/resources/capsule_shape.h b/scene/resources/capsule_shape.h
index 8e7d7bcb94..f097e51175 100644
--- a/scene/resources/capsule_shape.h
+++ b/scene/resources/capsule_shape.h
@@ -51,6 +51,7 @@ public:
float get_height() const;
virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const;
CapsuleShape();
};
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index 008e8bb13d..5658395cee 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -97,6 +97,10 @@ Rect2 CapsuleShape2D::get_rect() const {
return rect;
}
+real_t CapsuleShape2D::get_enclosing_radius() const {
+ return radius + height * 0.5;
+}
+
void CapsuleShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape2D::set_radius);
diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h
index 8398fab839..fe401a610c 100644
--- a/scene/resources/capsule_shape_2d.h
+++ b/scene/resources/capsule_shape_2d.h
@@ -56,6 +56,7 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
CapsuleShape2D();
};
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index 7142309e28..10f8ab8a8a 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -70,6 +70,10 @@ Rect2 CircleShape2D::get_rect() const {
return rect;
}
+real_t CircleShape2D::get_enclosing_radius() const {
+ return radius;
+}
+
void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Vector<Vector2> points;
diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h
index cafd291f13..8b064f4d9f 100644
--- a/scene/resources/circle_shape_2d.h
+++ b/scene/resources/circle_shape_2d.h
@@ -50,6 +50,7 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
CircleShape2D();
};
diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp
index 48cc08eae4..0a93f99ea3 100644
--- a/scene/resources/concave_polygon_shape.cpp
+++ b/scene/resources/concave_polygon_shape.cpp
@@ -64,6 +64,16 @@ Vector<Vector3> ConcavePolygonShape::get_debug_mesh_lines() {
return points;
}
+real_t ConcavePolygonShape::get_enclosing_radius() const {
+ PoolVector<Vector3> data = get_faces();
+ PoolVector<Vector3>::Read read = data.read();
+ real_t r = 0;
+ for (int i(0); i < data.size(); i++) {
+ r = MAX(read[i].length_squared(), r);
+ }
+ return Math::sqrt(r);
+}
+
void ConcavePolygonShape::_update_shape() {
Shape::_update_shape();
}
diff --git a/scene/resources/concave_polygon_shape.h b/scene/resources/concave_polygon_shape.h
index 5e371954d4..b4bebbd7b4 100644
--- a/scene/resources/concave_polygon_shape.h
+++ b/scene/resources/concave_polygon_shape.h
@@ -66,7 +66,8 @@ public:
void set_faces(const PoolVector<Vector3> &p_faces);
PoolVector<Vector3> get_faces() const;
- Vector<Vector3> get_debug_mesh_lines();
+ virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const;
ConcavePolygonShape();
};
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index 640f395158..840733add3 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -94,6 +94,16 @@ Rect2 ConcavePolygonShape2D::get_rect() const {
return rect;
}
+real_t ConcavePolygonShape2D::get_enclosing_radius() const {
+ PoolVector<Vector2> data = get_segments();
+ PoolVector<Vector2>::Read read = data.read();
+ real_t r = 0;
+ for (int i(0); i < data.size(); i++) {
+ r = MAX(read[i].length_squared(), r);
+ }
+ return Math::sqrt(r);
+}
+
void ConcavePolygonShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_segments", "segments"), &ConcavePolygonShape2D::set_segments);
diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h
index b95ed100e7..4e47ad34b8 100644
--- a/scene/resources/concave_polygon_shape_2d.h
+++ b/scene/resources/concave_polygon_shape_2d.h
@@ -47,6 +47,7 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
ConcavePolygonShape2D();
};
diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp
index 1498eb4af9..21fdcc1f06 100644
--- a/scene/resources/convex_polygon_shape.cpp
+++ b/scene/resources/convex_polygon_shape.cpp
@@ -55,6 +55,16 @@ Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() {
return Vector<Vector3>();
}
+real_t ConvexPolygonShape::get_enclosing_radius() const {
+ PoolVector<Vector3> data = get_points();
+ PoolVector<Vector3>::Read read = data.read();
+ real_t r = 0;
+ for (int i(0); i < data.size(); i++) {
+ r = MAX(read[i].length_squared(), r);
+ }
+ return Math::sqrt(r);
+}
+
void ConvexPolygonShape::_update_shape() {
PhysicsServer::get_singleton()->shape_set_data(get_shape(), points);
diff --git a/scene/resources/convex_polygon_shape.h b/scene/resources/convex_polygon_shape.h
index 4725d09b26..e3bf02399a 100644
--- a/scene/resources/convex_polygon_shape.h
+++ b/scene/resources/convex_polygon_shape.h
@@ -48,6 +48,7 @@ public:
PoolVector<Vector3> get_points() const;
virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const;
ConvexPolygonShape();
};
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index c404190398..296d014cc7 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -97,6 +97,14 @@ Rect2 ConvexPolygonShape2D::get_rect() const {
return rect;
}
+real_t ConvexPolygonShape2D::get_enclosing_radius() const {
+ real_t r = 0;
+ for (int i(0); i < get_points().size(); i++) {
+ r = MAX(get_points()[i].length_squared(), r);
+ }
+ return Math::sqrt(r);
+}
+
ConvexPolygonShape2D::ConvexPolygonShape2D() :
Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) {
}
diff --git a/scene/resources/convex_polygon_shape_2d.h b/scene/resources/convex_polygon_shape_2d.h
index ed6be738ab..83c250c0ce 100644
--- a/scene/resources/convex_polygon_shape_2d.h
+++ b/scene/resources/convex_polygon_shape_2d.h
@@ -51,6 +51,7 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
ConvexPolygonShape2D();
};
diff --git a/scene/resources/cylinder_shape.cpp b/scene/resources/cylinder_shape.cpp
index d9f6e4f054..b9b0d77a1b 100644
--- a/scene/resources/cylinder_shape.cpp
+++ b/scene/resources/cylinder_shape.cpp
@@ -62,6 +62,10 @@ Vector<Vector3> CylinderShape::get_debug_mesh_lines() {
return points;
}
+real_t CylinderShape::get_enclosing_radius() const {
+ return Vector2(radius, height * 0.5).length();
+}
+
void CylinderShape::_update_shape() {
Dictionary d;
diff --git a/scene/resources/cylinder_shape.h b/scene/resources/cylinder_shape.h
index ebddd4d92f..a26fda10cd 100644
--- a/scene/resources/cylinder_shape.h
+++ b/scene/resources/cylinder_shape.h
@@ -50,6 +50,7 @@ public:
float get_height() const;
virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const;
CylinderShape();
};
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index cc76df62e5..5a6a8dc286 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -69,7 +69,7 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, fl
img->resize(orig_size.x * scale, orig_size.y * scale);
}
- texture->create_from_image(img, ImageTexture::FLAG_FILTER);
+ texture->create_from_image(img);
(*tex_cache)[p_src] = texture;
}
@@ -98,7 +98,7 @@ static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left,
}
template <class T>
-static Ref<Texture> make_icon(T p_src) {
+static Ref<Texture2D> make_icon(T p_src) {
Ref<ImageTexture> texture(memnew(ImageTexture));
Ref<Image> img = memnew(Image(p_src));
@@ -115,7 +115,7 @@ static Ref<Texture> make_icon(T p_src) {
img->convert(Image::FORMAT_RGBA8);
img->resize(orig_size.x * scale, orig_size.y * scale);
}
- texture->create_from_image(img, ImageTexture::FLAG_FILTER);
+ texture->create_from_image(img);
return texture;
}
@@ -169,7 +169,7 @@ static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margi
return style;
}
-void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale) {
+void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale) {
scale = p_scale;
@@ -464,7 +464,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("completion_scroll_width", "TextEdit", 3);
theme->set_constant("line_spacing", "TextEdit", 4 * scale);
- Ref<Texture> empty_icon = memnew(ImageTexture);
+ Ref<Texture2D> empty_icon = memnew(ImageTexture);
// HScrollBar
@@ -647,8 +647,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("title_button_color", "Tree", control_font_color);
theme->set_color("font_color", "Tree", control_font_color_low);
theme->set_color("font_color_selected", "Tree", control_font_color_pressed);
- theme->set_color("selection_color", "Tree", Color(0.1, 0.1, 1, 0.8));
- theme->set_color("cursor_color", "Tree", Color(0, 0, 0));
theme->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1));
theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2));
theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27));
@@ -875,7 +873,7 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
t.instance();
Ref<StyleBox> default_style;
- Ref<Texture> default_icon;
+ Ref<Texture2D> default_icon;
Ref<Font> default_font;
if (p_font.is_valid()) {
default_font = p_font;
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index 1807770ff4..46f89a9b50 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -33,7 +33,7 @@
#include "scene/resources/theme.h"
-void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale);
+void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(bool p_hidpi, Ref<Font> p_font);
void clear_default_theme();
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index d19d82d252..d2a90f388e 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -28,8 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef FREETYPE_ENABLED
+#include "modules/modules_enabled.gen.h"
+#ifdef MODULE_FREETYPE_ENABLED
+
#include "dynamic_font.h"
+
#include "core/os/file_access.h"
#include "core/os/os.h"
@@ -219,11 +222,6 @@ Error DynamicFontAtSize::_load() {
ascent = (face->size->metrics.ascender / 64.0) / oversampling * scale_color_font;
descent = (-face->size->metrics.descender / 64.0) / oversampling * scale_color_font;
linegap = 0;
- texture_flags = 0;
- if (id.mipmaps)
- texture_flags |= Texture::FLAG_MIPMAPS;
- if (id.filter)
- texture_flags |= Texture::FLAG_FILTER;
valid = true;
return OK;
@@ -296,16 +294,6 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V
return ret;
}
-void DynamicFontAtSize::set_texture_flags(uint32_t p_flags) {
-
- texture_flags = p_flags;
- for (int i = 0; i < textures.size(); i++) {
- Ref<ImageTexture> &tex = textures.write[i].texture;
- if (!tex.is_null())
- tex->set_flags(p_flags);
- }
-}
-
float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only, bool p_outline) const {
if (!valid)
@@ -348,7 +336,7 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT
modulate.r = modulate.g = modulate.b = 1.0;
}
RID texture = font->textures[ch->texture_idx].texture->get_rid();
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, RID(), false);
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, RID(), RID(), Color(1, 1, 1, 1), false);
}
advance = ch->advance;
@@ -533,9 +521,9 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
if (tex.texture.is_null()) {
tex.texture.instance();
- tex.texture->create_from_image(img, Texture::FLAG_VIDEO_SURFACE | texture_flags);
+ tex.texture->create_from_image(img);
} else {
- tex.texture->set_data(img); //update
+ tex.texture->update(img); //update
}
}
@@ -656,7 +644,6 @@ DynamicFontAtSize::DynamicFontAtSize() {
ascent = 1;
descent = 1;
linegap = 1;
- texture_flags = 0;
oversampling = font_oversampling;
scale_color_font = 1;
}
@@ -755,34 +742,6 @@ Color DynamicFont::get_outline_color() const {
return outline_color;
}
-bool DynamicFont::get_use_mipmaps() const {
-
- return cache_id.mipmaps;
-}
-
-void DynamicFont::set_use_mipmaps(bool p_enable) {
-
- if (cache_id.mipmaps == p_enable)
- return;
- cache_id.mipmaps = p_enable;
- outline_cache_id.mipmaps = p_enable;
- _reload_cache();
-}
-
-bool DynamicFont::get_use_filter() const {
-
- return cache_id.filter;
-}
-
-void DynamicFont::set_use_filter(bool p_enable) {
-
- if (cache_id.filter == p_enable)
- return;
- cache_id.filter = p_enable;
- outline_cache_id.filter = p_enable;
- _reload_cache();
-}
-
bool DynamicFontData::is_antialiased() const {
return antialiased;
@@ -1004,10 +963,6 @@ void DynamicFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_outline_color", "color"), &DynamicFont::set_outline_color);
ClassDB::bind_method(D_METHOD("get_outline_color"), &DynamicFont::get_outline_color);
- ClassDB::bind_method(D_METHOD("set_use_mipmaps", "enable"), &DynamicFont::set_use_mipmaps);
- ClassDB::bind_method(D_METHOD("get_use_mipmaps"), &DynamicFont::get_use_mipmaps);
- ClassDB::bind_method(D_METHOD("set_use_filter", "enable"), &DynamicFont::set_use_filter);
- ClassDB::bind_method(D_METHOD("get_use_filter"), &DynamicFont::get_use_filter);
ClassDB::bind_method(D_METHOD("set_spacing", "type", "value"), &DynamicFont::set_spacing);
ClassDB::bind_method(D_METHOD("get_spacing", "type"), &DynamicFont::get_spacing);
@@ -1021,8 +976,6 @@ void DynamicFont::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "1,1024,1"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,1024,1"), "set_outline_size", "get_outline_size");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "get_use_mipmaps");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_filter"), "set_use_filter", "get_use_filter");
ADD_GROUP("Extra Spacing", "extra_spacing");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_top"), "set_spacing", "get_spacing", SPACING_TOP);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_bottom"), "set_spacing", "get_spacing", SPACING_BOTTOM);
diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h
index 2dafd3ce4f..94f03665d3 100644
--- a/scene/resources/dynamic_font.h
+++ b/scene/resources/dynamic_font.h
@@ -31,7 +31,9 @@
#ifndef DYNAMIC_FONT_H
#define DYNAMIC_FONT_H
-#ifdef FREETYPE_ENABLED
+#include "modules/modules_enabled.gen.h"
+#ifdef MODULE_FREETYPE_ENABLED
+
#include "core/io/resource_loader.h"
#include "core/os/mutex.h"
#include "core/os/thread_safe.h"
@@ -54,9 +56,7 @@ public:
struct {
uint32_t size : 16;
uint32_t outline_size : 8;
- uint32_t mipmaps : 1;
- uint32_t filter : 1;
- uint32_t unused : 6;
+ uint32_t unused : 8;
};
uint32_t key;
};
@@ -125,8 +125,6 @@ class DynamicFontAtSize : public Reference {
float oversampling;
float scale_color_font;
- uint32_t texture_flags;
-
bool valid;
struct CharTexture {
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 7597cd636e..12b2bf4bc9 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -61,25 +61,6 @@ void Environment::set_sky_custom_fov(float p_scale) {
bg_sky_custom_fov = p_scale;
VS::get_singleton()->environment_set_sky_custom_fov(environment, p_scale);
}
-void Environment::set_sky_orientation(const Basis &p_orientation) {
-
- bg_sky_orientation = p_orientation;
- _change_notify("background_sky_rotation");
- _change_notify("background_sky_rotation_degrees");
- VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation);
-}
-void Environment::set_sky_rotation(const Vector3 &p_euler_rad) {
-
- bg_sky_orientation.set_euler(p_euler_rad);
- _change_notify("background_sky_orientation");
- _change_notify("background_sky_rotation_degrees");
- VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation);
-}
-void Environment::set_sky_rotation_degrees(const Vector3 &p_euler_deg) {
-
- set_sky_rotation(p_euler_deg * Math_PI / 180.0);
- _change_notify("background_sky_rotation");
-}
void Environment::set_bg_color(const Color &p_color) {
bg_color = p_color;
@@ -98,24 +79,43 @@ void Environment::set_canvas_max_layer(int p_max_layer) {
void Environment::set_ambient_light_color(const Color &p_color) {
ambient_color = p_color;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color);
}
void Environment::set_ambient_light_energy(float p_energy) {
ambient_energy = p_energy;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color);
}
void Environment::set_ambient_light_sky_contribution(float p_energy) {
ambient_sky_contribution = p_energy;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color);
}
void Environment::set_camera_feed_id(int p_camera_feed_id) {
camera_feed_id = p_camera_feed_id;
+// FIXME: Disabled during Vulkan refactoring, should be ported.
+#if 0
VS::get_singleton()->environment_set_camera_feed_id(environment, camera_feed_id);
+#endif
};
+void Environment::set_ambient_source(AmbientSource p_source) {
+ ambient_source = p_source;
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color);
+}
+
+Environment::AmbientSource Environment::get_ambient_source() const {
+ return ambient_source;
+}
+void Environment::set_reflection_source(ReflectionSource p_source) {
+ reflection_source = p_source;
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color);
+}
+Environment::ReflectionSource Environment::get_reflection_source() const {
+ return reflection_source;
+}
+
Environment::BGMode Environment::get_background() const {
return bg_mode;
@@ -130,20 +130,14 @@ float Environment::get_sky_custom_fov() const {
return bg_sky_custom_fov;
}
-Basis Environment::get_sky_orientation() const {
-
- return bg_sky_orientation;
+void Environment::set_sky_rotation(const Vector3 &p_rotation) {
+ sky_rotation = p_rotation;
+ VS::get_singleton()->environment_set_sky_orientation(environment, Basis(p_rotation));
}
Vector3 Environment::get_sky_rotation() const {
- // should we cache this? maybe overkill
- return bg_sky_orientation.get_euler();
-}
-
-Vector3 Environment::get_sky_rotation_degrees() const {
-
- return get_sky_rotation() * 180.0 / Math_PI;
+ return sky_rotation;
}
Color Environment::get_bg_color() const {
@@ -300,26 +294,34 @@ float Environment::get_adjustment_saturation() const {
return adjustment_saturation;
}
-void Environment::set_adjustment_color_correction(const Ref<Texture> &p_ramp) {
+void Environment::set_adjustment_color_correction(const Ref<Texture2D> &p_ramp) {
adjustment_color_correction = p_ramp;
VS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
}
-Ref<Texture> Environment::get_adjustment_color_correction() const {
+Ref<Texture2D> Environment::get_adjustment_color_correction() const {
return adjustment_color_correction;
}
void Environment::_validate_property(PropertyInfo &property) const {
- if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "background_sky_orientation" || property.name == "background_sky_rotation" || property.name == "background_sky_rotation_degrees" || property.name == "ambient_light/sky_contribution") {
- if (bg_mode != BG_SKY && bg_mode != BG_COLOR_SKY) {
+ if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") {
+ if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
+ if (property.name == "glow_intensity" && glow_blend_mode == GLOW_BLEND_MODE_MIX) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ }
+
+ if (property.name == "glow_mix" && glow_blend_mode != GLOW_BLEND_MODE_MIX) {
+ property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ }
+
if (property.name == "background_color") {
- if (bg_mode != BG_COLOR && bg_mode != BG_COLOR_SKY) {
+ if (bg_mode != BG_COLOR && ambient_source != AMBIENT_SOURCE_COLOR) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
@@ -341,8 +343,6 @@ void Environment::_validate_property(PropertyInfo &property) const {
"auto_exposure_",
"ss_reflections_",
"ssao_",
- "dof_blur_far_",
- "dof_blur_near_",
"glow_",
"adjustment_",
NULL
@@ -451,7 +451,7 @@ bool Environment::is_ssr_rough() const {
void Environment::set_ssao_enabled(bool p_enable) {
ssao_enabled = p_enable;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
_change_notify();
}
@@ -463,7 +463,7 @@ bool Environment::is_ssao_enabled() const {
void Environment::set_ssao_radius(float p_radius) {
ssao_radius = p_radius;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
float Environment::get_ssao_radius() const {
@@ -473,7 +473,7 @@ float Environment::get_ssao_radius() const {
void Environment::set_ssao_intensity(float p_intensity) {
ssao_intensity = p_intensity;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
float Environment::get_ssao_intensity() const {
@@ -481,30 +481,10 @@ float Environment::get_ssao_intensity() const {
return ssao_intensity;
}
-void Environment::set_ssao_radius2(float p_radius) {
-
- ssao_radius2 = p_radius;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
-}
-float Environment::get_ssao_radius2() const {
-
- return ssao_radius2;
-}
-
-void Environment::set_ssao_intensity2(float p_intensity) {
-
- ssao_intensity2 = p_intensity;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
-}
-float Environment::get_ssao_intensity2() const {
-
- return ssao_intensity2;
-}
-
void Environment::set_ssao_bias(float p_bias) {
ssao_bias = p_bias;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
float Environment::get_ssao_bias() const {
@@ -514,7 +494,7 @@ float Environment::get_ssao_bias() const {
void Environment::set_ssao_direct_light_affect(float p_direct_light_affect) {
ssao_direct_light_affect = p_direct_light_affect;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
float Environment::get_ssao_direct_light_affect() const {
@@ -524,49 +504,38 @@ float Environment::get_ssao_direct_light_affect() const {
void Environment::set_ssao_ao_channel_affect(float p_ao_channel_affect) {
ssao_ao_channel_affect = p_ao_channel_affect;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
float Environment::get_ssao_ao_channel_affect() const {
return ssao_ao_channel_affect;
}
-void Environment::set_ssao_color(const Color &p_color) {
+void Environment::set_ao_color(const Color &p_color) {
- ssao_color = p_color;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ ao_color = p_color;
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color);
}
-Color Environment::get_ssao_color() const {
+Color Environment::get_ao_color() const {
- return ssao_color;
+ return ao_color;
}
void Environment::set_ssao_blur(SSAOBlur p_blur) {
ssao_blur = p_blur;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
Environment::SSAOBlur Environment::get_ssao_blur() const {
return ssao_blur;
}
-void Environment::set_ssao_quality(SSAOQuality p_quality) {
-
- ssao_quality = p_quality;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
-}
-
-Environment::SSAOQuality Environment::get_ssao_quality() const {
-
- return ssao_quality;
-}
-
void Environment::set_ssao_edge_sharpness(float p_edge_sharpness) {
ssao_edge_sharpness = p_edge_sharpness;
- VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
+ VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
float Environment::get_ssao_edge_sharpness() const {
@@ -577,7 +546,7 @@ float Environment::get_ssao_edge_sharpness() const {
void Environment::set_glow_enabled(bool p_enabled) {
glow_enabled = p_enabled;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
_change_notify();
}
@@ -595,7 +564,7 @@ void Environment::set_glow_level(int p_level, bool p_enabled) {
else
glow_levels &= ~(1 << p_level);
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
}
bool Environment::is_glow_level_enabled(int p_level) const {
@@ -608,7 +577,7 @@ void Environment::set_glow_intensity(float p_intensity) {
glow_intensity = p_intensity;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
}
float Environment::get_glow_intensity() const {
@@ -618,18 +587,28 @@ float Environment::get_glow_intensity() const {
void Environment::set_glow_strength(float p_strength) {
glow_strength = p_strength;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
}
float Environment::get_glow_strength() const {
return glow_strength;
}
+void Environment::set_glow_mix(float p_mix) {
+
+ glow_mix = p_mix;
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+}
+float Environment::get_glow_mix() const {
+
+ return glow_mix;
+}
+
void Environment::set_glow_bloom(float p_threshold) {
glow_bloom = p_threshold;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
}
float Environment::get_glow_bloom() const {
@@ -640,7 +619,8 @@ void Environment::set_glow_blend_mode(GlowBlendMode p_mode) {
glow_blend_mode = p_mode;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ _change_notify();
}
Environment::GlowBlendMode Environment::get_glow_blend_mode() const {
@@ -651,7 +631,7 @@ void Environment::set_glow_hdr_bleed_threshold(float p_threshold) {
glow_hdr_bleed_threshold = p_threshold;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
}
float Environment::get_glow_hdr_bleed_threshold() const {
@@ -662,7 +642,7 @@ void Environment::set_glow_hdr_luminance_cap(float p_amount) {
glow_hdr_luminance_cap = p_amount;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
}
float Environment::get_glow_hdr_luminance_cap() const {
@@ -673,7 +653,7 @@ void Environment::set_glow_hdr_bleed_scale(float p_scale) {
glow_hdr_bleed_scale = p_scale;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
}
float Environment::get_glow_hdr_bleed_scale() const {
@@ -683,7 +663,7 @@ float Environment::get_glow_hdr_bleed_scale() const {
void Environment::set_glow_bicubic_upscale(bool p_enable) {
glow_bicubic_upscale = p_enable;
- VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
+ VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale);
}
bool Environment::is_glow_bicubic_upscale_enabled() const {
@@ -691,115 +671,6 @@ bool Environment::is_glow_bicubic_upscale_enabled() const {
return glow_bicubic_upscale;
}
-void Environment::set_dof_blur_far_enabled(bool p_enable) {
-
- dof_blur_far_enabled = p_enable;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
- _change_notify();
-}
-
-bool Environment::is_dof_blur_far_enabled() const {
-
- return dof_blur_far_enabled;
-}
-
-void Environment::set_dof_blur_far_distance(float p_distance) {
-
- dof_blur_far_distance = p_distance;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
-}
-float Environment::get_dof_blur_far_distance() const {
-
- return dof_blur_far_distance;
-}
-
-void Environment::set_dof_blur_far_transition(float p_distance) {
-
- dof_blur_far_transition = p_distance;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
-}
-float Environment::get_dof_blur_far_transition() const {
-
- return dof_blur_far_transition;
-}
-
-void Environment::set_dof_blur_far_amount(float p_amount) {
-
- dof_blur_far_amount = p_amount;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
-}
-float Environment::get_dof_blur_far_amount() const {
-
- return dof_blur_far_amount;
-}
-
-void Environment::set_dof_blur_far_quality(DOFBlurQuality p_quality) {
-
- dof_blur_far_quality = p_quality;
- VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
-}
-
-Environment::DOFBlurQuality Environment::get_dof_blur_far_quality() const {
-
- return dof_blur_far_quality;
-}
-
-void Environment::set_dof_blur_near_enabled(bool p_enable) {
-
- dof_blur_near_enabled = p_enable;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
- _change_notify();
-}
-
-bool Environment::is_dof_blur_near_enabled() const {
-
- return dof_blur_near_enabled;
-}
-
-void Environment::set_dof_blur_near_distance(float p_distance) {
-
- dof_blur_near_distance = p_distance;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
-}
-
-float Environment::get_dof_blur_near_distance() const {
-
- return dof_blur_near_distance;
-}
-
-void Environment::set_dof_blur_near_transition(float p_distance) {
-
- dof_blur_near_transition = p_distance;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
-}
-
-float Environment::get_dof_blur_near_transition() const {
-
- return dof_blur_near_transition;
-}
-
-void Environment::set_dof_blur_near_amount(float p_amount) {
-
- dof_blur_near_amount = p_amount;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
-}
-
-float Environment::get_dof_blur_near_amount() const {
-
- return dof_blur_near_amount;
-}
-
-void Environment::set_dof_blur_near_quality(DOFBlurQuality p_quality) {
-
- dof_blur_near_quality = p_quality;
- VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
-}
-
-Environment::DOFBlurQuality Environment::get_dof_blur_near_quality() const {
-
- return dof_blur_near_quality;
-}
-
void Environment::set_fog_enabled(bool p_enabled) {
fog_enabled = p_enabled;
@@ -943,14 +814,31 @@ float Environment::get_fog_height_curve() const {
return fog_height_curve;
}
+#ifndef DISABLE_DEPRECATED
+// Kept for compatibility from 3.x to 4.0.
+bool Environment::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "background_sky") {
+ set_sky(p_value);
+ return true;
+ } else if (p_name == "background_sky_custom_fov") {
+ set_sky_custom_fov(p_value);
+ return true;
+ } else if (p_name == "background_sky_orientation") {
+ Vector3 euler = p_value.operator Basis().get_euler();
+ set_sky_rotation(euler);
+ return true;
+ } else {
+ return false;
+ }
+}
+#endif
+
void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background);
ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky);
ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov);
- ClassDB::bind_method(D_METHOD("set_sky_orientation", "orientation"), &Environment::set_sky_orientation);
ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation);
- ClassDB::bind_method(D_METHOD("set_sky_rotation_degrees", "euler_degrees"), &Environment::set_sky_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color);
ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy);
ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer);
@@ -958,13 +846,13 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ambient_light_energy", "energy"), &Environment::set_ambient_light_energy);
ClassDB::bind_method(D_METHOD("set_ambient_light_sky_contribution", "energy"), &Environment::set_ambient_light_sky_contribution);
ClassDB::bind_method(D_METHOD("set_camera_feed_id", "camera_feed_id"), &Environment::set_camera_feed_id);
+ ClassDB::bind_method(D_METHOD("set_ambient_source", "source"), &Environment::set_ambient_source);
+ ClassDB::bind_method(D_METHOD("set_reflection_source", "source"), &Environment::set_reflection_source);
ClassDB::bind_method(D_METHOD("get_background"), &Environment::get_background);
ClassDB::bind_method(D_METHOD("get_sky"), &Environment::get_sky);
ClassDB::bind_method(D_METHOD("get_sky_custom_fov"), &Environment::get_sky_custom_fov);
- ClassDB::bind_method(D_METHOD("get_sky_orientation"), &Environment::get_sky_orientation);
ClassDB::bind_method(D_METHOD("get_sky_rotation"), &Environment::get_sky_rotation);
- ClassDB::bind_method(D_METHOD("get_sky_rotation_degrees"), &Environment::get_sky_rotation_degrees);
ClassDB::bind_method(D_METHOD("get_bg_color"), &Environment::get_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_energy"), &Environment::get_bg_energy);
ClassDB::bind_method(D_METHOD("get_canvas_max_layer"), &Environment::get_canvas_max_layer);
@@ -972,24 +860,29 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_ambient_light_energy"), &Environment::get_ambient_light_energy);
ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution);
ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &Environment::get_camera_feed_id);
+ ClassDB::bind_method(D_METHOD("get_ambient_source"), &Environment::get_ambient_source);
+ ClassDB::bind_method(D_METHOD("get_reflection_source"), &Environment::get_reflection_source);
+ ClassDB::bind_method(D_METHOD("set_ao_color", "color"), &Environment::set_ao_color);
+ ClassDB::bind_method(D_METHOD("get_ao_color"), &Environment::get_ao_color);
ADD_GROUP("Background", "background_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Color+Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov");
- ADD_PROPERTY(PropertyInfo(Variant::BASIS, "background_sky_orientation"), "set_sky_orientation", "get_sky_orientation");
- // Only display rotation in degrees in the inspector (like in Spatial).
- // This avoids displaying the same information twice.
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation", PROPERTY_HINT_NONE, "", 0), "set_sky_rotation", "get_sky_rotation");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_sky_rotation_degrees", "get_sky_rotation_degrees");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_canvas_max_layer", PROPERTY_HINT_RANGE, "-1000,1000,1"), "set_canvas_max_layer", "get_canvas_max_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_camera_feed_id", PROPERTY_HINT_RANGE, "1,10,1"), "set_camera_feed_id", "get_camera_feed_id");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy");
+ ADD_GROUP("Sky", "sky_");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation"), "set_sky_rotation", "get_sky_rotation");
ADD_GROUP("Ambient Light", "ambient_light_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Color,Sky"), "set_ambient_source", "get_ambient_source");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_color"), "set_ambient_light_color", "get_ambient_light_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_occlusion_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ao_color", "get_ao_color");
+ ADD_GROUP("Reflected Light", "reflected_light_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "reflected_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Sky"), "set_reflection_source", "get_reflection_source");
ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled);
ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled);
@@ -1119,12 +1012,6 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ssao_intensity", "intensity"), &Environment::set_ssao_intensity);
ClassDB::bind_method(D_METHOD("get_ssao_intensity"), &Environment::get_ssao_intensity);
- ClassDB::bind_method(D_METHOD("set_ssao_radius2", "radius"), &Environment::set_ssao_radius2);
- ClassDB::bind_method(D_METHOD("get_ssao_radius2"), &Environment::get_ssao_radius2);
-
- ClassDB::bind_method(D_METHOD("set_ssao_intensity2", "intensity"), &Environment::set_ssao_intensity2);
- ClassDB::bind_method(D_METHOD("get_ssao_intensity2"), &Environment::get_ssao_intensity2);
-
ClassDB::bind_method(D_METHOD("set_ssao_bias", "bias"), &Environment::set_ssao_bias);
ClassDB::bind_method(D_METHOD("get_ssao_bias"), &Environment::get_ssao_bias);
@@ -1134,15 +1021,9 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ssao_ao_channel_affect", "amount"), &Environment::set_ssao_ao_channel_affect);
ClassDB::bind_method(D_METHOD("get_ssao_ao_channel_affect"), &Environment::get_ssao_ao_channel_affect);
- ClassDB::bind_method(D_METHOD("set_ssao_color", "color"), &Environment::set_ssao_color);
- ClassDB::bind_method(D_METHOD("get_ssao_color"), &Environment::get_ssao_color);
-
ClassDB::bind_method(D_METHOD("set_ssao_blur", "mode"), &Environment::set_ssao_blur);
ClassDB::bind_method(D_METHOD("get_ssao_blur"), &Environment::get_ssao_blur);
- ClassDB::bind_method(D_METHOD("set_ssao_quality", "quality"), &Environment::set_ssao_quality);
- ClassDB::bind_method(D_METHOD("get_ssao_quality"), &Environment::get_ssao_quality);
-
ClassDB::bind_method(D_METHOD("set_ssao_edge_sharpness", "edge_sharpness"), &Environment::set_ssao_edge_sharpness);
ClassDB::bind_method(D_METHOD("get_ssao_edge_sharpness"), &Environment::get_ssao_edge_sharpness);
@@ -1150,60 +1031,12 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssao_radius", "get_ssao_radius");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity", "get_ssao_intensity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius2", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_radius2", "get_ssao_radius2");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity2", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity2", "get_ssao_intensity2");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ssao_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ssao_color", "get_ssao_color");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_ssao_quality", "get_ssao_quality");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_blur", PROPERTY_HINT_ENUM, "Disabled,1x1,2x2,3x3"), "set_ssao_blur", "get_ssao_blur");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_edge_sharpness", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_ssao_edge_sharpness", "get_ssao_edge_sharpness");
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &Environment::set_dof_blur_far_enabled);
- ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &Environment::is_dof_blur_far_enabled);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "intensity"), &Environment::set_dof_blur_far_distance);
- ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &Environment::get_dof_blur_far_distance);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "intensity"), &Environment::set_dof_blur_far_transition);
- ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &Environment::get_dof_blur_far_transition);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_amount", "intensity"), &Environment::set_dof_blur_far_amount);
- ClassDB::bind_method(D_METHOD("get_dof_blur_far_amount"), &Environment::get_dof_blur_far_amount);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_far_quality", "intensity"), &Environment::set_dof_blur_far_quality);
- ClassDB::bind_method(D_METHOD("get_dof_blur_far_quality"), &Environment::get_dof_blur_far_quality);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &Environment::set_dof_blur_near_enabled);
- ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &Environment::is_dof_blur_near_enabled);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "intensity"), &Environment::set_dof_blur_near_distance);
- ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &Environment::get_dof_blur_near_distance);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "intensity"), &Environment::set_dof_blur_near_transition);
- ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &Environment::get_dof_blur_near_transition);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_amount", "intensity"), &Environment::set_dof_blur_near_amount);
- ClassDB::bind_method(D_METHOD("get_dof_blur_near_amount"), &Environment::get_dof_blur_near_amount);
-
- ClassDB::bind_method(D_METHOD("set_dof_blur_near_quality", "level"), &Environment::set_dof_blur_near_quality);
- ClassDB::bind_method(D_METHOD("get_dof_blur_near_quality"), &Environment::get_dof_blur_near_quality);
-
- ADD_GROUP("DOF Far Blur", "dof_blur_far_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_far_amount", "get_dof_blur_far_amount");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_far_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_far_quality", "get_dof_blur_far_quality");
-
- ADD_GROUP("DOF Near Blur", "dof_blur_near_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_near_amount", "get_dof_blur_near_amount");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_near_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_near_quality", "get_dof_blur_near_quality");
-
ClassDB::bind_method(D_METHOD("set_glow_enabled", "enabled"), &Environment::set_glow_enabled);
ClassDB::bind_method(D_METHOD("is_glow_enabled"), &Environment::is_glow_enabled);
@@ -1216,6 +1049,9 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_glow_strength", "strength"), &Environment::set_glow_strength);
ClassDB::bind_method(D_METHOD("get_glow_strength"), &Environment::get_glow_strength);
+ ClassDB::bind_method(D_METHOD("set_glow_mix", "mix"), &Environment::set_glow_mix);
+ ClassDB::bind_method(D_METHOD("get_glow_mix"), &Environment::get_glow_mix);
+
ClassDB::bind_method(D_METHOD("set_glow_bloom", "amount"), &Environment::set_glow_bloom);
ClassDB::bind_method(D_METHOD("get_glow_bloom"), &Environment::get_glow_bloom);
@@ -1245,9 +1081,10 @@ void Environment::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/7"), "set_glow_level", "is_glow_level_enabled", 6);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_intensity", PROPERTY_HINT_RANGE, "0.0,8.0,0.01"), "set_glow_intensity", "get_glow_intensity");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_mix", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_glow_mix", "get_glow_mix");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_strength", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_glow_strength", "get_glow_strength");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_bloom", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_glow_bloom", "get_glow_bloom");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "glow_blend_mode", PROPERTY_HINT_ENUM, "Additive,Screen,Softlight,Replace"), "set_glow_blend_mode", "get_glow_blend_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "glow_blend_mode", PROPERTY_HINT_ENUM, "Additive,Screen,Softlight,Replace,Mix"), "set_glow_blend_mode", "get_glow_blend_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_threshold", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_threshold", "get_glow_hdr_bleed_threshold");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale");
@@ -1273,59 +1110,58 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_brightness", "get_adjustment_brightness");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_contrast", "get_adjustment_contrast");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_adjustment_color_correction", "get_adjustment_color_correction");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_adjustment_color_correction", "get_adjustment_color_correction");
- BIND_ENUM_CONSTANT(BG_KEEP);
BIND_ENUM_CONSTANT(BG_CLEAR_COLOR);
BIND_ENUM_CONSTANT(BG_COLOR);
BIND_ENUM_CONSTANT(BG_SKY);
- BIND_ENUM_CONSTANT(BG_COLOR_SKY);
BIND_ENUM_CONSTANT(BG_CANVAS);
+ BIND_ENUM_CONSTANT(BG_KEEP);
BIND_ENUM_CONSTANT(BG_CAMERA_FEED);
BIND_ENUM_CONSTANT(BG_MAX);
+ BIND_ENUM_CONSTANT(AMBIENT_SOURCE_BG);
+ BIND_ENUM_CONSTANT(AMBIENT_SOURCE_DISABLED);
+ BIND_ENUM_CONSTANT(AMBIENT_SOURCE_COLOR);
+ BIND_ENUM_CONSTANT(AMBIENT_SOURCE_SKY);
+
+ BIND_ENUM_CONSTANT(REFLECTION_SOURCE_BG);
+ BIND_ENUM_CONSTANT(REFLECTION_SOURCE_DISABLED);
+ BIND_ENUM_CONSTANT(REFLECTION_SOURCE_SKY);
+
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_ADDITIVE);
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SCREEN);
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT);
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE);
+ BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_MIX);
BIND_ENUM_CONSTANT(TONE_MAPPER_LINEAR);
BIND_ENUM_CONSTANT(TONE_MAPPER_REINHARDT);
BIND_ENUM_CONSTANT(TONE_MAPPER_FILMIC);
BIND_ENUM_CONSTANT(TONE_MAPPER_ACES);
- BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW);
- BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM);
- BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_HIGH);
-
BIND_ENUM_CONSTANT(SSAO_BLUR_DISABLED);
BIND_ENUM_CONSTANT(SSAO_BLUR_1x1);
BIND_ENUM_CONSTANT(SSAO_BLUR_2x2);
BIND_ENUM_CONSTANT(SSAO_BLUR_3x3);
-
- BIND_ENUM_CONSTANT(SSAO_QUALITY_LOW);
- BIND_ENUM_CONSTANT(SSAO_QUALITY_MEDIUM);
- BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH);
}
Environment::Environment() :
bg_mode(BG_CLEAR_COLOR),
tone_mapper(TONE_MAPPER_LINEAR),
ssao_blur(SSAO_BLUR_3x3),
- ssao_quality(SSAO_QUALITY_MEDIUM),
- glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE),
- dof_blur_far_quality(DOF_BLUR_QUALITY_LOW),
- dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) {
+ glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE) {
environment = VS::get_singleton()->environment_create();
bg_mode = BG_CLEAR_COLOR;
bg_sky_custom_fov = 0;
- bg_sky_orientation = Basis();
bg_energy = 1.0;
bg_canvas_max_layer = 0;
ambient_energy = 1.0;
//ambient_sky_contribution = 1.0;
+ ambient_source = AMBIENT_SOURCE_BG;
+ reflection_source = REFLECTION_SOURCE_BG;
set_ambient_light_sky_contribution(1.0);
set_camera_feed_id(1);
@@ -1357,19 +1193,17 @@ Environment::Environment() :
ssao_enabled = false;
ssao_radius = 1;
ssao_intensity = 1;
- ssao_radius2 = 0;
- ssao_intensity2 = 1;
ssao_bias = 0.01;
ssao_direct_light_affect = 0.0;
ssao_ao_channel_affect = 0.0;
ssao_blur = SSAO_BLUR_3x3;
set_ssao_edge_sharpness(4);
- set_ssao_quality(SSAO_QUALITY_MEDIUM);
glow_enabled = false;
glow_levels = (1 << 2) | (1 << 4);
glow_intensity = 0.8;
glow_strength = 1.0;
+ glow_mix = 0.05;
glow_bloom = 0.0;
glow_blend_mode = GLOW_BLEND_MODE_SOFTLIGHT;
glow_hdr_bleed_threshold = 1.0;
@@ -1377,18 +1211,6 @@ Environment::Environment() :
glow_hdr_bleed_scale = 2.0;
glow_bicubic_upscale = false;
- dof_blur_far_enabled = false;
- dof_blur_far_distance = 10;
- dof_blur_far_transition = 5;
- dof_blur_far_amount = 0.1;
- dof_blur_far_quality = DOF_BLUR_QUALITY_MEDIUM;
-
- dof_blur_near_enabled = false;
- dof_blur_near_distance = 2;
- dof_blur_near_transition = 1;
- dof_blur_near_amount = 0.1;
- dof_blur_near_quality = DOF_BLUR_QUALITY_MEDIUM;
-
fog_enabled = false;
fog_color = Color(0.5, 0.5, 0.5);
fog_sun_color = Color(0.8, 0.8, 0.0);
@@ -1416,3 +1238,167 @@ Environment::~Environment() {
VS::get_singleton()->free(environment);
}
+
+//////////////////////
+
+void CameraEffects::set_dof_blur_far_enabled(bool p_enable) {
+
+ dof_blur_far_enabled = p_enable;
+ VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
+}
+
+bool CameraEffects::is_dof_blur_far_enabled() const {
+
+ return dof_blur_far_enabled;
+}
+
+void CameraEffects::set_dof_blur_far_distance(float p_distance) {
+
+ dof_blur_far_distance = p_distance;
+ VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
+}
+float CameraEffects::get_dof_blur_far_distance() const {
+
+ return dof_blur_far_distance;
+}
+
+void CameraEffects::set_dof_blur_far_transition(float p_distance) {
+
+ dof_blur_far_transition = p_distance;
+ VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
+}
+float CameraEffects::get_dof_blur_far_transition() const {
+
+ return dof_blur_far_transition;
+}
+
+void CameraEffects::set_dof_blur_near_enabled(bool p_enable) {
+
+ dof_blur_near_enabled = p_enable;
+ VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
+ _change_notify();
+}
+
+bool CameraEffects::is_dof_blur_near_enabled() const {
+
+ return dof_blur_near_enabled;
+}
+
+void CameraEffects::set_dof_blur_near_distance(float p_distance) {
+
+ dof_blur_near_distance = p_distance;
+ VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
+}
+
+float CameraEffects::get_dof_blur_near_distance() const {
+
+ return dof_blur_near_distance;
+}
+
+void CameraEffects::set_dof_blur_near_transition(float p_distance) {
+
+ dof_blur_near_transition = p_distance;
+ VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
+}
+
+float CameraEffects::get_dof_blur_near_transition() const {
+
+ return dof_blur_near_transition;
+}
+
+void CameraEffects::set_dof_blur_amount(float p_amount) {
+
+ dof_blur_amount = p_amount;
+ VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
+}
+float CameraEffects::get_dof_blur_amount() const {
+
+ return dof_blur_amount;
+}
+
+void CameraEffects::set_override_exposure_enabled(bool p_enabled) {
+ override_exposure_enabled = p_enabled;
+ VS::get_singleton()->camera_effects_set_custom_exposure(camera_effects, override_exposure_enabled, override_exposure);
+}
+
+bool CameraEffects::is_override_exposure_enabled() const {
+ return override_exposure_enabled;
+}
+
+void CameraEffects::set_override_exposure(float p_exposure) {
+ override_exposure = p_exposure;
+ VS::get_singleton()->camera_effects_set_custom_exposure(camera_effects, override_exposure_enabled, override_exposure);
+}
+
+float CameraEffects::get_override_exposure() const {
+ return override_exposure;
+}
+
+RID CameraEffects::get_rid() const {
+ return camera_effects;
+}
+
+void CameraEffects::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &CameraEffects::set_dof_blur_far_enabled);
+ ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &CameraEffects::is_dof_blur_far_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "intensity"), &CameraEffects::set_dof_blur_far_distance);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &CameraEffects::get_dof_blur_far_distance);
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "intensity"), &CameraEffects::set_dof_blur_far_transition);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &CameraEffects::get_dof_blur_far_transition);
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &CameraEffects::set_dof_blur_near_enabled);
+ ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &CameraEffects::is_dof_blur_near_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "intensity"), &CameraEffects::set_dof_blur_near_distance);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &CameraEffects::get_dof_blur_near_distance);
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "intensity"), &CameraEffects::set_dof_blur_near_transition);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &CameraEffects::get_dof_blur_near_transition);
+
+ ClassDB::bind_method(D_METHOD("set_dof_blur_amount", "intensity"), &CameraEffects::set_dof_blur_amount);
+ ClassDB::bind_method(D_METHOD("get_dof_blur_amount"), &CameraEffects::get_dof_blur_amount);
+
+ ClassDB::bind_method(D_METHOD("set_override_exposure_enabled", "enable"), &CameraEffects::set_override_exposure_enabled);
+ ClassDB::bind_method(D_METHOD("is_override_exposure_enabled"), &CameraEffects::is_override_exposure_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_override_exposure", "exposure"), &CameraEffects::set_override_exposure);
+ ClassDB::bind_method(D_METHOD("get_override_exposure"), &CameraEffects::get_override_exposure);
+
+ ADD_GROUP("DOF Blur", "dof_blur_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_amount", "get_dof_blur_amount");
+ ADD_GROUP("Override Exposure", "override_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_exposure_enable"), "set_override_exposure_enabled", "is_override_exposure_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "override_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_override_exposure", "get_override_exposure");
+}
+
+CameraEffects::CameraEffects() {
+
+ camera_effects = VS::get_singleton()->camera_effects_create();
+
+ dof_blur_far_enabled = false;
+ dof_blur_far_distance = 10;
+ dof_blur_far_transition = 5;
+
+ dof_blur_near_enabled = false;
+ dof_blur_near_distance = 2;
+ dof_blur_near_transition = 1;
+
+ set_dof_blur_amount(0.1);
+
+ override_exposure_enabled = false;
+ set_override_exposure(1.0);
+}
+
+CameraEffects::~CameraEffects() {
+
+ VS::get_singleton()->free(camera_effects);
+}
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 62c6c5b4cd..f9fe26f792 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -46,13 +46,25 @@ public:
BG_CLEAR_COLOR,
BG_COLOR,
BG_SKY,
- BG_COLOR_SKY,
BG_CANVAS,
BG_KEEP,
BG_CAMERA_FEED,
BG_MAX
};
+ enum AmbientSource {
+ AMBIENT_SOURCE_BG,
+ AMBIENT_SOURCE_DISABLED,
+ AMBIENT_SOURCE_COLOR,
+ AMBIENT_SOURCE_SKY,
+ };
+
+ enum ReflectionSource {
+ REFLECTION_SOURCE_BG,
+ REFLECTION_SOURCE_DISABLED,
+ REFLECTION_SOURCE_SKY,
+ };
+
enum ToneMapper {
TONE_MAPPER_LINEAR,
TONE_MAPPER_REINHARDT,
@@ -65,12 +77,7 @@ public:
GLOW_BLEND_MODE_SCREEN,
GLOW_BLEND_MODE_SOFTLIGHT,
GLOW_BLEND_MODE_REPLACE,
- };
-
- enum DOFBlurQuality {
- DOF_BLUR_QUALITY_LOW,
- DOF_BLUR_QUALITY_MEDIUM,
- DOF_BLUR_QUALITY_HIGH,
+ GLOW_BLEND_MODE_MIX,
};
enum SSAOBlur {
@@ -80,26 +87,23 @@ public:
SSAO_BLUR_3x3
};
- enum SSAOQuality {
- SSAO_QUALITY_LOW,
- SSAO_QUALITY_MEDIUM,
- SSAO_QUALITY_HIGH
- };
-
private:
RID environment;
BGMode bg_mode;
Ref<Sky> bg_sky;
float bg_sky_custom_fov;
- Basis bg_sky_orientation;
+ Vector3 sky_rotation;
Color bg_color;
float bg_energy;
int bg_canvas_max_layer;
Color ambient_color;
float ambient_energy;
+ Color ao_color;
float ambient_sky_contribution;
int camera_feed_id;
+ AmbientSource ambient_source;
+ ReflectionSource reflection_source;
ToneMapper tone_mapper;
float tonemap_exposure;
@@ -114,7 +118,7 @@ private:
float adjustment_contrast;
float adjustment_saturation;
float adjustment_brightness;
- Ref<Texture> adjustment_color_correction;
+ Ref<Texture2D> adjustment_color_correction;
bool ssr_enabled;
int ssr_max_steps;
@@ -126,20 +130,17 @@ private:
bool ssao_enabled;
float ssao_radius;
float ssao_intensity;
- float ssao_radius2;
- float ssao_intensity2;
float ssao_bias;
float ssao_direct_light_affect;
float ssao_ao_channel_affect;
- Color ssao_color;
SSAOBlur ssao_blur;
float ssao_edge_sharpness;
- SSAOQuality ssao_quality;
bool glow_enabled;
int glow_levels;
float glow_intensity;
float glow_strength;
+ float glow_mix;
float glow_bloom;
GlowBlendMode glow_blend_mode;
float glow_hdr_bleed_threshold;
@@ -147,18 +148,6 @@ private:
float glow_hdr_luminance_cap;
bool glow_bicubic_upscale;
- bool dof_blur_far_enabled;
- float dof_blur_far_distance;
- float dof_blur_far_transition;
- float dof_blur_far_amount;
- DOFBlurQuality dof_blur_far_quality;
-
- bool dof_blur_near_enabled;
- float dof_blur_near_distance;
- float dof_blur_near_transition;
- float dof_blur_near_amount;
- DOFBlurQuality dof_blur_near_quality;
-
bool fog_enabled;
Color fog_color;
Color fog_sun_color;
@@ -180,14 +169,17 @@ private:
protected:
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const;
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
+ bool _set(const StringName &p_name, const Variant &p_value);
+#endif
public:
void set_background(BGMode p_bg);
+
void set_sky(const Ref<Sky> &p_sky);
void set_sky_custom_fov(float p_scale);
- void set_sky_orientation(const Basis &p_orientation);
- void set_sky_rotation(const Vector3 &p_euler_rad);
- void set_sky_rotation_degrees(const Vector3 &p_euler_deg);
+ void set_sky_rotation(const Vector3 &p_rotation);
void set_bg_color(const Color &p_color);
void set_bg_energy(float p_energy);
void set_canvas_max_layer(int p_max_layer);
@@ -195,13 +187,15 @@ public:
void set_ambient_light_energy(float p_energy);
void set_ambient_light_sky_contribution(float p_energy);
void set_camera_feed_id(int p_camera_feed_id);
+ void set_ambient_source(AmbientSource p_source);
+ AmbientSource get_ambient_source() const;
+ void set_reflection_source(ReflectionSource p_source);
+ ReflectionSource get_reflection_source() const;
BGMode get_background() const;
Ref<Sky> get_sky() const;
float get_sky_custom_fov() const;
- Basis get_sky_orientation() const;
Vector3 get_sky_rotation() const;
- Vector3 get_sky_rotation_degrees() const;
Color get_bg_color() const;
float get_bg_energy() const;
int get_canvas_max_layer() const;
@@ -246,8 +240,8 @@ public:
void set_adjustment_saturation(float p_saturation);
float get_adjustment_saturation() const;
- void set_adjustment_color_correction(const Ref<Texture> &p_ramp);
- Ref<Texture> get_adjustment_color_correction() const;
+ void set_adjustment_color_correction(const Ref<Texture2D> &p_ramp);
+ Ref<Texture2D> get_adjustment_color_correction() const;
void set_ssr_enabled(bool p_enable);
bool is_ssr_enabled() const;
@@ -276,12 +270,6 @@ public:
void set_ssao_intensity(float p_intensity);
float get_ssao_intensity() const;
- void set_ssao_radius2(float p_radius);
- float get_ssao_radius2() const;
-
- void set_ssao_intensity2(float p_intensity);
- float get_ssao_intensity2() const;
-
void set_ssao_bias(float p_bias);
float get_ssao_bias() const;
@@ -291,15 +279,12 @@ public:
void set_ssao_ao_channel_affect(float p_ao_channel_affect);
float get_ssao_ao_channel_affect() const;
- void set_ssao_color(const Color &p_color);
- Color get_ssao_color() const;
+ void set_ao_color(const Color &p_color);
+ Color get_ao_color() const;
void set_ssao_blur(SSAOBlur p_blur);
SSAOBlur get_ssao_blur() const;
- void set_ssao_quality(SSAOQuality p_quality);
- SSAOQuality get_ssao_quality() const;
-
void set_ssao_edge_sharpness(float p_edge_sharpness);
float get_ssao_edge_sharpness() const;
@@ -315,6 +300,9 @@ public:
void set_glow_strength(float p_strength);
float get_glow_strength() const;
+ void set_glow_mix(float p_mix);
+ float get_glow_mix() const;
+
void set_glow_bloom(float p_threshold);
float get_glow_bloom() const;
@@ -333,36 +321,6 @@ public:
void set_glow_bicubic_upscale(bool p_enable);
bool is_glow_bicubic_upscale_enabled() const;
- void set_dof_blur_far_enabled(bool p_enable);
- bool is_dof_blur_far_enabled() const;
-
- void set_dof_blur_far_distance(float p_distance);
- float get_dof_blur_far_distance() const;
-
- void set_dof_blur_far_transition(float p_distance);
- float get_dof_blur_far_transition() const;
-
- void set_dof_blur_far_amount(float p_amount);
- float get_dof_blur_far_amount() const;
-
- void set_dof_blur_far_quality(DOFBlurQuality p_quality);
- DOFBlurQuality get_dof_blur_far_quality() const;
-
- void set_dof_blur_near_enabled(bool p_enable);
- bool is_dof_blur_near_enabled() const;
-
- void set_dof_blur_near_distance(float p_distance);
- float get_dof_blur_near_distance() const;
-
- void set_dof_blur_near_transition(float p_distance);
- float get_dof_blur_near_transition() const;
-
- void set_dof_blur_near_amount(float p_amount);
- float get_dof_blur_near_amount() const;
-
- void set_dof_blur_near_quality(DOFBlurQuality p_quality);
- DOFBlurQuality get_dof_blur_near_quality() const;
-
void set_fog_enabled(bool p_enabled);
bool is_fog_enabled() const;
@@ -412,10 +370,67 @@ public:
};
VARIANT_ENUM_CAST(Environment::BGMode)
+VARIANT_ENUM_CAST(Environment::AmbientSource)
+VARIANT_ENUM_CAST(Environment::ReflectionSource)
VARIANT_ENUM_CAST(Environment::ToneMapper)
VARIANT_ENUM_CAST(Environment::GlowBlendMode)
-VARIANT_ENUM_CAST(Environment::DOFBlurQuality)
-VARIANT_ENUM_CAST(Environment::SSAOQuality)
VARIANT_ENUM_CAST(Environment::SSAOBlur)
+class CameraEffects : public Resource {
+
+ GDCLASS(CameraEffects, Resource);
+
+private:
+ RID camera_effects;
+
+ bool dof_blur_far_enabled;
+ float dof_blur_far_distance;
+ float dof_blur_far_transition;
+
+ bool dof_blur_near_enabled;
+ float dof_blur_near_distance;
+ float dof_blur_near_transition;
+
+ float dof_blur_amount;
+
+ bool override_exposure_enabled;
+ float override_exposure;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_dof_blur_far_enabled(bool p_enable);
+ bool is_dof_blur_far_enabled() const;
+
+ void set_dof_blur_far_distance(float p_distance);
+ float get_dof_blur_far_distance() const;
+
+ void set_dof_blur_far_transition(float p_distance);
+ float get_dof_blur_far_transition() const;
+
+ void set_dof_blur_near_enabled(bool p_enable);
+ bool is_dof_blur_near_enabled() const;
+
+ void set_dof_blur_near_distance(float p_distance);
+ float get_dof_blur_near_distance() const;
+
+ void set_dof_blur_near_transition(float p_distance);
+ float get_dof_blur_near_transition() const;
+
+ void set_dof_blur_amount(float p_amount);
+ float get_dof_blur_amount() const;
+
+ void set_override_exposure_enabled(bool p_enabled);
+ bool is_override_exposure_enabled() const;
+
+ void set_override_exposure(float p_exposure);
+ float get_override_exposure() const;
+
+ virtual RID get_rid() const;
+
+ CameraEffects();
+ ~CameraEffects();
+};
+
#endif // ENVIRONMENT_H
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 19c59b3817..872d6a043c 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -182,7 +182,7 @@ void BitmapFont::_set_textures(const Vector<Variant> &p_textures) {
textures.clear();
for (int i = 0; i < p_textures.size(); i++) {
- Ref<Texture> tex = p_textures[i];
+ Ref<Texture2D> tex = p_textures[i];
ERR_CONTINUE(!tex.is_valid());
add_texture(tex);
}
@@ -192,7 +192,7 @@ Vector<Variant> BitmapFont::_get_textures() const {
Vector<Variant> rtextures;
for (int i = 0; i < textures.size(); i++)
- rtextures.push_back(textures[i].get_ref_ptr());
+ rtextures.push_back(textures[i]);
return rtextures;
}
@@ -270,7 +270,7 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
String base_dir = p_file.get_base_dir();
String file = base_dir.plus_file(keys["file"]);
- Ref<Texture> tex = ResourceLoader::load(file);
+ Ref<Texture2D> tex = ResourceLoader::load(file);
if (tex.is_null()) {
ERR_PRINT("Can't load font texture!");
} else {
@@ -356,7 +356,7 @@ float BitmapFont::get_descent() const {
return height - ascent;
}
-void BitmapFont::add_texture(const Ref<Texture> &p_texture) {
+void BitmapFont::add_texture(const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND_MSG(p_texture.is_null(), "It's not a reference to a valid Texture object.");
textures.push_back(p_texture);
@@ -367,9 +367,9 @@ int BitmapFont::get_texture_count() const {
return textures.size();
};
-Ref<Texture> BitmapFont::get_texture(int p_idx) const {
+Ref<Texture2D> BitmapFont::get_texture(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, textures.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_idx, textures.size(), Ref<Texture2D>());
return textures[p_idx];
};
@@ -556,7 +556,7 @@ float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_c
cpos.x += c->h_align;
cpos.y -= ascent;
cpos.y += c->v_align;
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx]->get_rid(), c->rect, p_modulate, false, RID(), false);
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx]->get_rid(), c->rect, p_modulate, false, RID(), RID(), Color(1, 1, 1, 1), false);
}
return get_char_size(p_char, p_next).width;
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 411145c153..fc1d92e2f9 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -108,7 +108,7 @@ class BitmapFont : public Font {
GDCLASS(BitmapFont, Font);
RES_BASE_EXTENSION("font");
- Vector<Ref<Texture> > textures;
+ Vector<Ref<Texture2D> > textures;
public:
struct Character {
@@ -168,7 +168,7 @@ public:
float get_ascent() const;
float get_descent() const;
- void add_texture(const Ref<Texture> &p_texture);
+ void add_texture(const Ref<Texture2D> &p_texture);
void add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1);
int get_character_count() const;
@@ -176,7 +176,7 @@ public:
Character get_character(CharType p_char) const;
int get_texture_count() const;
- Ref<Texture> get_texture(int p_idx) const;
+ Ref<Texture2D> get_texture(int p_idx) const;
void add_kerning_pair(CharType p_A, CharType p_B, int p_kerning);
int get_kerning_pair(CharType p_A, CharType p_B) const;
diff --git a/scene/resources/height_map_shape.cpp b/scene/resources/height_map_shape.cpp
index 2b86d658d8..48c9221e27 100644
--- a/scene/resources/height_map_shape.cpp
+++ b/scene/resources/height_map_shape.cpp
@@ -76,6 +76,10 @@ Vector<Vector3> HeightMapShape::get_debug_mesh_lines() {
return points;
}
+real_t HeightMapShape::get_enclosing_radius() const {
+ return Vector3(real_t(map_width), max_height - min_height, real_t(map_depth)).length();
+}
+
void HeightMapShape::_update_shape() {
Dictionary d;
diff --git a/scene/resources/height_map_shape.h b/scene/resources/height_map_shape.h
index 3a976e3add..a6263f061f 100644
--- a/scene/resources/height_map_shape.h
+++ b/scene/resources/height_map_shape.h
@@ -55,6 +55,7 @@ public:
PoolRealArray get_map_data() const;
virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const;
HeightMapShape();
};
diff --git a/scene/resources/line_shape_2d.cpp b/scene/resources/line_shape_2d.cpp
index 7f39467403..d1bb61820b 100644
--- a/scene/resources/line_shape_2d.cpp
+++ b/scene/resources/line_shape_2d.cpp
@@ -100,6 +100,10 @@ Rect2 LineShape2D::get_rect() const {
return rect;
}
+real_t LineShape2D::get_enclosing_radius() const {
+ return d;
+}
+
void LineShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_normal", "normal"), &LineShape2D::set_normal);
@@ -115,7 +119,7 @@ void LineShape2D::_bind_methods() {
LineShape2D::LineShape2D() :
Shape2D(Physics2DServer::get_singleton()->line_shape_create()) {
- normal = Vector2(0, -1);
+ normal = Vector2(0, 1);
d = 0;
_update_shape();
}
diff --git a/scene/resources/line_shape_2d.h b/scene/resources/line_shape_2d.h
index 7babfe12f6..5bf9e85bb9 100644
--- a/scene/resources/line_shape_2d.h
+++ b/scene/resources/line_shape_2d.h
@@ -55,6 +55,7 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
LineShape2D();
};
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index ab4dbb758a..6e2fe01834 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -171,7 +171,7 @@ bool ShaderMaterial::property_can_revert(const String &p_name) {
StringName pr = shader->remap_param(p_name);
if (pr) {
- Variant default_value = VisualServer::get_singleton()->material_get_param_default(_get_material(), pr);
+ Variant default_value = VisualServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr);
Variant current_value;
_get(p_name, current_value);
return default_value.get_type() != Variant::NIL && default_value != current_value;
@@ -185,7 +185,7 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) {
if (shader.is_valid()) {
StringName pr = shader->remap_param(p_name);
if (pr) {
- r_ret = VisualServer::get_singleton()->material_get_param_default(_get_material(), pr);
+ r_ret = VisualServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr);
}
}
return r_ret;
@@ -290,18 +290,18 @@ ShaderMaterial::~ShaderMaterial() {
/////////////////////////////////
-Mutex *SpatialMaterial::material_mutex = NULL;
-SelfList<SpatialMaterial>::List *SpatialMaterial::dirty_materials = NULL;
-Map<SpatialMaterial::MaterialKey, SpatialMaterial::ShaderData> SpatialMaterial::shader_map;
-SpatialMaterial::ShaderNames *SpatialMaterial::shader_names = NULL;
+Mutex *BaseMaterial3D::material_mutex = NULL;
+SelfList<BaseMaterial3D>::List *BaseMaterial3D::dirty_materials = NULL;
+Map<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData> BaseMaterial3D::shader_map;
+BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = NULL;
-void SpatialMaterial::init_shaders() {
+void BaseMaterial3D::init_shaders() {
#ifndef NO_THREADS
material_mutex = Mutex::create();
#endif
- dirty_materials = memnew(SelfList<SpatialMaterial>::List);
+ dirty_materials = memnew(SelfList<BaseMaterial3D>::List);
shader_names = memnew(ShaderNames);
@@ -317,7 +317,7 @@ void SpatialMaterial::init_shaders() {
shader_names->clearcoat = "clearcoat";
shader_names->clearcoat_gloss = "clearcoat_gloss";
shader_names->anisotropy = "anisotropy_ratio";
- shader_names->depth_scale = "depth_scale";
+ shader_names->heightmap_scale = "heightmap_scale";
shader_names->subsurface_scattering_strength = "subsurface_scattering_strength";
shader_names->transmission = "transmission";
shader_names->refraction = "refraction";
@@ -332,9 +332,9 @@ void SpatialMaterial::init_shaders() {
shader_names->particles_anim_h_frames = "particles_anim_h_frames";
shader_names->particles_anim_v_frames = "particles_anim_v_frames";
shader_names->particles_anim_loop = "particles_anim_loop";
- shader_names->depth_min_layers = "depth_min_layers";
- shader_names->depth_max_layers = "depth_max_layers";
- shader_names->depth_flip = "depth_flip";
+ shader_names->heightmap_min_layers = "heightmap_min_layers";
+ shader_names->heightmap_max_layers = "heightmap_max_layers";
+ shader_names->heightmap_flip = "heightmap_flip";
shader_names->grow = "grow";
@@ -345,11 +345,10 @@ void SpatialMaterial::init_shaders() {
shader_names->distance_fade_max = "distance_fade_max";
shader_names->metallic_texture_channel = "metallic_texture_channel";
- shader_names->roughness_texture_channel = "roughness_texture_channel";
shader_names->ao_texture_channel = "ao_texture_channel";
shader_names->clearcoat_texture_channel = "clearcoat_texture_channel";
shader_names->rim_texture_channel = "rim_texture_channel";
- shader_names->depth_texture_channel = "depth_texture_channel";
+ shader_names->heightmap_texture_channel = "heightmap_texture_channel";
shader_names->refraction_texture_channel = "refraction_texture_channel";
shader_names->alpha_scissor_threshold = "alpha_scissor_threshold";
@@ -362,18 +361,19 @@ void SpatialMaterial::init_shaders() {
shader_names->texture_names[TEXTURE_CLEARCOAT] = "texture_clearcoat";
shader_names->texture_names[TEXTURE_FLOWMAP] = "texture_flowmap";
shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion";
- shader_names->texture_names[TEXTURE_DEPTH] = "texture_depth";
+ shader_names->texture_names[TEXTURE_HEIGHTMAP] = "texture_heightmap";
shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering";
shader_names->texture_names[TEXTURE_TRANSMISSION] = "texture_transmission";
shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction";
shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask";
shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo";
shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal";
+ shader_names->texture_names[TEXTURE_ORM] = "texture_orm";
}
-Ref<SpatialMaterial> SpatialMaterial::materials_for_2d[SpatialMaterial::MAX_MATERIALS_FOR_2D];
+Ref<StandardMaterial3D> BaseMaterial3D::materials_for_2d[BaseMaterial3D::MAX_MATERIALS_FOR_2D];
-void SpatialMaterial::finish_shaders() {
+void BaseMaterial3D::finish_shaders() {
for (int i = 0; i < MAX_MATERIALS_FOR_2D; i++) {
materials_for_2d[i].unref();
@@ -389,7 +389,7 @@ void SpatialMaterial::finish_shaders() {
memdelete(shader_names);
}
-void SpatialMaterial::_update_shader() {
+void BaseMaterial3D::_update_shader() {
dirty_materials->remove(&element);
@@ -415,6 +415,23 @@ void SpatialMaterial::_update_shader() {
return;
}
+ String texfilter_str;
+ switch (texture_filter) {
+ case TEXTURE_FILTER_NEAREST: texfilter_str = "filter_nearest"; break;
+ case TEXTURE_FILTER_LINEAR: texfilter_str = "filter_linear"; break;
+ case TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS: texfilter_str = "filter_nearest_mipmap"; break;
+ case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: texfilter_str = "filter_linear_mipmap"; break;
+ case TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC: texfilter_str = "filter_nearest_mipmap_aniso"; break;
+ case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: texfilter_str = "filter_linear_mipmap_aniso"; break;
+ case TEXTURE_FILTER_MAX: break; // Internal value, skip.
+ }
+
+ if (flags[FLAG_USE_TEXTURE_REPEAT]) {
+ texfilter_str += ",repeat_enable";
+ } else {
+ texfilter_str += ",repeat_disable";
+ }
+
//must create a shader!
String code = "shader_type spatial;\nrender_mode ";
@@ -434,7 +451,10 @@ void SpatialMaterial::_update_shader() {
case DEPTH_DRAW_OPAQUE_ONLY: code += ",depth_draw_opaque"; break;
case DEPTH_DRAW_ALWAYS: code += ",depth_draw_always"; break;
case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break;
- case DEPTH_DRAW_ALPHA_OPAQUE_PREPASS: code += ",depth_draw_alpha_prepass"; break;
+ }
+
+ if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) {
+ code += ",depth_prepass_alpha";
}
switch (cull_mode) {
@@ -457,36 +477,28 @@ void SpatialMaterial::_update_shader() {
case SPECULAR_DISABLED: code += ",specular_disabled"; break;
}
- if (flags[FLAG_UNSHADED]) {
+ if (shading_mode == SHADING_MODE_UNSHADED) {
code += ",unshaded";
}
if (flags[FLAG_DISABLE_DEPTH_TEST]) {
- code += ",depth_test_disable";
+ code += ",depth_test_disabled";
}
- if (flags[FLAG_USE_VERTEX_LIGHTING]) {
+ if (shading_mode == SHADING_MODE_PER_VERTEX) {
code += ",vertex_lighting";
}
- if (flags[FLAG_TRIPLANAR_USE_WORLD] && (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR])) {
- code += ",world_vertex_coords";
- }
if (flags[FLAG_DONT_RECEIVE_SHADOWS]) {
code += ",shadows_disabled";
}
if (flags[FLAG_DISABLE_AMBIENT_LIGHT]) {
code += ",ambient_light_disabled";
}
- if (flags[FLAG_ENSURE_CORRECT_NORMALS]) {
- code += ",ensure_correct_normals";
- }
if (flags[FLAG_USE_SHADOW_TO_OPACITY]) {
code += ",shadow_to_opacity";
}
code += ";\n";
code += "uniform vec4 albedo : hint_color;\n";
- code += "uniform sampler2D texture_albedo : hint_albedo;\n";
- code += "uniform float specular;\n";
- code += "uniform float metallic;\n";
+ code += "uniform sampler2D texture_albedo : hint_albedo," + texfilter_str + ";\n";
if (grow_enabled) {
code += "uniform float grow;\n";
}
@@ -499,21 +511,41 @@ void SpatialMaterial::_update_shader() {
code += "uniform float distance_fade_max;\n";
}
- if (flags[FLAG_USE_ALPHA_SCISSOR]) {
+ if (transparency == TRANSPARENCY_ALPHA_SCISSOR) {
code += "uniform float alpha_scissor_threshold;\n";
}
- code += "uniform float roughness : hint_range(0,1);\n";
+
code += "uniform float point_size : hint_range(0,128);\n";
- if (textures[TEXTURE_METALLIC] != NULL) {
- code += "uniform sampler2D texture_metallic : hint_white;\n";
+ //TODO ALL HINTS
+ if (!orm) {
+ code += "uniform float roughness : hint_range(0,1);\n";
+ code += "uniform sampler2D texture_metallic : hint_white," + texfilter_str + ";\n";
code += "uniform vec4 metallic_texture_channel;\n";
- }
+ switch (roughness_texture_channel) {
+ case TEXTURE_CHANNEL_RED: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_r," + texfilter_str + ";\n";
+ } break;
+ case TEXTURE_CHANNEL_GREEN: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_g," + texfilter_str + ";\n";
+ } break;
+ case TEXTURE_CHANNEL_BLUE: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_b," + texfilter_str + ";\n";
+ } break;
+ case TEXTURE_CHANNEL_ALPHA: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_a," + texfilter_str + ";\n";
+ } break;
+ case TEXTURE_CHANNEL_GRAYSCALE: {
+ code += "uniform sampler2D texture_roughness : hint_roughness_gray," + texfilter_str + ";\n";
+ } break;
+ }
- if (textures[TEXTURE_ROUGHNESS] != NULL) {
- code += "uniform sampler2D texture_roughness : hint_white;\n";
- code += "uniform vec4 roughness_texture_channel;\n";
+ code += "uniform float specular;\n";
+ code += "uniform float metallic;\n";
+ } else {
+ code += "uniform sampler2D texture_orm : hint_roughness_g," + texfilter_str + ";\n";
}
+
if (billboard_mode == BILLBOARD_PARTICLES) {
code += "uniform int particles_anim_h_frames;\n";
code += "uniform int particles_anim_v_frames;\n";
@@ -522,34 +554,34 @@ void SpatialMaterial::_update_shader() {
if (features[FEATURE_EMISSION]) {
- code += "uniform sampler2D texture_emission : hint_black_albedo;\n";
+ code += "uniform sampler2D texture_emission : hint_black_albedo," + texfilter_str + ";\n";
code += "uniform vec4 emission : hint_color;\n";
code += "uniform float emission_energy;\n";
}
if (features[FEATURE_REFRACTION]) {
- code += "uniform sampler2D texture_refraction;\n";
+ code += "uniform sampler2D texture_refraction : " + texfilter_str + ";\n";
code += "uniform float refraction : hint_range(-16,16);\n";
code += "uniform vec4 refraction_texture_channel;\n";
}
if (features[FEATURE_NORMAL_MAPPING]) {
- code += "uniform sampler2D texture_normal : hint_normal;\n";
+ code += "uniform sampler2D texture_normal : hint_roughness_normal," + texfilter_str + ";\n";
code += "uniform float normal_scale : hint_range(-16,16);\n";
}
if (features[FEATURE_RIM]) {
code += "uniform float rim : hint_range(0,1);\n";
code += "uniform float rim_tint : hint_range(0,1);\n";
- code += "uniform sampler2D texture_rim : hint_white;\n";
+ code += "uniform sampler2D texture_rim : hint_white," + texfilter_str + ";\n";
}
if (features[FEATURE_CLEARCOAT]) {
code += "uniform float clearcoat : hint_range(0,1);\n";
code += "uniform float clearcoat_gloss : hint_range(0,1);\n";
- code += "uniform sampler2D texture_clearcoat : hint_white;\n";
+ code += "uniform sampler2D texture_clearcoat : hint_white," + texfilter_str + ";\n";
}
if (features[FEATURE_ANISOTROPY]) {
code += "uniform float anisotropy_ratio : hint_range(0,256);\n";
- code += "uniform sampler2D texture_flowmap : hint_aniso;\n";
+ code += "uniform sampler2D texture_flowmap : hint_aniso," + texfilter_str + ";\n";
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
code += "uniform sampler2D texture_ambient_occlusion : hint_white;\n";
@@ -558,29 +590,29 @@ void SpatialMaterial::_update_shader() {
}
if (features[FEATURE_DETAIL]) {
- code += "uniform sampler2D texture_detail_albedo : hint_albedo;\n";
- code += "uniform sampler2D texture_detail_normal : hint_normal;\n";
- code += "uniform sampler2D texture_detail_mask : hint_white;\n";
+ code += "uniform sampler2D texture_detail_albedo : hint_albedo," + texfilter_str + ";\n";
+ code += "uniform sampler2D texture_detail_normal : hint_normal," + texfilter_str + ";\n";
+ code += "uniform sampler2D texture_detail_mask : hint_white," + texfilter_str + ";\n";
}
if (features[FEATURE_SUBSURACE_SCATTERING]) {
code += "uniform float subsurface_scattering_strength : hint_range(0,1);\n";
- code += "uniform sampler2D texture_subsurface_scattering : hint_white;\n";
+ code += "uniform sampler2D texture_subsurface_scattering : hint_white," + texfilter_str + ";\n";
}
if (features[FEATURE_TRANSMISSION]) {
code += "uniform vec4 transmission : hint_color;\n";
- code += "uniform sampler2D texture_transmission : hint_black;\n";
+ code += "uniform sampler2D texture_transmission : hint_black," + texfilter_str + ";\n";
}
- if (features[FEATURE_DEPTH_MAPPING]) {
- code += "uniform sampler2D texture_depth : hint_black;\n";
- code += "uniform float depth_scale;\n";
- code += "uniform int depth_min_layers;\n";
- code += "uniform int depth_max_layers;\n";
- code += "uniform vec2 depth_flip;\n";
+ if (features[FEATURE_HEIGHT_MAPPING]) {
+ code += "uniform sampler2D texture_heightmap : hint_black," + texfilter_str + ";\n";
+ code += "uniform float heightmap_scale;\n";
+ code += "uniform int heightmap_min_layers;\n";
+ code += "uniform int heightmap_max_layers;\n";
+ code += "uniform vec2 heightmap_flip;\n";
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "varying vec3 uv1_triplanar_pos;\n";
@@ -618,7 +650,7 @@ void SpatialMaterial::_update_shader() {
code += "\tPOINT_SIZE=point_size;\n";
}
- if (flags[FLAG_USE_VERTEX_LIGHTING]) {
+ if (shading_mode == SHADING_MODE_PER_VERTEX) {
code += "\tROUGHNESS=roughness;\n";
}
@@ -750,33 +782,49 @@ void SpatialMaterial::_update_shader() {
code += "\tvec2 base_uv2 = UV2;\n";
}
- if (!VisualServer::get_singleton()->is_low_end() && features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar
+ if (!VisualServer::get_singleton()->is_low_end() && features[FEATURE_HEIGHT_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //heightmap not supported with triplanar
code += "\t{\n";
- code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-)
+ code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*heightmap_flip.x,-BINORMAL*heightmap_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-)
if (deep_parallax) {
- code += "\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
+ code += "\t\tfloat num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
code += "\t\tfloat layer_depth = 1.0 / num_layers;\n";
code += "\t\tfloat current_layer_depth = 0.0;\n";
- code += "\t\tvec2 P = view_dir.xy * depth_scale;\n";
+ code += "\t\tvec2 P = view_dir.xy * heightmap_scale;\n";
code += "\t\tvec2 delta = P / num_layers;\n";
code += "\t\tvec2 ofs = base_uv;\n";
- code += "\t\tfloat depth = textureLod(texture_depth, ofs,0.0).r;\n";
+ if (flags[FLAG_INVERT_HEIGHTMAP]) {
+ code += "\t\tfloat depth = texture(texture_heightmap, ofs).r;\n";
+ } else {
+ code += "\t\tfloat depth = 1.0 - texture(texture_heightmap, ofs).r;\n";
+ }
code += "\t\tfloat current_depth = 0.0;\n";
code += "\t\twhile(current_depth < depth) {\n";
code += "\t\t\tofs -= delta;\n";
- code += "\t\t\tdepth = textureLod(texture_depth, ofs,0.0).r;\n";
+ if (flags[FLAG_INVERT_HEIGHTMAP]) {
+ code += "\t\t\tdepth = texture(texture_heightmap, ofs).r;\n";
+ } else {
+ code += "\t\t\tdepth = 1.0 - texture(texture_heightmap, ofs).r;\n";
+ }
code += "\t\t\tcurrent_depth += layer_depth;\n";
code += "\t\t}\n";
code += "\t\tvec2 prev_ofs = ofs + delta;\n";
code += "\t\tfloat after_depth = depth - current_depth;\n";
- code += "\t\tfloat before_depth = textureLod(texture_depth, prev_ofs, 0.0).r - current_depth + layer_depth;\n";
+ if (flags[FLAG_INVERT_HEIGHTMAP]) {
+ code += "\t\tfloat before_depth = texture(texture_heightmap, prev_ofs).r - current_depth + layer_depth;\n";
+ } else {
+ code += "\t\tfloat before_depth = ( 1.0 - texture(texture_heightmap, prev_ofs).r ) - current_depth + layer_depth;\n";
+ }
code += "\t\tfloat weight = after_depth / (after_depth - before_depth);\n";
code += "\t\tofs = mix(ofs,prev_ofs,weight);\n";
} else {
- code += "\t\tfloat depth = texture(texture_depth, base_uv).r;\n";
- code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * depth_scale);\n";
+ if (flags[FLAG_INVERT_HEIGHTMAP]) {
+ code += "\t\tfloat depth = texture(texture_heightmap, base_uv).r;\n";
+ } else {
+ code += "\t\tfloat depth = 1.0 - texture(texture_heightmap, base_uv).r;\n";
+ }
+ code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * heightmap_scale);\n";
}
code += "\t\tbase_uv=ofs;\n";
@@ -806,29 +854,49 @@ void SpatialMaterial::_update_shader() {
}
code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";
- if (textures[TEXTURE_METALLIC] != NULL) {
+ if (!orm) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n";
} else {
code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n";
}
code += "\tMETALLIC = metallic_tex * metallic;\n";
- } else {
- code += "\tMETALLIC = metallic;\n";
- }
- if (textures[TEXTURE_ROUGHNESS] != NULL) {
+ switch (roughness_texture_channel) {
+ case TEXTURE_CHANNEL_RED: {
+ code += "\tvec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n";
+ } break;
+ case TEXTURE_CHANNEL_GREEN: {
+ code += "\tvec4 roughness_texture_channel = vec4(0.0,1.0,0.0,0.0);\n";
+ } break;
+ case TEXTURE_CHANNEL_BLUE: {
+ code += "\tvec4 roughness_texture_channel = vec4(0.0,0.0,1.0,0.0);\n";
+ } break;
+ case TEXTURE_CHANNEL_ALPHA: {
+ code += "\tvec4 roughness_texture_channel = vec4(0.0,0.0,0.0,1.0);\n";
+ } break;
+ case TEXTURE_CHANNEL_GRAYSCALE: {
+ code += "\tvec4 roughness_texture_channel = vec4(0.333333,0.333333,0.333333,0.0);\n";
+ } break;
+ }
+
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n";
} else {
code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n";
}
code += "\tROUGHNESS = roughness_tex * roughness;\n";
+ code += "\tSPECULAR = specular;\n";
} else {
- code += "\tROUGHNESS = roughness;\n";
- }
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tfloat orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
+ } else {
+ code += "\tfloat orm_tex = texture(texture_orm,base_uv);\n";
+ }
- code += "\tSPECULAR = specular;\n";
+ code += "\tROUGHNESS = orm_tex.g;\n";
+ code += "\tMETALLIC = orm_tex.b;\n";
+ }
if (features[FEATURE_NORMAL_MAPPING]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
@@ -878,8 +946,10 @@ void SpatialMaterial::_update_shader() {
code += "\tALBEDO *= 1.0 - ref_amount;\n";
code += "\tALPHA = 1.0;\n";
- } else if (features[FEATURE_TRANSPARENT] || flags[FLAG_USE_ALPHA_SCISSOR] || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
+ } else if (transparency == TRANSPARENCY_ALPHA || transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) {
code += "\tALPHA = albedo.a * albedo_tex.a;\n";
+ } else if (transparency == TRANSPARENCY_ALPHA_SCISSOR) {
+ code += "\tif (albedo.a * albedo_tex.a < alpha_scissor_threshold) discard;\n";
}
if (proximity_fade_enabled) {
@@ -965,18 +1035,23 @@ void SpatialMaterial::_update_shader() {
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
- if (flags[FLAG_AO_ON_UV2]) {
- if (flags[FLAG_UV2_USE_TRIPLANAR]) {
- code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
+
+ if (!orm) {
+ if (flags[FLAG_AO_ON_UV2]) {
+ if (flags[FLAG_UV2_USE_TRIPLANAR]) {
+ code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n";
+ } else {
+ code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
+ }
} else {
- code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
+ } else {
+ code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
+ }
}
} else {
- if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n";
- } else {
- code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
- }
+ code += "\tAO = orm_tex.r;\n";
}
code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n";
@@ -1043,10 +1118,6 @@ void SpatialMaterial::_update_shader() {
code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
}
- if (flags[FLAG_USE_ALPHA_SCISSOR]) {
- code += "\tALPHA_SCISSOR=alpha_scissor_threshold;\n";
- }
-
code += "}\n";
ShaderData shader_data;
@@ -1060,7 +1131,7 @@ void SpatialMaterial::_update_shader() {
VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
}
-void SpatialMaterial::flush_changes() {
+void BaseMaterial3D::flush_changes() {
if (material_mutex)
material_mutex->lock();
@@ -1074,7 +1145,7 @@ void SpatialMaterial::flush_changes() {
material_mutex->unlock();
}
-void SpatialMaterial::_queue_shader_change() {
+void BaseMaterial3D::_queue_shader_change() {
if (material_mutex)
material_mutex->lock();
@@ -1087,7 +1158,7 @@ void SpatialMaterial::_queue_shader_change() {
material_mutex->unlock();
}
-bool SpatialMaterial::_is_shader_dirty() const {
+bool BaseMaterial3D::_is_shader_dirty() const {
bool dirty = false;
@@ -1101,188 +1172,188 @@ bool SpatialMaterial::_is_shader_dirty() const {
return dirty;
}
-void SpatialMaterial::set_albedo(const Color &p_albedo) {
+void BaseMaterial3D::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
VS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo);
}
-Color SpatialMaterial::get_albedo() const {
+Color BaseMaterial3D::get_albedo() const {
return albedo;
}
-void SpatialMaterial::set_specular(float p_specular) {
+void BaseMaterial3D::set_specular(float p_specular) {
specular = p_specular;
VS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
}
-float SpatialMaterial::get_specular() const {
+float BaseMaterial3D::get_specular() const {
return specular;
}
-void SpatialMaterial::set_roughness(float p_roughness) {
+void BaseMaterial3D::set_roughness(float p_roughness) {
roughness = p_roughness;
VS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness);
}
-float SpatialMaterial::get_roughness() const {
+float BaseMaterial3D::get_roughness() const {
return roughness;
}
-void SpatialMaterial::set_metallic(float p_metallic) {
+void BaseMaterial3D::set_metallic(float p_metallic) {
metallic = p_metallic;
VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic);
}
-float SpatialMaterial::get_metallic() const {
+float BaseMaterial3D::get_metallic() const {
return metallic;
}
-void SpatialMaterial::set_emission(const Color &p_emission) {
+void BaseMaterial3D::set_emission(const Color &p_emission) {
emission = p_emission;
VS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission);
}
-Color SpatialMaterial::get_emission() const {
+Color BaseMaterial3D::get_emission() const {
return emission;
}
-void SpatialMaterial::set_emission_energy(float p_emission_energy) {
+void BaseMaterial3D::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 SpatialMaterial::get_emission_energy() const {
+float BaseMaterial3D::get_emission_energy() const {
return emission_energy;
}
-void SpatialMaterial::set_normal_scale(float p_normal_scale) {
+void BaseMaterial3D::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 SpatialMaterial::get_normal_scale() const {
+float BaseMaterial3D::get_normal_scale() const {
return normal_scale;
}
-void SpatialMaterial::set_rim(float p_rim) {
+void BaseMaterial3D::set_rim(float p_rim) {
rim = p_rim;
VS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim);
}
-float SpatialMaterial::get_rim() const {
+float BaseMaterial3D::get_rim() const {
return rim;
}
-void SpatialMaterial::set_rim_tint(float p_rim_tint) {
+void BaseMaterial3D::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 SpatialMaterial::get_rim_tint() const {
+float BaseMaterial3D::get_rim_tint() const {
return rim_tint;
}
-void SpatialMaterial::set_ao_light_affect(float p_ao_light_affect) {
+void BaseMaterial3D::set_ao_light_affect(float p_ao_light_affect) {
ao_light_affect = p_ao_light_affect;
VS::get_singleton()->material_set_param(_get_material(), shader_names->ao_light_affect, p_ao_light_affect);
}
-float SpatialMaterial::get_ao_light_affect() const {
+float BaseMaterial3D::get_ao_light_affect() const {
return ao_light_affect;
}
-void SpatialMaterial::set_clearcoat(float p_clearcoat) {
+void BaseMaterial3D::set_clearcoat(float p_clearcoat) {
clearcoat = p_clearcoat;
VS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat);
}
-float SpatialMaterial::get_clearcoat() const {
+float BaseMaterial3D::get_clearcoat() const {
return clearcoat;
}
-void SpatialMaterial::set_clearcoat_gloss(float p_clearcoat_gloss) {
+void BaseMaterial3D::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 SpatialMaterial::get_clearcoat_gloss() const {
+float BaseMaterial3D::get_clearcoat_gloss() const {
return clearcoat_gloss;
}
-void SpatialMaterial::set_anisotropy(float p_anisotropy) {
+void BaseMaterial3D::set_anisotropy(float p_anisotropy) {
anisotropy = p_anisotropy;
VS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy);
}
-float SpatialMaterial::get_anisotropy() const {
+float BaseMaterial3D::get_anisotropy() const {
return anisotropy;
}
-void SpatialMaterial::set_depth_scale(float p_depth_scale) {
+void BaseMaterial3D::set_heightmap_scale(float p_heightmap_scale) {
- depth_scale = p_depth_scale;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_scale, p_depth_scale);
+ heightmap_scale = p_heightmap_scale;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_scale, p_heightmap_scale);
}
-float SpatialMaterial::get_depth_scale() const {
+float BaseMaterial3D::get_heightmap_scale() const {
- return depth_scale;
+ return heightmap_scale;
}
-void SpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
+void BaseMaterial3D::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 SpatialMaterial::get_subsurface_scattering_strength() const {
+float BaseMaterial3D::get_subsurface_scattering_strength() const {
return subsurface_scattering_strength;
}
-void SpatialMaterial::set_transmission(const Color &p_transmission) {
+void BaseMaterial3D::set_transmission(const Color &p_transmission) {
transmission = p_transmission;
VS::get_singleton()->material_set_param(_get_material(), shader_names->transmission, transmission);
}
-Color SpatialMaterial::get_transmission() const {
+Color BaseMaterial3D::get_transmission() const {
return transmission;
}
-void SpatialMaterial::set_refraction(float p_refraction) {
+void BaseMaterial3D::set_refraction(float p_refraction) {
refraction = p_refraction;
VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction);
}
-float SpatialMaterial::get_refraction() const {
+float BaseMaterial3D::get_refraction() const {
return refraction;
}
-void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) {
+void BaseMaterial3D::set_detail_uv(DetailUV p_detail_uv) {
if (detail_uv == p_detail_uv)
return;
@@ -1290,12 +1361,12 @@ void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) {
detail_uv = p_detail_uv;
_queue_shader_change();
}
-SpatialMaterial::DetailUV SpatialMaterial::get_detail_uv() const {
+BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const {
return detail_uv;
}
-void SpatialMaterial::set_blend_mode(BlendMode p_mode) {
+void BaseMaterial3D::set_blend_mode(BlendMode p_mode) {
if (blend_mode == p_mode)
return;
@@ -1303,22 +1374,52 @@ void SpatialMaterial::set_blend_mode(BlendMode p_mode) {
blend_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::BlendMode SpatialMaterial::get_blend_mode() const {
+BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
return blend_mode;
}
-void SpatialMaterial::set_detail_blend_mode(BlendMode p_mode) {
+void BaseMaterial3D::set_detail_blend_mode(BlendMode p_mode) {
detail_blend_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::BlendMode SpatialMaterial::get_detail_blend_mode() const {
+BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const {
return detail_blend_mode;
}
-void SpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) {
+void BaseMaterial3D::set_transparency(Transparency p_transparency) {
+
+ if (transparency == p_transparency) {
+ return;
+ }
+
+ transparency = p_transparency;
+ _queue_shader_change();
+ _change_notify();
+}
+
+BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const {
+ return transparency;
+}
+
+void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) {
+
+ if (shading_mode == p_shading_mode) {
+ return;
+ }
+
+ shading_mode = p_shading_mode;
+ _queue_shader_change();
+ _change_notify();
+}
+
+BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const {
+ return shading_mode;
+}
+
+void BaseMaterial3D::set_depth_draw_mode(DepthDrawMode p_mode) {
if (depth_draw_mode == p_mode)
return;
@@ -1326,12 +1427,12 @@ void SpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) {
depth_draw_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::DepthDrawMode SpatialMaterial::get_depth_draw_mode() const {
+BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
return depth_draw_mode;
}
-void SpatialMaterial::set_cull_mode(CullMode p_mode) {
+void BaseMaterial3D::set_cull_mode(CullMode p_mode) {
if (cull_mode == p_mode)
return;
@@ -1339,12 +1440,12 @@ void SpatialMaterial::set_cull_mode(CullMode p_mode) {
cull_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::CullMode SpatialMaterial::get_cull_mode() const {
+BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const {
return cull_mode;
}
-void SpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) {
+void BaseMaterial3D::set_diffuse_mode(DiffuseMode p_mode) {
if (diffuse_mode == p_mode)
return;
@@ -1352,12 +1453,12 @@ void SpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) {
diffuse_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::DiffuseMode SpatialMaterial::get_diffuse_mode() const {
+BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const {
return diffuse_mode;
}
-void SpatialMaterial::set_specular_mode(SpecularMode p_mode) {
+void BaseMaterial3D::set_specular_mode(SpecularMode p_mode) {
if (specular_mode == p_mode)
return;
@@ -1365,12 +1466,12 @@ void SpatialMaterial::set_specular_mode(SpecularMode p_mode) {
specular_mode = p_mode;
_queue_shader_change();
}
-SpatialMaterial::SpecularMode SpatialMaterial::get_specular_mode() const {
+BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const {
return specular_mode;
}
-void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) {
+void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
@@ -1378,19 +1479,19 @@ void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) {
return;
flags[p_flag] = p_enabled;
- if ((p_flag == FLAG_USE_ALPHA_SCISSOR) || (p_flag == FLAG_UNSHADED) || (p_flag == FLAG_USE_SHADOW_TO_OPACITY)) {
+ if ((p_flag == FLAG_USE_SHADOW_TO_OPACITY) || (p_flag == FLAG_USE_TEXTURE_REPEAT)) {
_change_notify();
}
_queue_shader_change();
}
-bool SpatialMaterial::get_flag(Flags p_flag) const {
+bool BaseMaterial3D::get_flag(Flags p_flag) const {
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags[p_flag];
}
-void SpatialMaterial::set_feature(Feature p_feature, bool p_enabled) {
+void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {
ERR_FAIL_INDEX(p_feature, FEATURE_MAX);
if (features[p_feature] == p_enabled)
@@ -1401,13 +1502,13 @@ void SpatialMaterial::set_feature(Feature p_feature, bool p_enabled) {
_queue_shader_change();
}
-bool SpatialMaterial::get_feature(Feature p_feature) const {
+bool BaseMaterial3D::get_feature(Feature p_feature) const {
ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, false);
return features[p_feature];
}
-void SpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_texture) {
+void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
textures[p_param] = p_texture;
@@ -1417,41 +1518,50 @@ void SpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_te
_queue_shader_change();
}
-Ref<Texture> SpatialMaterial::get_texture(TextureParam p_param) const {
+Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const {
- ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture2D>());
return textures[p_param];
}
-Ref<Texture> SpatialMaterial::get_texture_by_name(StringName p_name) const {
- for (int i = 0; i < (int)SpatialMaterial::TEXTURE_MAX; i++) {
+Ref<Texture2D> BaseMaterial3D::get_texture_by_name(StringName p_name) const {
+ for (int i = 0; i < (int)BaseMaterial3D::TEXTURE_MAX; i++) {
TextureParam param = TextureParam(i);
if (p_name == shader_names->texture_names[param])
return textures[param];
}
- return Ref<Texture>();
+ return Ref<Texture2D>();
}
-void SpatialMaterial::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const {
+void BaseMaterial3D::set_texture_filter(TextureFilter p_filter) {
+ texture_filter = p_filter;
+ _queue_shader_change();
+}
+
+BaseMaterial3D::TextureFilter BaseMaterial3D::get_texture_filter() const {
+ return texture_filter;
+}
+
+void BaseMaterial3D::_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 SpatialMaterial::_validate_high_end(const String &text, PropertyInfo &property) const {
+void BaseMaterial3D::_validate_high_end(const String &text, PropertyInfo &property) const {
if (property.name.begins_with(text)) {
property.usage |= PROPERTY_USAGE_HIGH_END_GFX;
}
}
-void SpatialMaterial::_validate_property(PropertyInfo &property) const {
+void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
_validate_feature("normal", FEATURE_NORMAL_MAPPING, property);
_validate_feature("emission", FEATURE_EMISSION, property);
_validate_feature("rim", FEATURE_RIM, property);
_validate_feature("clearcoat", FEATURE_CLEARCOAT, property);
_validate_feature("anisotropy", FEATURE_ANISOTROPY, property);
_validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property);
- _validate_feature("depth", FEATURE_DEPTH_MAPPING, property);
+ _validate_feature("heightmap", FEATURE_HEIGHT_MAPPING, property);
_validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property);
_validate_feature("transmission", FEATURE_TRANSMISSION, property);
_validate_feature("refraction", FEATURE_REFRACTION, property);
@@ -1461,7 +1571,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
_validate_high_end("subsurf_scatter", property);
_validate_high_end("anisotropy", property);
_validate_high_end("clearcoat", property);
- _validate_high_end("depth", property);
+ _validate_high_end("heightmap", property);
if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) {
property.usage = 0;
@@ -1479,48 +1589,67 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- if (property.name == "params_alpha_scissor_threshold" && !flags[FLAG_USE_ALPHA_SCISSOR]) {
+ if (property.name == "alpha_scissor_threshold" && transparency != TRANSPARENCY_ALPHA_SCISSOR) {
property.usage = 0;
}
- if ((property.name == "depth_min_layers" || property.name == "depth_max_layers") && !deep_parallax) {
+ if ((property.name == "heightmap_min_layers" || property.name == "heightmap_max_layers") && !deep_parallax) {
property.usage = 0;
}
- if (flags[FLAG_UNSHADED]) {
- if (property.name.begins_with("anisotropy")) {
- property.usage = 0;
- }
+ if (orm) {
- if (property.name.begins_with("ao")) {
- property.usage = 0;
+ if (property.name == "shading_mode") {
+ property.hint_string = "Unshaded,PerPixel"; //vertex not supported in ORM mode, since no individual roughness.
}
-
- if (property.name.begins_with("clearcoat")) {
+ if (property.name.begins_with("roughness") || property.name.begins_with("metallic") || property.name.begins_with("ao_texture")) {
property.usage = 0;
}
- if (property.name.begins_with("emission")) {
+ } else {
+ if (property.name == "orm_texture") {
property.usage = 0;
}
+ }
- if (property.name.begins_with("metallic")) {
- property.usage = 0;
- }
+ if (shading_mode != SHADING_MODE_PER_PIXEL) {
- if (property.name.begins_with("normal")) {
- property.usage = 0;
+ if (shading_mode != SHADING_MODE_PER_VERTEX) {
+
+ //these may still work per vertex
+ if (property.name.begins_with("ao")) {
+ property.usage = 0;
+ }
+ if (property.name.begins_with("emission")) {
+ property.usage = 0;
+ }
+
+ if (property.name.begins_with("metallic")) {
+ property.usage = 0;
+ }
+ if (property.name.begins_with("rim")) {
+ property.usage = 0;
+ }
+
+ if (property.name.begins_with("roughness")) {
+ property.usage = 0;
+ }
+
+ if (property.name.begins_with("subsurf_scatter")) {
+ property.usage = 0;
+ }
}
- if (property.name.begins_with("rim")) {
+ //these definitely only need per pixel
+ if (property.name.begins_with("anisotropy")) {
property.usage = 0;
}
- if (property.name.begins_with("roughness")) {
+ if (property.name.begins_with("clearcoat")) {
property.usage = 0;
}
- if (property.name.begins_with("subsurf_scatter")) {
+ if (property.name.begins_with("normal")) {
property.usage = 0;
}
@@ -1530,222 +1659,211 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
}
}
-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 SpatialMaterial::get_line_width() const {
-
- return line_width;
-}
-
-void SpatialMaterial::set_point_size(float p_point_size) {
+void BaseMaterial3D::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 SpatialMaterial::get_point_size() const {
+float BaseMaterial3D::get_point_size() const {
return point_size;
}
-void SpatialMaterial::set_uv1_scale(const Vector3 &p_scale) {
+void BaseMaterial3D::set_uv1_scale(const Vector3 &p_scale) {
uv1_scale = p_scale;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale);
}
-Vector3 SpatialMaterial::get_uv1_scale() const {
+Vector3 BaseMaterial3D::get_uv1_scale() const {
return uv1_scale;
}
-void SpatialMaterial::set_uv1_offset(const Vector3 &p_offset) {
+void BaseMaterial3D::set_uv1_offset(const Vector3 &p_offset) {
uv1_offset = p_offset;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset);
}
-Vector3 SpatialMaterial::get_uv1_offset() const {
+Vector3 BaseMaterial3D::get_uv1_offset() const {
return uv1_offset;
}
-void SpatialMaterial::set_uv1_triplanar_blend_sharpness(float p_sharpness) {
+void BaseMaterial3D::set_uv1_triplanar_blend_sharpness(float p_sharpness) {
uv1_triplanar_sharpness = p_sharpness;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, p_sharpness);
}
-float SpatialMaterial::get_uv1_triplanar_blend_sharpness() const {
+float BaseMaterial3D::get_uv1_triplanar_blend_sharpness() const {
return uv1_triplanar_sharpness;
}
-void SpatialMaterial::set_uv2_scale(const Vector3 &p_scale) {
+void BaseMaterial3D::set_uv2_scale(const Vector3 &p_scale) {
uv2_scale = p_scale;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale);
}
-Vector3 SpatialMaterial::get_uv2_scale() const {
+Vector3 BaseMaterial3D::get_uv2_scale() const {
return uv2_scale;
}
-void SpatialMaterial::set_uv2_offset(const Vector3 &p_offset) {
+void BaseMaterial3D::set_uv2_offset(const Vector3 &p_offset) {
uv2_offset = p_offset;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset);
}
-Vector3 SpatialMaterial::get_uv2_offset() const {
+Vector3 BaseMaterial3D::get_uv2_offset() const {
return uv2_offset;
}
-void SpatialMaterial::set_uv2_triplanar_blend_sharpness(float p_sharpness) {
+void BaseMaterial3D::set_uv2_triplanar_blend_sharpness(float p_sharpness) {
uv2_triplanar_sharpness = p_sharpness;
VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, p_sharpness);
}
-float SpatialMaterial::get_uv2_triplanar_blend_sharpness() const {
+float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const {
return uv2_triplanar_sharpness;
}
-void SpatialMaterial::set_billboard_mode(BillboardMode p_mode) {
+void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) {
billboard_mode = p_mode;
_queue_shader_change();
_change_notify();
}
-SpatialMaterial::BillboardMode SpatialMaterial::get_billboard_mode() const {
+BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const {
return billboard_mode;
}
-void SpatialMaterial::set_particles_anim_h_frames(int p_frames) {
+void BaseMaterial3D::set_particles_anim_h_frames(int p_frames) {
particles_anim_h_frames = p_frames;
VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames);
}
-int SpatialMaterial::get_particles_anim_h_frames() const {
+int BaseMaterial3D::get_particles_anim_h_frames() const {
return particles_anim_h_frames;
}
-void SpatialMaterial::set_particles_anim_v_frames(int p_frames) {
+void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) {
particles_anim_v_frames = p_frames;
VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames);
}
-int SpatialMaterial::get_particles_anim_v_frames() const {
+int BaseMaterial3D::get_particles_anim_v_frames() const {
return particles_anim_v_frames;
}
-void SpatialMaterial::set_particles_anim_loop(bool p_loop) {
+void BaseMaterial3D::set_particles_anim_loop(bool p_loop) {
particles_anim_loop = p_loop;
VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop);
}
-bool SpatialMaterial::get_particles_anim_loop() const {
+bool BaseMaterial3D::get_particles_anim_loop() const {
return particles_anim_loop;
}
-void SpatialMaterial::set_depth_deep_parallax(bool p_enable) {
+void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) {
deep_parallax = p_enable;
_queue_shader_change();
_change_notify();
}
-bool SpatialMaterial::is_depth_deep_parallax_enabled() const {
+bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const {
return deep_parallax;
}
-void SpatialMaterial::set_depth_deep_parallax_min_layers(int p_layer) {
+void BaseMaterial3D::set_heightmap_deep_parallax_min_layers(int p_layer) {
deep_parallax_min_layers = p_layer;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_min_layers, p_layer);
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_min_layers, p_layer);
}
-int SpatialMaterial::get_depth_deep_parallax_min_layers() const {
+int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const {
return deep_parallax_min_layers;
}
-void SpatialMaterial::set_depth_deep_parallax_max_layers(int p_layer) {
+void BaseMaterial3D::set_heightmap_deep_parallax_max_layers(int p_layer) {
deep_parallax_max_layers = p_layer;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_max_layers, p_layer);
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_max_layers, p_layer);
}
-int SpatialMaterial::get_depth_deep_parallax_max_layers() const {
+int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const {
return deep_parallax_max_layers;
}
-void SpatialMaterial::set_depth_deep_parallax_flip_tangent(bool p_flip) {
+void BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent(bool p_flip) {
- depth_parallax_flip_tangent = p_flip;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_flip, Vector2(depth_parallax_flip_tangent ? -1 : 1, depth_parallax_flip_binormal ? -1 : 1));
+ heightmap_parallax_flip_tangent = p_flip;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
-bool SpatialMaterial::get_depth_deep_parallax_flip_tangent() const {
+bool BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent() const {
- return depth_parallax_flip_tangent;
+ return heightmap_parallax_flip_tangent;
}
-void SpatialMaterial::set_depth_deep_parallax_flip_binormal(bool p_flip) {
+void BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal(bool p_flip) {
- depth_parallax_flip_binormal = p_flip;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_flip, Vector2(depth_parallax_flip_tangent ? -1 : 1, depth_parallax_flip_binormal ? -1 : 1));
+ heightmap_parallax_flip_binormal = p_flip;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
-bool SpatialMaterial::get_depth_deep_parallax_flip_binormal() const {
+bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const {
- return depth_parallax_flip_binormal;
+ return heightmap_parallax_flip_binormal;
}
-void SpatialMaterial::set_grow_enabled(bool p_enable) {
+void BaseMaterial3D::set_grow_enabled(bool p_enable) {
grow_enabled = p_enable;
_queue_shader_change();
_change_notify();
}
-bool SpatialMaterial::is_grow_enabled() const {
+bool BaseMaterial3D::is_grow_enabled() const {
return grow_enabled;
}
-void SpatialMaterial::set_alpha_scissor_threshold(float p_threshold) {
+void BaseMaterial3D::set_alpha_scissor_threshold(float p_threshold) {
alpha_scissor_threshold = p_threshold;
VS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_threshold);
}
-float SpatialMaterial::get_alpha_scissor_threshold() const {
+float BaseMaterial3D::get_alpha_scissor_threshold() const {
return alpha_scissor_threshold;
}
-void SpatialMaterial::set_grow(float p_grow) {
+void BaseMaterial3D::set_grow(float p_grow) {
grow = p_grow;
VS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow);
}
-float SpatialMaterial::get_grow() const {
+float BaseMaterial3D::get_grow() const {
return grow;
}
-static Plane _get_texture_mask(SpatialMaterial::TextureChannel p_channel) {
+static Plane _get_texture_mask(BaseMaterial3D::TextureChannel p_channel) {
static const Plane masks[5] = {
Plane(1, 0, 0, 0),
Plane(0, 1, 0, 0),
@@ -1757,50 +1875,50 @@ static Plane _get_texture_mask(SpatialMaterial::TextureChannel p_channel) {
return masks[p_channel];
}
-void SpatialMaterial::set_metallic_texture_channel(TextureChannel p_channel) {
+void BaseMaterial3D::set_metallic_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
metallic_texture_channel = p_channel;
VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic_texture_channel, _get_texture_mask(p_channel));
}
-SpatialMaterial::TextureChannel SpatialMaterial::get_metallic_texture_channel() const {
+BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() const {
return metallic_texture_channel;
}
-void SpatialMaterial::set_roughness_texture_channel(TextureChannel p_channel) {
+void BaseMaterial3D::set_roughness_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
roughness_texture_channel = p_channel;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->roughness_texture_channel, _get_texture_mask(p_channel));
+ _queue_shader_change();
}
-SpatialMaterial::TextureChannel SpatialMaterial::get_roughness_texture_channel() const {
+BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() const {
return roughness_texture_channel;
}
-void SpatialMaterial::set_ao_texture_channel(TextureChannel p_channel) {
+void BaseMaterial3D::set_ao_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
ao_texture_channel = p_channel;
VS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel));
}
-SpatialMaterial::TextureChannel SpatialMaterial::get_ao_texture_channel() const {
+BaseMaterial3D::TextureChannel BaseMaterial3D::get_ao_texture_channel() const {
return ao_texture_channel;
}
-void SpatialMaterial::set_refraction_texture_channel(TextureChannel p_channel) {
+void BaseMaterial3D::set_refraction_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
refraction_texture_channel = p_channel;
VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel));
}
-SpatialMaterial::TextureChannel SpatialMaterial::get_refraction_texture_channel() const {
+BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel() const {
return refraction_texture_channel;
}
-RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) {
+RID BaseMaterial3D::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) {
int version = 0;
if (p_shaded)
@@ -1822,16 +1940,14 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent,
return materials_for_2d[version]->get_rid();
}
- Ref<SpatialMaterial> material;
+ Ref<StandardMaterial3D> material;
material.instance();
- material->set_flag(FLAG_UNSHADED, !p_shaded);
- material->set_feature(FEATURE_TRANSPARENT, p_transparent);
+ material->set_shading_mode(p_shaded ? SHADING_MODE_PER_PIXEL : SHADING_MODE_UNSHADED);
+ material->set_transparency(p_transparent ? (p_opaque_prepass ? TRANSPARENCY_ALPHA_DEPTH_PRE_PASS : (p_cut_alpha ? TRANSPARENCY_ALPHA_SCISSOR : TRANSPARENCY_ALPHA)) : TRANSPARENCY_DISABLED);
material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK);
- material->set_depth_draw_mode(p_opaque_prepass ? DEPTH_DRAW_ALPHA_OPAQUE_PREPASS : DEPTH_DRAW_OPAQUE_ONLY);
material->set_flag(FLAG_SRGB_VERTEX_COLOR, true);
material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- material->set_flag(FLAG_USE_ALPHA_SCISSOR, p_cut_alpha);
if (p_billboard || p_billboard_y) {
material->set_flag(FLAG_BILLBOARD_KEEP_SCALE, true);
material->set_billboard_mode(p_billboard_y ? BILLBOARD_FIXED_Y : BILLBOARD_ENABLED);
@@ -1842,67 +1958,67 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent,
return materials_for_2d[version]->get_rid();
}
-void SpatialMaterial::set_on_top_of_alpha() {
- set_feature(FEATURE_TRANSPARENT, true);
+void BaseMaterial3D::set_on_top_of_alpha() {
+ set_transparency(TRANSPARENCY_DISABLED);
set_render_priority(RENDER_PRIORITY_MAX);
set_flag(FLAG_DISABLE_DEPTH_TEST, true);
}
-void SpatialMaterial::set_proximity_fade(bool p_enable) {
+void BaseMaterial3D::set_proximity_fade(bool p_enable) {
proximity_fade_enabled = p_enable;
_queue_shader_change();
_change_notify();
}
-bool SpatialMaterial::is_proximity_fade_enabled() const {
+bool BaseMaterial3D::is_proximity_fade_enabled() const {
return proximity_fade_enabled;
}
-void SpatialMaterial::set_proximity_fade_distance(float p_distance) {
+void BaseMaterial3D::set_proximity_fade_distance(float p_distance) {
proximity_fade_distance = p_distance;
VS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, p_distance);
}
-float SpatialMaterial::get_proximity_fade_distance() const {
+float BaseMaterial3D::get_proximity_fade_distance() const {
return proximity_fade_distance;
}
-void SpatialMaterial::set_distance_fade(DistanceFadeMode p_mode) {
+void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) {
distance_fade = p_mode;
_queue_shader_change();
_change_notify();
}
-SpatialMaterial::DistanceFadeMode SpatialMaterial::get_distance_fade() const {
+BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const {
return distance_fade;
}
-void SpatialMaterial::set_distance_fade_max_distance(float p_distance) {
+void BaseMaterial3D::set_distance_fade_max_distance(float p_distance) {
distance_fade_max_distance = p_distance;
VS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance);
}
-float SpatialMaterial::get_distance_fade_max_distance() const {
+float BaseMaterial3D::get_distance_fade_max_distance() const {
return distance_fade_max_distance;
}
-void SpatialMaterial::set_distance_fade_min_distance(float p_distance) {
+void BaseMaterial3D::set_distance_fade_min_distance(float p_distance) {
distance_fade_min_distance = p_distance;
VS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance);
}
-float SpatialMaterial::get_distance_fade_min_distance() const {
+float BaseMaterial3D::get_distance_fade_min_distance() const {
return distance_fade_min_distance;
}
-void SpatialMaterial::set_emission_operator(EmissionOperator p_op) {
+void BaseMaterial3D::set_emission_operator(EmissionOperator p_op) {
if (emission_op == p_op)
return;
@@ -1910,244 +2026,236 @@ void SpatialMaterial::set_emission_operator(EmissionOperator p_op) {
_queue_shader_change();
}
-SpatialMaterial::EmissionOperator SpatialMaterial::get_emission_operator() const {
+BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
return emission_op;
}
-RID SpatialMaterial::get_shader_rid() const {
+RID BaseMaterial3D::get_shader_rid() const {
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
return shader_map[current_key].shader;
}
-Shader::Mode SpatialMaterial::get_shader_mode() const {
+Shader::Mode BaseMaterial3D::get_shader_mode() const {
return Shader::MODE_SPATIAL;
}
-void SpatialMaterial::_bind_methods() {
+void BaseMaterial3D::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &BaseMaterial3D::set_albedo);
+ ClassDB::bind_method(D_METHOD("get_albedo"), &BaseMaterial3D::get_albedo);
+
+ ClassDB::bind_method(D_METHOD("set_transparency", "transparency"), &BaseMaterial3D::set_transparency);
+ ClassDB::bind_method(D_METHOD("get_transparency"), &BaseMaterial3D::get_transparency);
- 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_shading_mode", "shading_mode"), &BaseMaterial3D::set_shading_mode);
+ ClassDB::bind_method(D_METHOD("get_shading_mode"), &BaseMaterial3D::get_shading_mode);
- 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_specular", "specular"), &BaseMaterial3D::set_specular);
+ ClassDB::bind_method(D_METHOD("get_specular"), &BaseMaterial3D::get_specular);
- ClassDB::bind_method(D_METHOD("set_metallic", "metallic"), &SpatialMaterial::set_metallic);
- ClassDB::bind_method(D_METHOD("get_metallic"), &SpatialMaterial::get_metallic);
+ ClassDB::bind_method(D_METHOD("set_metallic", "metallic"), &BaseMaterial3D::set_metallic);
+ ClassDB::bind_method(D_METHOD("get_metallic"), &BaseMaterial3D::get_metallic);
- 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_roughness", "roughness"), &BaseMaterial3D::set_roughness);
+ ClassDB::bind_method(D_METHOD("get_roughness"), &BaseMaterial3D::get_roughness);
- 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_emission", "emission"), &BaseMaterial3D::set_emission);
+ ClassDB::bind_method(D_METHOD("get_emission"), &BaseMaterial3D::get_emission);
- 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_emission_energy", "emission_energy"), &BaseMaterial3D::set_emission_energy);
+ ClassDB::bind_method(D_METHOD("get_emission_energy"), &BaseMaterial3D::get_emission_energy);
- 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_normal_scale", "normal_scale"), &BaseMaterial3D::set_normal_scale);
+ ClassDB::bind_method(D_METHOD("get_normal_scale"), &BaseMaterial3D::get_normal_scale);
- 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_rim", "rim"), &BaseMaterial3D::set_rim);
+ ClassDB::bind_method(D_METHOD("get_rim"), &BaseMaterial3D::get_rim);
- 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_rim_tint", "rim_tint"), &BaseMaterial3D::set_rim_tint);
+ ClassDB::bind_method(D_METHOD("get_rim_tint"), &BaseMaterial3D::get_rim_tint);
- 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_clearcoat", "clearcoat"), &BaseMaterial3D::set_clearcoat);
+ ClassDB::bind_method(D_METHOD("get_clearcoat"), &BaseMaterial3D::get_clearcoat);
- 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_clearcoat_gloss", "clearcoat_gloss"), &BaseMaterial3D::set_clearcoat_gloss);
+ ClassDB::bind_method(D_METHOD("get_clearcoat_gloss"), &BaseMaterial3D::get_clearcoat_gloss);
- 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_anisotropy", "anisotropy"), &BaseMaterial3D::set_anisotropy);
+ ClassDB::bind_method(D_METHOD("get_anisotropy"), &BaseMaterial3D::get_anisotropy);
- ClassDB::bind_method(D_METHOD("set_depth_scale", "depth_scale"), &SpatialMaterial::set_depth_scale);
- ClassDB::bind_method(D_METHOD("get_depth_scale"), &SpatialMaterial::get_depth_scale);
+ ClassDB::bind_method(D_METHOD("set_heightmap_scale", "heightmap_scale"), &BaseMaterial3D::set_heightmap_scale);
+ ClassDB::bind_method(D_METHOD("get_heightmap_scale"), &BaseMaterial3D::get_heightmap_scale);
- 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_subsurface_scattering_strength", "strength"), &BaseMaterial3D::set_subsurface_scattering_strength);
+ ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &BaseMaterial3D::get_subsurface_scattering_strength);
- ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &SpatialMaterial::set_transmission);
- ClassDB::bind_method(D_METHOD("get_transmission"), &SpatialMaterial::get_transmission);
+ ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &BaseMaterial3D::set_transmission);
+ ClassDB::bind_method(D_METHOD("get_transmission"), &BaseMaterial3D::get_transmission);
- 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_refraction", "refraction"), &BaseMaterial3D::set_refraction);
+ ClassDB::bind_method(D_METHOD("get_refraction"), &BaseMaterial3D::get_refraction);
- 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_point_size", "point_size"), &BaseMaterial3D::set_point_size);
+ ClassDB::bind_method(D_METHOD("get_point_size"), &BaseMaterial3D::get_point_size);
- 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_detail_uv", "detail_uv"), &BaseMaterial3D::set_detail_uv);
+ ClassDB::bind_method(D_METHOD("get_detail_uv"), &BaseMaterial3D::get_detail_uv);
- 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_blend_mode", "blend_mode"), &BaseMaterial3D::set_blend_mode);
+ ClassDB::bind_method(D_METHOD("get_blend_mode"), &BaseMaterial3D::get_blend_mode);
- 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_depth_draw_mode", "depth_draw_mode"), &BaseMaterial3D::set_depth_draw_mode);
+ ClassDB::bind_method(D_METHOD("get_depth_draw_mode"), &BaseMaterial3D::get_depth_draw_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_cull_mode", "cull_mode"), &BaseMaterial3D::set_cull_mode);
+ ClassDB::bind_method(D_METHOD("get_cull_mode"), &BaseMaterial3D::get_cull_mode);
- 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_diffuse_mode", "diffuse_mode"), &BaseMaterial3D::set_diffuse_mode);
+ ClassDB::bind_method(D_METHOD("get_diffuse_mode"), &BaseMaterial3D::get_diffuse_mode);
- 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_specular_mode", "specular_mode"), &BaseMaterial3D::set_specular_mode);
+ ClassDB::bind_method(D_METHOD("get_specular_mode"), &BaseMaterial3D::get_specular_mode);
- 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_flag", "flag", "enable"), &BaseMaterial3D::set_flag);
+ ClassDB::bind_method(D_METHOD("get_flag", "flag"), &BaseMaterial3D::get_flag);
- ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &SpatialMaterial::set_flag);
- ClassDB::bind_method(D_METHOD("get_flag", "flag"), &SpatialMaterial::get_flag);
+ ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &BaseMaterial3D::set_texture_filter);
+ ClassDB::bind_method(D_METHOD("get_texture_filter"), &BaseMaterial3D::get_texture_filter);
- 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_feature", "feature", "enable"), &BaseMaterial3D::set_feature);
+ ClassDB::bind_method(D_METHOD("get_feature", "feature"), &BaseMaterial3D::get_feature);
- ClassDB::bind_method(D_METHOD("set_texture", "param", "texture"), &SpatialMaterial::set_texture);
- ClassDB::bind_method(D_METHOD("get_texture", "param"), &SpatialMaterial::get_texture);
+ ClassDB::bind_method(D_METHOD("set_texture", "param", "texture"), &BaseMaterial3D::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture", "param"), &BaseMaterial3D::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_detail_blend_mode", "detail_blend_mode"), &BaseMaterial3D::set_detail_blend_mode);
+ ClassDB::bind_method(D_METHOD("get_detail_blend_mode"), &BaseMaterial3D::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_scale", "scale"), &BaseMaterial3D::set_uv1_scale);
+ ClassDB::bind_method(D_METHOD("get_uv1_scale"), &BaseMaterial3D::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_uv1_offset", "offset"), &BaseMaterial3D::set_uv1_offset);
+ ClassDB::bind_method(D_METHOD("get_uv1_offset"), &BaseMaterial3D::get_uv1_offset);
- ClassDB::bind_method(D_METHOD("set_uv1_triplanar_blend_sharpness", "sharpness"), &SpatialMaterial::set_uv1_triplanar_blend_sharpness);
- ClassDB::bind_method(D_METHOD("get_uv1_triplanar_blend_sharpness"), &SpatialMaterial::get_uv1_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("set_uv1_triplanar_blend_sharpness", "sharpness"), &BaseMaterial3D::set_uv1_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("get_uv1_triplanar_blend_sharpness"), &BaseMaterial3D::get_uv1_triplanar_blend_sharpness);
- 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_scale", "scale"), &BaseMaterial3D::set_uv2_scale);
+ ClassDB::bind_method(D_METHOD("get_uv2_scale"), &BaseMaterial3D::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_uv2_offset", "offset"), &BaseMaterial3D::set_uv2_offset);
+ ClassDB::bind_method(D_METHOD("get_uv2_offset"), &BaseMaterial3D::get_uv2_offset);
- ClassDB::bind_method(D_METHOD("set_uv2_triplanar_blend_sharpness", "sharpness"), &SpatialMaterial::set_uv2_triplanar_blend_sharpness);
- ClassDB::bind_method(D_METHOD("get_uv2_triplanar_blend_sharpness"), &SpatialMaterial::get_uv2_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("set_uv2_triplanar_blend_sharpness", "sharpness"), &BaseMaterial3D::set_uv2_triplanar_blend_sharpness);
+ ClassDB::bind_method(D_METHOD("get_uv2_triplanar_blend_sharpness"), &BaseMaterial3D::get_uv2_triplanar_blend_sharpness);
- 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_billboard_mode", "mode"), &BaseMaterial3D::set_billboard_mode);
+ ClassDB::bind_method(D_METHOD("get_billboard_mode"), &BaseMaterial3D::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_h_frames", "frames"), &BaseMaterial3D::set_particles_anim_h_frames);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &BaseMaterial3D::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_v_frames", "frames"), &BaseMaterial3D::set_particles_anim_v_frames);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &BaseMaterial3D::get_particles_anim_v_frames);
- ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &SpatialMaterial::set_particles_anim_loop);
- ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &SpatialMaterial::get_particles_anim_loop);
+ ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &BaseMaterial3D::set_particles_anim_loop);
+ ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &BaseMaterial3D::get_particles_anim_loop);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax", "enable"), &SpatialMaterial::set_depth_deep_parallax);
- ClassDB::bind_method(D_METHOD("is_depth_deep_parallax_enabled"), &SpatialMaterial::is_depth_deep_parallax_enabled);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax", "enable"), &BaseMaterial3D::set_heightmap_deep_parallax);
+ ClassDB::bind_method(D_METHOD("is_heightmap_deep_parallax_enabled"), &BaseMaterial3D::is_heightmap_deep_parallax_enabled);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_min_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_min_layers);
- ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_min_layers"), &SpatialMaterial::get_depth_deep_parallax_min_layers);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_min_layers", "layer"), &BaseMaterial3D::set_heightmap_deep_parallax_min_layers);
+ ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_min_layers"), &BaseMaterial3D::get_heightmap_deep_parallax_min_layers);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_max_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_max_layers);
- ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_max_layers"), &SpatialMaterial::get_depth_deep_parallax_max_layers);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_max_layers", "layer"), &BaseMaterial3D::set_heightmap_deep_parallax_max_layers);
+ ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_max_layers"), &BaseMaterial3D::get_heightmap_deep_parallax_max_layers);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_flip_tangent", "flip"), &SpatialMaterial::set_depth_deep_parallax_flip_tangent);
- ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_flip_tangent"), &SpatialMaterial::get_depth_deep_parallax_flip_tangent);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_flip_tangent", "flip"), &BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent);
+ ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_flip_tangent"), &BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent);
- ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_flip_binormal", "flip"), &SpatialMaterial::set_depth_deep_parallax_flip_binormal);
- ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_flip_binormal"), &SpatialMaterial::get_depth_deep_parallax_flip_binormal);
+ ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_flip_binormal", "flip"), &BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal);
+ ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_flip_binormal"), &BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal);
- ClassDB::bind_method(D_METHOD("set_grow", "amount"), &SpatialMaterial::set_grow);
- ClassDB::bind_method(D_METHOD("get_grow"), &SpatialMaterial::get_grow);
+ ClassDB::bind_method(D_METHOD("set_grow", "amount"), &BaseMaterial3D::set_grow);
+ ClassDB::bind_method(D_METHOD("get_grow"), &BaseMaterial3D::get_grow);
- ClassDB::bind_method(D_METHOD("set_emission_operator", "operator"), &SpatialMaterial::set_emission_operator);
- ClassDB::bind_method(D_METHOD("get_emission_operator"), &SpatialMaterial::get_emission_operator);
+ ClassDB::bind_method(D_METHOD("set_emission_operator", "operator"), &BaseMaterial3D::set_emission_operator);
+ ClassDB::bind_method(D_METHOD("get_emission_operator"), &BaseMaterial3D::get_emission_operator);
- ClassDB::bind_method(D_METHOD("set_ao_light_affect", "amount"), &SpatialMaterial::set_ao_light_affect);
- ClassDB::bind_method(D_METHOD("get_ao_light_affect"), &SpatialMaterial::get_ao_light_affect);
+ ClassDB::bind_method(D_METHOD("set_ao_light_affect", "amount"), &BaseMaterial3D::set_ao_light_affect);
+ ClassDB::bind_method(D_METHOD("get_ao_light_affect"), &BaseMaterial3D::get_ao_light_affect);
- ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &SpatialMaterial::set_alpha_scissor_threshold);
- ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &SpatialMaterial::get_alpha_scissor_threshold);
+ ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &BaseMaterial3D::set_alpha_scissor_threshold);
+ ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &BaseMaterial3D::get_alpha_scissor_threshold);
- ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &SpatialMaterial::set_grow_enabled);
- ClassDB::bind_method(D_METHOD("is_grow_enabled"), &SpatialMaterial::is_grow_enabled);
+ ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &BaseMaterial3D::set_grow_enabled);
+ ClassDB::bind_method(D_METHOD("is_grow_enabled"), &BaseMaterial3D::is_grow_enabled);
- ClassDB::bind_method(D_METHOD("set_metallic_texture_channel", "channel"), &SpatialMaterial::set_metallic_texture_channel);
- ClassDB::bind_method(D_METHOD("get_metallic_texture_channel"), &SpatialMaterial::get_metallic_texture_channel);
+ ClassDB::bind_method(D_METHOD("set_metallic_texture_channel", "channel"), &BaseMaterial3D::set_metallic_texture_channel);
+ ClassDB::bind_method(D_METHOD("get_metallic_texture_channel"), &BaseMaterial3D::get_metallic_texture_channel);
- ClassDB::bind_method(D_METHOD("set_roughness_texture_channel", "channel"), &SpatialMaterial::set_roughness_texture_channel);
- ClassDB::bind_method(D_METHOD("get_roughness_texture_channel"), &SpatialMaterial::get_roughness_texture_channel);
+ ClassDB::bind_method(D_METHOD("set_roughness_texture_channel", "channel"), &BaseMaterial3D::set_roughness_texture_channel);
+ ClassDB::bind_method(D_METHOD("get_roughness_texture_channel"), &BaseMaterial3D::get_roughness_texture_channel);
- ClassDB::bind_method(D_METHOD("set_ao_texture_channel", "channel"), &SpatialMaterial::set_ao_texture_channel);
- ClassDB::bind_method(D_METHOD("get_ao_texture_channel"), &SpatialMaterial::get_ao_texture_channel);
+ ClassDB::bind_method(D_METHOD("set_ao_texture_channel", "channel"), &BaseMaterial3D::set_ao_texture_channel);
+ ClassDB::bind_method(D_METHOD("get_ao_texture_channel"), &BaseMaterial3D::get_ao_texture_channel);
- ClassDB::bind_method(D_METHOD("set_refraction_texture_channel", "channel"), &SpatialMaterial::set_refraction_texture_channel);
- ClassDB::bind_method(D_METHOD("get_refraction_texture_channel"), &SpatialMaterial::get_refraction_texture_channel);
+ ClassDB::bind_method(D_METHOD("set_refraction_texture_channel", "channel"), &BaseMaterial3D::set_refraction_texture_channel);
+ ClassDB::bind_method(D_METHOD("get_refraction_texture_channel"), &BaseMaterial3D::get_refraction_texture_channel);
- ClassDB::bind_method(D_METHOD("set_proximity_fade", "enabled"), &SpatialMaterial::set_proximity_fade);
- ClassDB::bind_method(D_METHOD("is_proximity_fade_enabled"), &SpatialMaterial::is_proximity_fade_enabled);
+ ClassDB::bind_method(D_METHOD("set_proximity_fade", "enabled"), &BaseMaterial3D::set_proximity_fade);
+ ClassDB::bind_method(D_METHOD("is_proximity_fade_enabled"), &BaseMaterial3D::is_proximity_fade_enabled);
- ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &SpatialMaterial::set_proximity_fade_distance);
- ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &SpatialMaterial::get_proximity_fade_distance);
+ ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &BaseMaterial3D::set_proximity_fade_distance);
+ ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &BaseMaterial3D::get_proximity_fade_distance);
- ClassDB::bind_method(D_METHOD("set_distance_fade", "mode"), &SpatialMaterial::set_distance_fade);
- ClassDB::bind_method(D_METHOD("get_distance_fade"), &SpatialMaterial::get_distance_fade);
+ ClassDB::bind_method(D_METHOD("set_distance_fade", "mode"), &BaseMaterial3D::set_distance_fade);
+ ClassDB::bind_method(D_METHOD("get_distance_fade"), &BaseMaterial3D::get_distance_fade);
- ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance", "distance"), &SpatialMaterial::set_distance_fade_max_distance);
- ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance"), &SpatialMaterial::get_distance_fade_max_distance);
+ ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance", "distance"), &BaseMaterial3D::set_distance_fade_max_distance);
+ ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance"), &BaseMaterial3D::get_distance_fade_max_distance);
- ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &SpatialMaterial::set_distance_fade_min_distance);
- ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &SpatialMaterial::get_distance_fade_min_distance);
+ ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &BaseMaterial3D::set_distance_fade_min_distance);
+ ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance);
+
+ ADD_GROUP("Transparency", "");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,AlphaScissor,DepthPrePass"), "set_transparency", "get_transparency");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never"), "set_depth_draw_mode", "get_depth_draw_mode");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST);
+
+ ADD_GROUP("Shading", "");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,PerPixel,PerVertex"), "set_shading_mode", "get_shading_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT);
- ADD_GROUP("Flags", "flags_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_shadow_to_opacity"), "set_flag", "get_flag", FLAG_USE_SHADOW_TO_OPACITY);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_vertex_lighting"), "set_flag", "get_flag", FLAG_USE_VERTEX_LIGHTING);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_world_triplanar"), "set_flag", "get_flag", FLAG_TRIPLANAR_USE_WORLD);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_do_not_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_ensure_correct_normals"), "set_flag", "get_flag", FLAG_ENSURE_CORRECT_NORMALS);
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, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "params_specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_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_PROPERTYI(PropertyInfo(Variant::BOOL, "params_billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "params_grow"), "set_grow_enabled", "is_grow_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_grow_amount", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_grow", "get_grow");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_use_alpha_scissor"), "set_flag", "get_flag", FLAG_USE_ALPHA_SCISSOR);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
- 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");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ALBEDO);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
+
+ ADD_GROUP("ORM", "orm_");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orm_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ORM);
ADD_GROUP("Metallic", "metallic_");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_METALLIC);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_METALLIC);
ADD_PROPERTY(PropertyInfo(Variant::INT, "metallic_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_metallic_texture_channel", "get_metallic_texture_channel");
ADD_GROUP("Roughness", "roughness_");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ROUGHNESS);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ROUGHNESS);
ADD_PROPERTY(PropertyInfo(Variant::INT, "roughness_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_roughness_texture_channel", "get_roughness_texture_channel");
ADD_GROUP("Emission", "emission_");
@@ -2156,83 +2264,110 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_emission_energy", "get_emission_energy");
ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_operator", PROPERTY_HINT_ENUM, "Add,Multiply"), "set_emission_operator", "get_emission_operator");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_on_uv2"), "set_flag", "get_flag", FLAG_EMISSION_ON_UV2);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_EMISSION);
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);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_NORMAL);
ADD_GROUP("Rim", "rim_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "rim_enabled"), "set_feature", "get_feature", FEATURE_RIM);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "rim", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim", "get_rim");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "rim_tint", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim_tint", "get_rim_tint");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "rim_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_RIM);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "rim_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_RIM);
ADD_GROUP("Clearcoat", "clearcoat_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "clearcoat_enabled"), "set_feature", "get_feature", FEATURE_CLEARCOAT);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "clearcoat", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat", "get_clearcoat");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "clearcoat_gloss", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat_gloss", "get_clearcoat_gloss");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "clearcoat_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_CLEARCOAT);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "clearcoat_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_CLEARCOAT);
ADD_GROUP("Anisotropy", "anisotropy_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "anisotropy_enabled"), "set_feature", "get_feature", FEATURE_ANISOTROPY);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "anisotropy", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_anisotropy", "get_anisotropy");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anisotropy_flowmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_FLOWMAP);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anisotropy_flowmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_FLOWMAP);
ADD_GROUP("Ambient Occlusion", "ao_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_enabled"), "set_feature", "get_feature", FEATURE_AMBIENT_OCCLUSION);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ao_light_affect", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao_light_affect", "get_ao_light_affect");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_on_uv2"), "set_flag", "get_flag", FLAG_AO_ON_UV2);
ADD_PROPERTY(PropertyInfo(Variant::INT, "ao_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_ao_texture_channel", "get_ao_texture_channel");
- ADD_GROUP("Depth", "depth_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "depth_enabled"), "set_feature", "get_feature", FEATURE_DEPTH_MAPPING);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_depth_scale", "get_depth_scale");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_deep_parallax"), "set_depth_deep_parallax", "is_depth_deep_parallax_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_min_layers", "get_depth_deep_parallax_min_layers");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_max_layers", "get_depth_deep_parallax_max_layers");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_flip_tangent"), "set_depth_deep_parallax_flip_tangent", "get_depth_deep_parallax_flip_tangent");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_flip_binormal"), "set_depth_deep_parallax_flip_binormal", "get_depth_deep_parallax_flip_binormal");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "depth_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DEPTH);
+ ADD_GROUP("Height", "heightmap_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_enabled"), "set_feature", "get_feature", FEATURE_HEIGHT_MAPPING);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_heightmap_scale", "get_heightmap_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_deep_parallax"), "set_heightmap_deep_parallax", "is_heightmap_deep_parallax_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_tangent"), "set_heightmap_deep_parallax_flip_tangent", "get_heightmap_deep_parallax_flip_tangent");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_binormal"), "set_heightmap_deep_parallax_flip_binormal", "get_heightmap_deep_parallax_flip_binormal");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "heightmap_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_HEIGHTMAP);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_flip_texture"), "set_flag", "get_flag", FLAG_INVERT_HEIGHTMAP);
ADD_GROUP("Subsurf Scatter", "subsurf_scatter_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURACE_SCATTERING);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING);
ADD_GROUP("Transmission", "transmission_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transmission_enabled"), "set_feature", "get_feature", FEATURE_TRANSMISSION);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "transmission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_transmission", "get_transmission");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_TRANSMISSION);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_TRANSMISSION);
ADD_GROUP("Refraction", "refraction_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_REFRACTION);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_REFRACTION);
ADD_PROPERTY(PropertyInfo(Variant::INT, "refraction_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_refraction_texture_channel", "get_refraction_texture_channel");
ADD_GROUP("Detail", "detail_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "detail_enabled"), "set_feature", "get_feature", FEATURE_DETAIL);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_MASK);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_MASK);
ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_detail_blend_mode", "get_detail_blend_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_uv_layer", PROPERTY_HINT_ENUM, "UV1,UV2"), "set_detail_uv", "get_detail_uv");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_ALBEDO);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_ALBEDO);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL);
ADD_GROUP("UV1", "uv1_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_scale"), "set_uv1_scale", "get_uv1_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_offset"), "set_uv1_offset", "get_uv1_offset");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_triplanar"), "set_flag", "get_flag", FLAG_UV1_USE_TRIPLANAR);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv1_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv1_triplanar_blend_sharpness", "get_uv1_triplanar_blend_sharpness");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_world_triplanar"), "set_flag", "get_flag", FLAG_UV1_USE_WORLD_TRIPLANAR);
ADD_GROUP("UV2", "uv2_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_scale"), "set_uv2_scale", "get_uv2_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_offset"), "set_uv2_offset", "get_uv2_offset");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_TRIPLANAR);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv2_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_world_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_WORLD_TRIPLANAR);
+
+ ADD_GROUP("Sampling", "texture_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapNearest,MipmapLinear,MipmapNearestAniso,MipmapLinearAniso"), "set_texture_filter", "get_texture_filter");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "texture_repeat"), "set_flag", "get_flag", FLAG_USE_TEXTURE_REPEAT);
+ ADD_GROUP("Shadows", "");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "shadow_to_opacity"), "set_flag", "get_flag", FLAG_USE_SHADOW_TO_OPACITY);
+
+ ADD_GROUP("Billboard", "billboard_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE);
+
+ 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("Grow", "grow_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "grow"), "set_grow_enabled", "is_grow_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow_amount", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_grow", "get_grow");
+ ADD_GROUP("Transform", "");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_point_size", "get_point_size");
ADD_GROUP("Proximity Fade", "proximity_fade_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enable"), "set_proximity_fade", "is_proximity_fade_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_proximity_fade_distance", "get_proximity_fade_distance");
@@ -2250,26 +2385,45 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(TEXTURE_CLEARCOAT);
BIND_ENUM_CONSTANT(TEXTURE_FLOWMAP);
BIND_ENUM_CONSTANT(TEXTURE_AMBIENT_OCCLUSION);
- BIND_ENUM_CONSTANT(TEXTURE_DEPTH);
+ BIND_ENUM_CONSTANT(TEXTURE_HEIGHTMAP);
BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING);
BIND_ENUM_CONSTANT(TEXTURE_TRANSMISSION);
BIND_ENUM_CONSTANT(TEXTURE_REFRACTION);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_MASK);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_ALBEDO);
BIND_ENUM_CONSTANT(TEXTURE_DETAIL_NORMAL);
+ BIND_ENUM_CONSTANT(TEXTURE_ORM);
BIND_ENUM_CONSTANT(TEXTURE_MAX);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC);
+ BIND_ENUM_CONSTANT(TEXTURE_FILTER_MAX);
+
BIND_ENUM_CONSTANT(DETAIL_UV_1);
BIND_ENUM_CONSTANT(DETAIL_UV_2);
- BIND_ENUM_CONSTANT(FEATURE_TRANSPARENT);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_DISABLED);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_SCISSOR);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
+ BIND_ENUM_CONSTANT(TRANSPARENCY_MAX);
+
+ BIND_ENUM_CONSTANT(SHADING_MODE_UNSHADED);
+ BIND_ENUM_CONSTANT(SHADING_MODE_PER_PIXEL);
+ BIND_ENUM_CONSTANT(SHADING_MODE_PER_VERTEX);
+ BIND_ENUM_CONSTANT(SHADING_MODE_MAX);
+
BIND_ENUM_CONSTANT(FEATURE_EMISSION);
BIND_ENUM_CONSTANT(FEATURE_NORMAL_MAPPING);
BIND_ENUM_CONSTANT(FEATURE_RIM);
BIND_ENUM_CONSTANT(FEATURE_CLEARCOAT);
BIND_ENUM_CONSTANT(FEATURE_ANISOTROPY);
BIND_ENUM_CONSTANT(FEATURE_AMBIENT_OCCLUSION);
- BIND_ENUM_CONSTANT(FEATURE_DEPTH_MAPPING);
+ BIND_ENUM_CONSTANT(FEATURE_HEIGHT_MAPPING);
BIND_ENUM_CONSTANT(FEATURE_SUBSURACE_SCATTERING);
BIND_ENUM_CONSTANT(FEATURE_TRANSMISSION);
BIND_ENUM_CONSTANT(FEATURE_REFRACTION);
@@ -2284,14 +2438,11 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(DEPTH_DRAW_OPAQUE_ONLY);
BIND_ENUM_CONSTANT(DEPTH_DRAW_ALWAYS);
BIND_ENUM_CONSTANT(DEPTH_DRAW_DISABLED);
- BIND_ENUM_CONSTANT(DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
BIND_ENUM_CONSTANT(CULL_BACK);
BIND_ENUM_CONSTANT(CULL_FRONT);
BIND_ENUM_CONSTANT(CULL_DISABLED);
- BIND_ENUM_CONSTANT(FLAG_UNSHADED);
- BIND_ENUM_CONSTANT(FLAG_USE_VERTEX_LIGHTING);
BIND_ENUM_CONSTANT(FLAG_DISABLE_DEPTH_TEST);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_FROM_VERTEX_COLOR);
BIND_ENUM_CONSTANT(FLAG_SRGB_VERTEX_COLOR);
@@ -2300,15 +2451,16 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_BILLBOARD_KEEP_SCALE);
BIND_ENUM_CONSTANT(FLAG_UV1_USE_TRIPLANAR);
BIND_ENUM_CONSTANT(FLAG_UV2_USE_TRIPLANAR);
+ BIND_ENUM_CONSTANT(FLAG_UV1_USE_WORLD_TRIPLANAR);
+ BIND_ENUM_CONSTANT(FLAG_UV2_USE_WORLD_TRIPLANAR);
BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2);
BIND_ENUM_CONSTANT(FLAG_EMISSION_ON_UV2);
- BIND_ENUM_CONSTANT(FLAG_USE_ALPHA_SCISSOR);
- BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
BIND_ENUM_CONSTANT(FLAG_DONT_RECEIVE_SHADOWS);
BIND_ENUM_CONSTANT(FLAG_DISABLE_AMBIENT_LIGHT);
- BIND_ENUM_CONSTANT(FLAG_ENSURE_CORRECT_NORMALS);
BIND_ENUM_CONSTANT(FLAG_USE_SHADOW_TO_OPACITY);
+ BIND_ENUM_CONSTANT(FLAG_USE_TEXTURE_REPEAT);
+ BIND_ENUM_CONSTANT(FLAG_INVERT_HEIGHTMAP);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
@@ -2343,10 +2495,13 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(DISTANCE_FADE_OBJECT_DITHER);
}
-SpatialMaterial::SpatialMaterial() :
+BaseMaterial3D::BaseMaterial3D(bool p_orm) :
element(this) {
+ orm = p_orm;
// Initialize to the same values as the shader
+ transparency = TRANSPARENCY_DISABLED;
+ shading_mode = SHADING_MODE_PER_PIXEL;
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
set_specular(0.5);
set_roughness(1.0);
@@ -2359,11 +2514,10 @@ SpatialMaterial::SpatialMaterial() :
set_clearcoat(1);
set_clearcoat_gloss(0.5);
set_anisotropy(0);
- set_depth_scale(0.05);
+ set_heightmap_scale(0.05);
set_subsurface_scattering_strength(0);
set_transmission(Color(0, 0, 0));
set_refraction(0.05);
- set_line_width(1);
set_point_size(1);
set_uv1_offset(Vector3(0, 0, 0));
set_uv1_scale(Vector3(1, 1, 1));
@@ -2395,11 +2549,11 @@ SpatialMaterial::SpatialMaterial() :
set_grow(0.0);
deep_parallax = false;
- depth_parallax_flip_tangent = false;
- depth_parallax_flip_binormal = false;
- set_depth_deep_parallax_min_layers(8);
- set_depth_deep_parallax_max_layers(32);
- set_depth_deep_parallax_flip_tangent(false); //also sets binormal
+ heightmap_parallax_flip_tangent = false;
+ heightmap_parallax_flip_binormal = false;
+ set_heightmap_deep_parallax_min_layers(8);
+ set_heightmap_deep_parallax_max_layers(32);
+ set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal
detail_uv = DETAIL_UV_1;
blend_mode = BLEND_MODE_MIX;
@@ -2409,6 +2563,8 @@ SpatialMaterial::SpatialMaterial() :
for (int i = 0; i < FLAG_MAX; i++) {
flags[i] = 0;
}
+ flags[FLAG_USE_TEXTURE_REPEAT] = true;
+
diffuse_mode = DIFFUSE_BURLEY;
specular_mode = SPECULAR_SCHLICK_GGX;
@@ -2418,10 +2574,11 @@ SpatialMaterial::SpatialMaterial() :
current_key.key = 0;
current_key.invalid_key = 1;
+ texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
_queue_shader_change();
}
-SpatialMaterial::~SpatialMaterial() {
+BaseMaterial3D::~BaseMaterial3D() {
if (material_mutex)
material_mutex->lock();
@@ -2440,3 +2597,95 @@ SpatialMaterial::~SpatialMaterial() {
if (material_mutex)
material_mutex->unlock();
}
+
+//////////////////////
+
+#ifndef DISABLE_DEPRECATED
+// Kept for compatibility from 3.x to 4.0.
+bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "flags_transparent") {
+ bool transparent = p_value;
+ if (transparent) {
+ set_transparency(TRANSPARENCY_ALPHA);
+ }
+ return true;
+ } else if (p_name == "flags_unshaded") {
+ bool unshaded = p_value;
+ if (unshaded) {
+ set_shading_mode(SHADING_MODE_UNSHADED);
+ }
+ return true;
+ } else if (p_name == "flags_vertex_lighting") {
+ bool vertex_lit = p_value;
+ if (vertex_lit && get_shading_mode() != SHADING_MODE_UNSHADED) {
+ set_shading_mode(SHADING_MODE_PER_VERTEX);
+ }
+ return true;
+ } else if (p_name == "params_use_alpha_scissor") {
+ bool use_scissor = p_value;
+ if (use_scissor) {
+ set_transparency(TRANSPARENCY_ALPHA_SCISSOR);
+ }
+ return true;
+ } else if (p_name == "params_depth_draw_mode") {
+ int mode = p_value;
+ if (mode == 3) {
+ set_transparency(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
+ }
+ return true;
+ } else if (p_name == "depth_enabled") {
+ bool enabled = p_value;
+ if (enabled) {
+ set_feature(FEATURE_HEIGHT_MAPPING, true);
+ set_flag(FLAG_INVERT_HEIGHTMAP, true);
+ }
+ return true;
+ } else {
+ static const Pair<const char *, const char *> remaps[] = {
+ { "flags_use_shadow_to_opacity", "shadow_to_opacity" },
+ { "flags_use_shadow_to_opacity", "shadow_to_opacity" },
+ { "flags_no_depth_test", "no_depth_test" },
+ { "flags_use_point_size", "use_point_size" },
+ { "flags_fixed_size", "fixed_Size" },
+ { "flags_albedo_tex_force_srg", "albedo_tex_force_srgb" },
+ { "flags_do_not_receive_shadows", "disable_receive_shadows" },
+ { "flags_disable_ambient_light", "disable_ambient_light" },
+ { "params_diffuse_mode", "diffuse_mode" },
+ { "params_specular_mode", "specular_mode" },
+ { "params_blend_mode", "blend_mode" },
+ { "params_cull_mode", "cull_mode" },
+ { "params_depth_draw_mode", "params_depth_draw_mode" },
+ { "params_point_size", "point_size" },
+ { "params_billboard_mode", "billboard_mode" },
+ { "params_billboard_keep_scale", "billboard_keep_scale" },
+ { "params_grow", "grow" },
+ { "params_grow_amount", "grow_amount" },
+ { "params_alpha_scissor_threshold", "alpha_scissor_threshold" },
+
+ { "depth_scale", "heightmap_scale" },
+ { "depth_deep_parallax", "heightmap_deep_parallax" },
+ { "depth_min_layers", "heightmap_min_layers" },
+ { "depth_max_layers", "heightmap_max_layers" },
+ { "depth_flip_tangent", "heightmap_flip_tangent" },
+ { "depth_flip_binormal", "heightmap_flip_binormal" },
+ { "depth_texture", "heightmap_texture" },
+
+ { NULL, NULL },
+ };
+
+ int idx = 0;
+ while (remaps[idx].first) {
+ if (p_name == remaps[idx].first) {
+ set(remaps[idx].second, p_value);
+ return true;
+ }
+ idx++;
+ }
+
+ print_line("remapped parameter not found: " + String(p_name));
+ return true;
+ }
+
+ return false;
+}
+#endif // DISABLE_DEPRECATED
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 8e66011bec..8c5a648058 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -106,9 +106,11 @@ public:
~ShaderMaterial();
};
-class SpatialMaterial : public Material {
+class StandardMaterial3D;
- GDCLASS(SpatialMaterial, Material);
+class BaseMaterial3D : public Material {
+
+ GDCLASS(BaseMaterial3D, Material);
public:
enum TextureParam {
@@ -121,31 +123,56 @@ public:
TEXTURE_CLEARCOAT,
TEXTURE_FLOWMAP,
TEXTURE_AMBIENT_OCCLUSION,
- TEXTURE_DEPTH,
+ TEXTURE_HEIGHTMAP,
TEXTURE_SUBSURFACE_SCATTERING,
TEXTURE_TRANSMISSION,
TEXTURE_REFRACTION,
TEXTURE_DETAIL_MASK,
TEXTURE_DETAIL_ALBEDO,
TEXTURE_DETAIL_NORMAL,
+ TEXTURE_ORM,
TEXTURE_MAX
};
+ enum TextureFilter {
+ TEXTURE_FILTER_NEAREST,
+ TEXTURE_FILTER_LINEAR,
+ TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS,
+ TEXTURE_FILTER_LINEAR_WITH_MIPMAPS,
+ TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC,
+ TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC,
+ TEXTURE_FILTER_MAX
+ };
+
enum DetailUV {
DETAIL_UV_1,
DETAIL_UV_2
};
+ enum Transparency {
+ TRANSPARENCY_DISABLED,
+ TRANSPARENCY_ALPHA,
+ TRANSPARENCY_ALPHA_SCISSOR,
+ TRANSPARENCY_ALPHA_DEPTH_PRE_PASS,
+ TRANSPARENCY_MAX,
+ };
+
+ enum ShadingMode {
+ SHADING_MODE_UNSHADED,
+ SHADING_MODE_PER_PIXEL,
+ SHADING_MODE_PER_VERTEX,
+ SHADING_MODE_MAX
+ };
+
enum Feature {
- FEATURE_TRANSPARENT,
FEATURE_EMISSION,
FEATURE_NORMAL_MAPPING,
FEATURE_RIM,
FEATURE_CLEARCOAT,
FEATURE_ANISOTROPY,
FEATURE_AMBIENT_OCCLUSION,
- FEATURE_DEPTH_MAPPING,
+ FEATURE_HEIGHT_MAPPING,
FEATURE_SUBSURACE_SCATTERING,
FEATURE_TRANSMISSION,
FEATURE_REFRACTION,
@@ -164,8 +191,6 @@ public:
DEPTH_DRAW_OPAQUE_ONLY,
DEPTH_DRAW_ALWAYS,
DEPTH_DRAW_DISABLED,
- DEPTH_DRAW_ALPHA_OPAQUE_PREPASS
-
};
enum CullMode {
@@ -175,8 +200,6 @@ public:
};
enum Flags {
- FLAG_UNSHADED,
- FLAG_USE_VERTEX_LIGHTING,
FLAG_DISABLE_DEPTH_TEST,
FLAG_ALBEDO_FROM_VERTEX_COLOR,
FLAG_SRGB_VERTEX_COLOR,
@@ -185,15 +208,16 @@ public:
FLAG_BILLBOARD_KEEP_SCALE,
FLAG_UV1_USE_TRIPLANAR,
FLAG_UV2_USE_TRIPLANAR,
- FLAG_TRIPLANAR_USE_WORLD,
+ FLAG_UV1_USE_WORLD_TRIPLANAR,
+ FLAG_UV2_USE_WORLD_TRIPLANAR,
FLAG_AO_ON_UV2,
FLAG_EMISSION_ON_UV2,
- FLAG_USE_ALPHA_SCISSOR,
FLAG_ALBEDO_TEXTURE_FORCE_SRGB,
FLAG_DONT_RECEIVE_SHADOWS,
- FLAG_ENSURE_CORRECT_NORMALS,
FLAG_DISABLE_AMBIENT_LIGHT,
FLAG_USE_SHADOW_TO_OPACITY,
+ FLAG_USE_TEXTURE_REPEAT,
+ FLAG_INVERT_HEIGHTMAP,
FLAG_MAX
};
@@ -244,12 +268,12 @@ private:
union MaterialKey {
struct {
- uint64_t feature_mask : 12;
+ uint64_t feature_mask : FEATURE_MAX;
uint64_t detail_uv : 1;
uint64_t blend_mode : 2;
uint64_t depth_draw_mode : 2;
uint64_t cull_mode : 2;
- uint64_t flags : 19;
+ uint64_t flags : FLAG_MAX;
uint64_t detail_blend_mode : 2;
uint64_t diffuse_mode : 3;
uint64_t specular_mode : 3;
@@ -260,8 +284,10 @@ private:
uint64_t proximity_fade : 1;
uint64_t distance_fade : 2;
uint64_t emission_op : 1;
- uint64_t texture_metallic : 1;
- uint64_t texture_roughness : 1;
+ uint64_t texture_filter : 3;
+ uint64_t transparency : 2;
+ uint64_t shading_mode : 2;
+ uint64_t roughness_channel : 3;
};
uint64_t key;
@@ -293,6 +319,10 @@ private:
mk.blend_mode = blend_mode;
mk.depth_draw_mode = depth_draw_mode;
mk.cull_mode = cull_mode;
+ mk.texture_filter = texture_filter;
+ mk.transparency = transparency;
+ mk.shading_mode = shading_mode;
+ mk.roughness_channel = roughness_texture_channel;
for (int i = 0; i < FLAG_MAX; i++) {
if (flags[i]) {
mk.flags |= ((uint64_t)1 << i);
@@ -307,8 +337,6 @@ private:
mk.proximity_fade = proximity_fade_enabled;
mk.distance_fade = distance_fade;
mk.emission_op = emission_op;
- mk.texture_metallic = textures[TEXTURE_METALLIC].is_valid() ? 1 : 0;
- mk.texture_roughness = textures[TEXTURE_ROUGHNESS].is_valid() ? 1 : 0;
return mk;
}
@@ -326,7 +354,7 @@ private:
StringName clearcoat;
StringName clearcoat_gloss;
StringName anisotropy;
- StringName depth_scale;
+ StringName heightmap_scale;
StringName subsurface_scattering_strength;
StringName transmission;
StringName refraction;
@@ -338,9 +366,9 @@ private:
StringName particles_anim_h_frames;
StringName particles_anim_v_frames;
StringName particles_anim_loop;
- StringName depth_min_layers;
- StringName depth_max_layers;
- StringName depth_flip;
+ StringName heightmap_min_layers;
+ StringName heightmap_max_layers;
+ StringName heightmap_flip;
StringName uv1_blend_sharpness;
StringName uv2_blend_sharpness;
StringName grow;
@@ -350,11 +378,10 @@ private:
StringName ao_light_affect;
StringName metallic_texture_channel;
- StringName roughness_texture_channel;
StringName ao_texture_channel;
StringName clearcoat_texture_channel;
StringName rim_texture_channel;
- StringName depth_texture_channel;
+ StringName heightmap_texture_channel;
StringName refraction_texture_channel;
StringName alpha_scissor_threshold;
@@ -362,15 +389,17 @@ private:
};
static Mutex *material_mutex;
- static SelfList<SpatialMaterial>::List *dirty_materials;
+ static SelfList<BaseMaterial3D>::List *dirty_materials;
static ShaderNames *shader_names;
- SelfList<SpatialMaterial> element;
+ SelfList<BaseMaterial3D> element;
void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
_FORCE_INLINE_ bool _is_shader_dirty() const;
+ bool orm;
+
Color albedo;
float specular;
float metallic;
@@ -383,11 +412,10 @@ private:
float clearcoat;
float clearcoat_gloss;
float anisotropy;
- float depth_scale;
+ float heightmap_scale;
float subsurface_scattering_strength;
Color transmission;
float refraction;
- float line_width;
float point_size;
float alpha_scissor_threshold;
bool grow_enabled;
@@ -396,6 +424,10 @@ private:
int particles_anim_h_frames;
int particles_anim_v_frames;
bool particles_anim_loop;
+ Transparency transparency;
+ ShadingMode shading_mode;
+
+ TextureFilter texture_filter;
Vector3 uv1_scale;
Vector3 uv1_offset;
@@ -410,8 +442,8 @@ private:
bool deep_parallax;
int deep_parallax_min_layers;
int deep_parallax_max_layers;
- bool depth_parallax_flip_tangent;
- bool depth_parallax_flip_binormal;
+ bool heightmap_parallax_flip_tangent;
+ bool heightmap_parallax_flip_binormal;
bool proximity_fade_enabled;
float proximity_fade_distance;
@@ -437,13 +469,13 @@ private:
bool features[FEATURE_MAX];
- Ref<Texture> textures[TEXTURE_MAX];
+ Ref<Texture2D> textures[TEXTURE_MAX];
_FORCE_INLINE_ void _validate_feature(const String &text, Feature feature, PropertyInfo &property) const;
static const int MAX_MATERIALS_FOR_2D = 128;
- static Ref<SpatialMaterial> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff
+ static Ref<StandardMaterial3D> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff
void _validate_high_end(const String &text, PropertyInfo &property) const;
@@ -492,23 +524,23 @@ public:
void set_anisotropy(float p_anisotropy);
float get_anisotropy() const;
- void set_depth_scale(float p_depth_scale);
- float get_depth_scale() const;
+ void set_heightmap_scale(float p_heightmap_scale);
+ float get_heightmap_scale() const;
- void set_depth_deep_parallax(bool p_enable);
- bool is_depth_deep_parallax_enabled() const;
+ void set_heightmap_deep_parallax(bool p_enable);
+ bool is_heightmap_deep_parallax_enabled() const;
- void set_depth_deep_parallax_min_layers(int p_layer);
- int get_depth_deep_parallax_min_layers() const;
+ void set_heightmap_deep_parallax_min_layers(int p_layer);
+ int get_heightmap_deep_parallax_min_layers() const;
- void set_depth_deep_parallax_max_layers(int p_layer);
- int get_depth_deep_parallax_max_layers() const;
+ void set_heightmap_deep_parallax_max_layers(int p_layer);
+ int get_heightmap_deep_parallax_max_layers() const;
- void set_depth_deep_parallax_flip_tangent(bool p_flip);
- bool get_depth_deep_parallax_flip_tangent() const;
+ void set_heightmap_deep_parallax_flip_tangent(bool p_flip);
+ bool get_heightmap_deep_parallax_flip_tangent() const;
- void set_depth_deep_parallax_flip_binormal(bool p_flip);
- bool get_depth_deep_parallax_flip_binormal() const;
+ void set_heightmap_deep_parallax_flip_binormal(bool p_flip);
+ bool get_heightmap_deep_parallax_flip_binormal() const;
void set_subsurface_scattering_strength(float p_subsurface_scattering_strength);
float get_subsurface_scattering_strength() const;
@@ -519,12 +551,15 @@ public:
void set_refraction(float p_refraction);
float get_refraction() const;
- void set_line_width(float p_line_width);
- float get_line_width() const;
-
void set_point_size(float p_point_size);
float get_point_size() const;
+ void set_transparency(Transparency p_transparency);
+ Transparency get_transparency() const;
+
+ void set_shading_mode(ShadingMode p_shading_mode);
+ ShadingMode get_shading_mode() const;
+
void set_detail_uv(DetailUV p_detail_uv);
DetailUV get_detail_uv() const;
@@ -549,10 +584,13 @@ public:
void set_flag(Flags p_flag, bool p_enabled);
bool get_flag(Flags p_flag) const;
- void set_texture(TextureParam p_param, const Ref<Texture> &p_texture);
- Ref<Texture> get_texture(TextureParam p_param) const;
+ void set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_texture(TextureParam p_param) const;
// Used only for shader material conversion
- Ref<Texture> get_texture_by_name(StringName p_name) const;
+ Ref<Texture2D> get_texture_by_name(StringName p_name) const;
+
+ void set_texture_filter(TextureFilter p_filter);
+ TextureFilter get_texture_filter() const;
void set_feature(Feature p_feature, bool p_enabled);
bool get_feature(Feature p_feature) const;
@@ -634,23 +672,46 @@ public:
virtual Shader::Mode get_shader_mode() const;
- SpatialMaterial();
- virtual ~SpatialMaterial();
+ BaseMaterial3D(bool p_orm);
+ virtual ~BaseMaterial3D();
};
-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)
-VARIANT_ENUM_CAST(SpatialMaterial::TextureChannel)
-VARIANT_ENUM_CAST(SpatialMaterial::EmissionOperator)
-VARIANT_ENUM_CAST(SpatialMaterial::DistanceFadeMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::TextureParam)
+VARIANT_ENUM_CAST(BaseMaterial3D::TextureFilter)
+VARIANT_ENUM_CAST(BaseMaterial3D::ShadingMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::Transparency)
+VARIANT_ENUM_CAST(BaseMaterial3D::DetailUV)
+VARIANT_ENUM_CAST(BaseMaterial3D::Feature)
+VARIANT_ENUM_CAST(BaseMaterial3D::BlendMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::DepthDrawMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::CullMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::Flags)
+VARIANT_ENUM_CAST(BaseMaterial3D::DiffuseMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::SpecularMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::BillboardMode)
+VARIANT_ENUM_CAST(BaseMaterial3D::TextureChannel)
+VARIANT_ENUM_CAST(BaseMaterial3D::EmissionOperator)
+VARIANT_ENUM_CAST(BaseMaterial3D::DistanceFadeMode)
+
+class StandardMaterial3D : public BaseMaterial3D {
+ GDCLASS(StandardMaterial3D, BaseMaterial3D)
+protected:
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
+ bool _set(const StringName &p_name, const Variant &p_value);
+#endif
+
+public:
+ StandardMaterial3D() :
+ BaseMaterial3D(false) {}
+};
+
+class ORMMaterial3D : public BaseMaterial3D {
+ GDCLASS(ORMMaterial3D, BaseMaterial3D)
+public:
+ ORMMaterial3D() :
+ BaseMaterial3D(true) {}
+};
//////////////////////
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 0599920303..58463abad8 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -159,7 +159,7 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
bool Mesh::surface_is_softbody_friendly(int p_idx) const {
const uint32_t surface_format = surface_get_format(p_idx);
- return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_VERTEX)) && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL)));
+ return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL)));
}
PoolVector<Face3> Mesh::get_faces() const {
@@ -500,10 +500,8 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP);
- BIND_ENUM_CONSTANT(PRIMITIVE_LINE_LOOP);
BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES);
BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP);
- BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_FAN);
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED);
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE);
@@ -518,19 +516,14 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BASE);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_VERTEX);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BONES);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_WEIGHTS);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX);
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES);
- BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_16_BIT_BONES);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT);
@@ -597,6 +590,124 @@ Vector<Ref<Shape> > Mesh::convex_decompose() const {
Mesh::Mesh() {
}
+static PoolVector<uint8_t> _fix_array_compatibility(const PoolVector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) {
+
+ bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE)));
+ bool has_bones = (p_format & Mesh::ARRAY_FORMAT_BONES);
+ bool bone_8 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2));
+ bool weight_32 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_TEX_UV2 << 2));
+
+ print_line("convert vertex16: " + itos(vertex_16bit) + " convert bone 8 " + itos(bone_8) + " convert weight 32 " + itos(weight_32));
+
+ if (!vertex_16bit && !bone_8 && !weight_32) {
+ return p_src;
+ }
+
+ bool vertex_2d = (p_format & (Mesh::ARRAY_COMPRESS_INDEX << 1));
+
+ uint32_t src_stride = p_src.size() / p_elements;
+ uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) + (bone_8 ? 4 : 0) - (weight_32 ? 8 : 0);
+
+ PoolVector<uint8_t> ret = p_src;
+
+ ret.resize(dst_stride * p_elements);
+ {
+ PoolVector<uint8_t>::Write w = ret.write();
+ PoolVector<uint8_t>::Read r = p_src.read();
+
+ for (uint32_t i = 0; i < p_elements; i++) {
+
+ uint32_t remaining = src_stride;
+ const uint8_t *src = (const uint8_t *)(r.ptr() + src_stride * i);
+ uint8_t *dst = (uint8_t *)(w.ptr() + dst_stride * i);
+
+ if (!vertex_2d) { //3D
+ if (vertex_16bit) {
+ float *dstw = (float *)dst;
+ const uint16_t *srcr = (const uint16_t *)src;
+ dstw[0] = Math::half_to_float(srcr[0]);
+ dstw[1] = Math::half_to_float(srcr[1]);
+ dstw[2] = Math::half_to_float(srcr[2]);
+ remaining -= 8;
+ src += 8;
+ } else {
+ src += 12;
+ remaining -= 12;
+ }
+ dst += 12;
+ } else {
+ if (vertex_16bit) {
+ float *dstw = (float *)dst;
+ const uint16_t *srcr = (const uint16_t *)src;
+ dstw[0] = Math::half_to_float(srcr[0]);
+ dstw[1] = Math::half_to_float(srcr[1]);
+ remaining -= 4;
+ src += 4;
+ } else {
+ src += 8;
+ remaining -= 8;
+ }
+ dst += 8;
+ }
+
+ if (has_bones) {
+
+ remaining -= bone_8 ? 4 : 8;
+ remaining -= weight_32 ? 16 : 8;
+ }
+
+ for (uint32_t j = 0; j < remaining; j++) {
+ dst[j] = src[j];
+ }
+
+ if (has_bones) {
+
+ dst += remaining;
+ src += remaining;
+
+ if (bone_8) {
+
+ const uint8_t *src_bones = (const uint8_t *)src;
+ uint16_t *dst_bones = (uint16_t *)dst;
+
+ dst_bones[0] = src_bones[0];
+ dst_bones[1] = src_bones[1];
+ dst_bones[2] = src_bones[2];
+ dst_bones[3] = src_bones[3];
+
+ src += 4;
+ } else {
+ for (uint32_t j = 0; j < 8; j++) {
+ dst[j] = src[j];
+ }
+
+ src += 8;
+ }
+
+ dst += 8;
+
+ if (weight_32) {
+
+ const float *src_weights = (const float *)src;
+ uint16_t *dst_weights = (uint16_t *)dst;
+
+ dst_weights[0] = CLAMP(src_weights[0] * 65535, 0, 65535); //16bits unorm
+ dst_weights[1] = CLAMP(src_weights[1] * 65535, 0, 65535);
+ dst_weights[2] = CLAMP(src_weights[2] * 65535, 0, 65535);
+ dst_weights[3] = CLAMP(src_weights[3] * 65535, 0, 65535);
+
+ } else {
+ for (uint32_t j = 0; j < 8; j++) {
+ dst[j] = src[j];
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
String sname = p_name;
@@ -631,9 +742,13 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
if (!sname.begins_with("surfaces"))
return false;
+ WARN_DEPRECATED_MSG("Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene.");
+
int idx = sname.get_slicec('/', 1).to_int();
String what = sname.get_slicec('/', 2);
@@ -644,12 +759,13 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(!d.has("primitive"), false);
if (d.has("arrays")) {
- //old format
+ //oldest format (2.x)
ERR_FAIL_COND_V(!d.has("morph_arrays"), false);
add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]);
} else if (d.has("array_data")) {
-
+ //print_line("array data (old style");
+ //older format (3.x)
PoolVector<uint8_t> array_data = d["array_data"];
PoolVector<uint8_t> array_index_data;
if (d.has("array_index_data"))
@@ -660,9 +776,23 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
uint32_t primitive = d["primitive"];
+ uint32_t primitive_remap[7] = {
+ PRIMITIVE_POINTS,
+ PRIMITIVE_LINES,
+ PRIMITIVE_LINE_STRIP,
+ PRIMITIVE_LINES,
+ PRIMITIVE_TRIANGLES,
+ PRIMITIVE_TRIANGLE_STRIP,
+ PRIMITIVE_TRIANGLE_STRIP
+ };
+
+ primitive = primitive_remap[primitive]; //compatibility
+
ERR_FAIL_COND_V(!d.has("vertex_count"), false);
int vertex_count = d["vertex_count"];
+ array_data = _fix_array_compatibility(array_data, format, vertex_count);
+
int index_count = 0;
if (d.has("index_count"))
index_count = d["index_count"];
@@ -673,10 +803,17 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
Array blend_shape_data = d["blend_shape_data"];
for (int i = 0; i < blend_shape_data.size(); i++) {
PoolVector<uint8_t> shape = blend_shape_data[i];
+ shape = _fix_array_compatibility(shape, format, vertex_count);
+
blend_shapes.push_back(shape);
}
}
+ //clear unused flags
+ print_line("format pre: " + itos(format));
+ format &= ~uint32_t((1 << (ARRAY_VERTEX + ARRAY_COMPRESS_BASE)) | (ARRAY_COMPRESS_INDEX << 2) | (ARRAY_COMPRESS_TEX_UV2 << 2));
+ print_line("format post: " + itos(format));
+
ERR_FAIL_COND_V(!d.has("aabb"), false);
AABB aabb = d["aabb"];
@@ -705,10 +842,204 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
+#endif // DISABLE_DEPRECATED
return false;
}
+Array ArrayMesh::_get_surfaces() const {
+
+ if (mesh.is_null()) {
+ return Array();
+ }
+
+ Array ret;
+ for (int i = 0; i < surfaces.size(); i++) {
+ VisualServer::SurfaceData surface = VS::get_singleton()->mesh_get_surface(mesh, i);
+ Dictionary data;
+ data["format"] = surface.format;
+ data["primitive"] = surface.primitive;
+ data["vertex_data"] = surface.vertex_data;
+ data["vertex_count"] = surface.vertex_count;
+ data["aabb"] = surface.aabb;
+ if (surface.index_count) {
+ data["index_data"] = surface.index_data;
+ data["index_count"] = surface.index_count;
+ };
+
+ Array lods;
+ for (int j = 0; j < surface.lods.size(); j++) {
+ lods.push_back(surface.lods[j].edge_length);
+ lods.push_back(surface.lods[j].index_data);
+ }
+
+ if (lods.size()) {
+ data["lods"] = lods;
+ }
+
+ Array bone_aabbs;
+ for (int j = 0; j < surface.bone_aabbs.size(); j++) {
+ bone_aabbs.push_back(surface.bone_aabbs[j]);
+ }
+ if (bone_aabbs.size()) {
+ data["bone_aabbs"] = bone_aabbs;
+ }
+
+ Array blend_shapes;
+ for (int j = 0; j < surface.blend_shapes.size(); j++) {
+ blend_shapes.push_back(surface.blend_shapes[j]);
+ }
+
+ if (surfaces[i].material.is_valid()) {
+ data["material"] = surfaces[i].material;
+ }
+
+ if (surfaces[i].name != String()) {
+ data["name"] = surfaces[i].name;
+ }
+
+ if (surfaces[i].is_2d) {
+ data["2d"] = true;
+ }
+
+ ret.push_back(data);
+ }
+ print_line("Saving surfaces: " + itos(ret.size()));
+
+ return ret;
+}
+
+void ArrayMesh::_create_if_empty() const {
+ if (!mesh.is_valid()) {
+ mesh = VS::get_singleton()->mesh_create();
+ VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)blend_shape_mode);
+ }
+}
+
+void ArrayMesh::_set_surfaces(const Array &p_surfaces) {
+
+ Vector<VS::SurfaceData> surface_data;
+ Vector<Ref<Material> > surface_materials;
+ Vector<String> surface_names;
+ Vector<bool> surface_2d;
+
+ for (int i = 0; i < p_surfaces.size(); i++) {
+ VS::SurfaceData surface;
+ Dictionary d = p_surfaces[i];
+ ERR_FAIL_COND(!d.has("format"));
+ ERR_FAIL_COND(!d.has("primitive"));
+ ERR_FAIL_COND(!d.has("vertex_data"));
+ ERR_FAIL_COND(!d.has("vertex_count"));
+ ERR_FAIL_COND(!d.has("aabb"));
+ surface.format = d["format"];
+ surface.primitive = VS::PrimitiveType(int(d["primitive"]));
+ surface.vertex_data = d["vertex_data"];
+ surface.vertex_count = d["vertex_count"];
+ surface.aabb = d["aabb"];
+
+ if (d.has("index_data")) {
+ ERR_FAIL_COND(!d.has("index_count"));
+ surface.index_data = d["index_data"];
+ surface.index_count = d["index_count"];
+ }
+
+ if (d.has("lods")) {
+ Array lods = d["lods"];
+ ERR_FAIL_COND(lods.size() & 1); //must be even
+ for (int j = 0; j < lods.size(); j += 2) {
+ VS::SurfaceData::LOD lod;
+ lod.edge_length = lods[j + 0];
+ lod.index_data = lods[j + 1];
+ surface.lods.push_back(lod);
+ }
+ }
+
+ if (d.has("bone_aabbs")) {
+ Array bone_aabbs = d["bone_aabbs"];
+ for (int j = 0; j < bone_aabbs.size(); j++) {
+ surface.bone_aabbs.push_back(bone_aabbs[j]);
+ }
+ }
+
+ if (d.has("blend_shapes")) {
+ Array blend_shapes;
+ for (int j = 0; j < blend_shapes.size(); j++) {
+ surface.blend_shapes.push_back(blend_shapes[j]);
+ }
+ }
+
+ Ref<Material> material;
+ if (d.has("material")) {
+ material = d["material"];
+ if (material.is_valid()) {
+ surface.material = material->get_rid();
+ }
+ }
+
+ String name;
+ if (d.has("name")) {
+ name = d["name"];
+ }
+
+ bool _2d = false;
+ if (d.has("2d")) {
+ _2d = d["2d"];
+ }
+ /*
+ print_line("format: " + itos(surface.format));
+ print_line("aabb: " + surface.aabb);
+ print_line("array size: " + itos(surface.vertex_data.size()));
+ print_line("vertex count: " + itos(surface.vertex_count));
+ print_line("index size: " + itos(surface.index_data.size()));
+ print_line("index count: " + itos(surface.index_count));
+ print_line("primitive: " + itos(surface.primitive));
+*/
+ surface_data.push_back(surface);
+ surface_materials.push_back(material);
+ surface_names.push_back(name);
+ surface_2d.push_back(_2d);
+ }
+
+ if (mesh.is_valid()) {
+ //if mesh exists, it needs to be updated
+ VS::get_singleton()->mesh_clear(mesh);
+ for (int i = 0; i < surface_data.size(); i++) {
+ VS::get_singleton()->mesh_add_surface(mesh, surface_data[i]);
+ }
+ } else {
+ // if mesh does not exist (first time this is loaded, most likely),
+ // we can create it with a single call, which is a lot more efficient and thread friendly
+ print_line("create mesh from surfaces: " + itos(surface_data.size()));
+ mesh = VS::get_singleton()->mesh_create_from_surfaces(surface_data);
+ VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)blend_shape_mode);
+ }
+
+ surfaces.clear();
+
+ aabb = AABB();
+ for (int i = 0; i < surface_data.size(); i++) {
+ Surface s;
+ s.aabb = surface_data[i].aabb;
+ if (i == 0) {
+ aabb = s.aabb;
+ blend_shapes.resize(surface_data[i].blend_shapes.size());
+ } else {
+ aabb.merge_with(s.aabb);
+ }
+
+ s.material = surface_materials[i];
+ s.is_2d = surface_2d[i];
+ s.name = surface_names[i];
+
+ s.format = surface_data[i].format;
+ s.primitive = PrimitiveType(surface_data[i].primitive);
+ s.array_length = surface_data[i].vertex_count;
+ s.index_array_length = surface_data[i].index_count;
+
+ surfaces.push_back(s);
+ }
+}
+
bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
if (_is_generated())
@@ -739,48 +1070,8 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
else if (what == "name")
r_ret = surface_get_name(idx);
return true;
- } else if (!sname.begins_with("surfaces"))
- return false;
-
- int idx = sname.get_slicec('/', 1).to_int();
- ERR_FAIL_INDEX_V(idx, surfaces.size(), false);
-
- Dictionary d;
-
- d["array_data"] = VS::get_singleton()->mesh_surface_get_array(mesh, idx);
- d["vertex_count"] = VS::get_singleton()->mesh_surface_get_array_len(mesh, idx);
- d["array_index_data"] = VS::get_singleton()->mesh_surface_get_index_array(mesh, idx);
- d["index_count"] = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, idx);
- d["primitive"] = VS::get_singleton()->mesh_surface_get_primitive_type(mesh, idx);
- d["format"] = VS::get_singleton()->mesh_surface_get_format(mesh, idx);
- d["aabb"] = VS::get_singleton()->mesh_surface_get_aabb(mesh, idx);
-
- Vector<AABB> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh, idx);
- Array arr;
- arr.resize(skel_aabb.size());
- for (int i = 0; i < skel_aabb.size(); i++) {
- arr[i] = skel_aabb[i];
- }
- d["skeleton_aabb"] = arr;
-
- Vector<PoolVector<uint8_t> > blend_shape_data = VS::get_singleton()->mesh_surface_get_blend_shapes(mesh, idx);
-
- Array md;
- for (int i = 0; i < blend_shape_data.size(); i++) {
- md.push_back(blend_shape_data[i]);
}
- d["blend_shape_data"] = md;
-
- Ref<Material> m = surface_get_material(idx);
- if (m.is_valid())
- d["material"] = m;
- String n = surface_get_name(idx);
- if (n != "")
- d["name"] = n;
-
- r_ret = d;
-
return true;
}
@@ -796,12 +1087,11 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < surfaces.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, "surfaces/" + itos(i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
if (surfaces[i].is_2d) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial", PROPERTY_USAGE_EDITOR));
} else {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_EDITOR));
}
}
}
@@ -819,55 +1109,61 @@ void ArrayMesh::_recompute_aabb() {
aabb.merge_with(surfaces[i].aabb);
}
}
+#ifndef _MSC_VER
+#warning need to add binding to add_surface using future MeshSurfaceData object
+#endif
+void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<VS::SurfaceData::LOD> &p_lods) {
-void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) {
+ _create_if_empty();
Surface s;
s.aabb = p_aabb;
s.is_2d = p_format & ARRAY_FLAG_USE_2D_VERTICES;
+ s.primitive = p_primitive;
+ s.array_length = p_vertex_count;
+ s.index_array_length = p_index_count;
+ s.format = p_format;
+
surfaces.push_back(s);
_recompute_aabb();
- VisualServer::get_singleton()->mesh_add_surface(mesh, p_format, (VS::PrimitiveType)p_primitive, p_array, p_vertex_count, p_index_array, p_index_count, p_aabb, p_blend_shapes, p_bone_aabbs);
-}
+ VS::SurfaceData sd;
+ sd.format = p_format;
+ sd.primitive = VS::PrimitiveType(p_primitive);
+ sd.aabb = p_aabb;
+ sd.vertex_count = p_vertex_count;
+ sd.vertex_data = p_array;
+ sd.index_count = p_index_count;
+ sd.index_data = p_index_array;
+ sd.blend_shapes = p_blend_shapes;
+ sd.bone_aabbs = p_bone_aabb;
+ sd.lods = p_lods;
-void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_flags) {
+ VisualServer::get_singleton()->mesh_add_surface(mesh, sd);
- ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX);
-
- Surface s;
-
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_flags);
-
- /* make aABB? */ {
-
- Variant arr = p_arrays[ARRAY_VERTEX];
- PoolVector<Vector3> vertices = arr;
- int len = vertices.size();
- ERR_FAIL_COND(len == 0);
- PoolVector<Vector3>::Read r = vertices.read();
- const Vector3 *vtx = r.ptr();
+ clear_cache();
+ _change_notify();
+ emit_changed();
+}
- // check AABB
- AABB aabb;
- for (int i = 0; i < len; i++) {
+void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) {
- if (i == 0)
- aabb.position = vtx[i];
- else
- aabb.expand_to(vtx[i]);
- }
+ ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX);
- s.aabb = aabb;
- s.is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY;
- surfaces.push_back(s);
+ VS::SurfaceData surface;
- _recompute_aabb();
- }
+ Error err = VS::get_singleton()->mesh_create_surface_data_from_arrays(&surface, (VisualServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_lods, p_flags);
+ ERR_FAIL_COND(err != OK);
- clear_cache();
- _change_notify();
- emit_changed();
+ /* print_line("format: " + itos(surface.format));
+ print_line("aabb: " + surface.aabb);
+ print_line("array size: " + itos(surface.vertex_data.size()));
+ print_line("vertex count: " + itos(surface.vertex_count));
+ print_line("index size: " + itos(surface.index_data.size()));
+ print_line("index count: " + itos(surface.index_count));
+ print_line("primitive: " + itos(surface.primitive));
+*/
+ add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shapes, surface.bone_aabbs, surface.lods);
}
Array ArrayMesh::surface_get_arrays(int p_surface) const {
@@ -880,6 +1176,10 @@ Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
return VisualServer::get_singleton()->mesh_surface_get_blend_shape_arrays(mesh, p_surface);
}
+Dictionary ArrayMesh::surface_get_lods(int p_surface) const {
+ ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Dictionary());
+ return VisualServer::get_singleton()->mesh_surface_get_lods(mesh, p_surface);
+}
int ArrayMesh::get_surface_count() const {
@@ -903,7 +1203,7 @@ void ArrayMesh::add_blend_shape(const StringName &p_name) {
}
blend_shapes.push_back(name);
- VS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size());
+ //VS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size());
}
int ArrayMesh::get_blend_shape_count() const {
@@ -924,7 +1224,9 @@ void ArrayMesh::clear_blend_shapes() {
void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) {
blend_shape_mode = p_mode;
- VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)p_mode);
+ if (mesh.is_valid()) {
+ VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)p_mode);
+ }
}
ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const {
@@ -932,40 +1234,28 @@ ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const {
return blend_shape_mode;
}
-void ArrayMesh::surface_remove(int p_idx) {
-
- ERR_FAIL_INDEX(p_idx, surfaces.size());
- VisualServer::get_singleton()->mesh_remove_surface(mesh, p_idx);
- surfaces.remove(p_idx);
-
- clear_cache();
- _recompute_aabb();
- _change_notify();
- emit_changed();
-}
-
int ArrayMesh::surface_get_array_len(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
- return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, p_idx);
+ return surfaces[p_idx].array_length;
}
int ArrayMesh::surface_get_array_index_len(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
- return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, p_idx);
+ return surfaces[p_idx].index_array_length;
}
uint32_t ArrayMesh::surface_get_format(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), 0);
- return VisualServer::get_singleton()->mesh_surface_get_format(mesh, p_idx);
+ return surfaces[p_idx].format;
}
ArrayMesh::PrimitiveType ArrayMesh::surface_get_primitive_type(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), PRIMITIVE_LINES);
- return (PrimitiveType)VisualServer::get_singleton()->mesh_surface_get_primitive_type(mesh, p_idx);
+ return surfaces[p_idx].primitive;
}
void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
@@ -986,7 +1276,6 @@ int ArrayMesh::surface_find_by_name(const String &p_name) const {
return i;
}
}
-
return -1;
}
@@ -1025,35 +1314,9 @@ Ref<Material> ArrayMesh::surface_get_material(int p_idx) const {
return surfaces[p_idx].material;
}
-void ArrayMesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) {
-
- VisualServer::get_singleton()->mesh_add_surface_from_mesh_data(mesh, p_mesh_data);
- AABB aabb;
- for (int i = 0; i < p_mesh_data.vertices.size(); i++) {
-
- if (i == 0)
- aabb.position = p_mesh_data.vertices[i];
- else
- aabb.expand_to(p_mesh_data.vertices[i]);
- }
-
- Surface s;
- s.aabb = aabb;
- if (surfaces.size() == 0)
- aabb = s.aabb;
- else
- aabb.merge_with(s.aabb);
-
- clear_cache();
-
- surfaces.push_back(s);
- _change_notify();
-
- emit_changed();
-}
-
RID ArrayMesh::get_rid() const {
+ _create_if_empty();
return mesh;
}
AABB ArrayMesh::get_aabb() const {
@@ -1061,8 +1324,18 @@ AABB ArrayMesh::get_aabb() const {
return aabb;
}
+void ArrayMesh::clear_surfaces() {
+ if (!mesh.is_valid()) {
+ return;
+ }
+ VS::get_singleton()->mesh_clear(mesh);
+ surfaces.clear();
+ aabb = AABB();
+}
+
void ArrayMesh::set_custom_aabb(const AABB &p_custom) {
+ _create_if_empty();
custom_aabb = p_custom;
VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
emit_changed();
@@ -1075,6 +1348,9 @@ AABB ArrayMesh::get_custom_aabb() const {
void ArrayMesh::regen_normalmaps() {
+ if (surfaces.size() == 0) {
+ return;
+ }
Vector<Ref<SurfaceTool> > surfs;
for (int i = 0; i < get_surface_count(); i++) {
@@ -1083,9 +1359,7 @@ void ArrayMesh::regen_normalmaps() {
surfs.push_back(st);
}
- while (get_surface_count()) {
- surface_remove(0);
- }
+ clear_surfaces();
for (int i = 0; i < surfs.size(); i++) {
@@ -1205,9 +1479,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
}
//remove surfaces
- while (get_surface_count()) {
- surface_remove(0);
- }
+ clear_surfaces();
//create surfacetools for each surface..
Vector<Ref<SurfaceTool> > surfaces_tools;
@@ -1291,8 +1563,8 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode);
ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
- ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
- ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &ArrayMesh::surface_remove);
+ ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces);
ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region);
ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len);
ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len);
@@ -1314,7 +1586,11 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb);
ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative", PROPERTY_USAGE_NOEDITOR), "set_blend_shape_mode", "get_blend_shape_mode");
+ ClassDB::bind_method(D_METHOD("_set_surfaces", "surfaces"), &ArrayMesh::_set_surfaces);
+ ClassDB::bind_method(D_METHOD("_get_surfaces"), &ArrayMesh::_get_surfaces);
+
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_surfaces", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_surfaces", "_get_surfaces");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
BIND_CONSTANT(NO_INDEX_ARRAY);
@@ -1355,11 +1631,14 @@ void ArrayMesh::reload_from_file() {
ArrayMesh::ArrayMesh() {
- mesh = VisualServer::get_singleton()->mesh_create();
+ //mesh is now created on demand
+ //mesh = VisualServer::get_singleton()->mesh_create();
blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
}
ArrayMesh::~ArrayMesh() {
- VisualServer::get_singleton()->free(mesh);
+ if (mesh.is_valid()) {
+ VisualServer::get_singleton()->free(mesh);
+ }
}
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 30ce94f16b..b8f3702bbe 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -83,21 +83,17 @@ public:
ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX,
ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1),
- ARRAY_COMPRESS_VERTEX = 1 << (ARRAY_VERTEX + ARRAY_COMPRESS_BASE), // mandatory
ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE),
- ARRAY_COMPRESS_BONES = 1 << (ARRAY_BONES + ARRAY_COMPRESS_BASE),
- ARRAY_COMPRESS_WEIGHTS = 1 << (ARRAY_WEIGHTS + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE),
ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1,
- ARRAY_FLAG_USE_16_BIT_BONES = ARRAY_COMPRESS_INDEX << 2,
ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3,
- ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 | ARRAY_COMPRESS_WEIGHTS
+ ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2
};
@@ -105,10 +101,9 @@ public:
PRIMITIVE_POINTS = VisualServer::PRIMITIVE_POINTS,
PRIMITIVE_LINES = VisualServer::PRIMITIVE_LINES,
PRIMITIVE_LINE_STRIP = VisualServer::PRIMITIVE_LINE_STRIP,
- PRIMITIVE_LINE_LOOP = VisualServer::PRIMITIVE_LINE_LOOP,
PRIMITIVE_TRIANGLES = VisualServer::PRIMITIVE_TRIANGLES,
PRIMITIVE_TRIANGLE_STRIP = VisualServer::PRIMITIVE_TRIANGLE_STRIP,
- PRIMITIVE_TRIANGLE_FAN = VisualServer::PRIMITIVE_TRIANGLE_FAN,
+ PRIMITIVE_MAX = VisualServer::PRIMITIVE_MAX,
};
enum BlendShapeMode {
@@ -123,6 +118,7 @@ public:
virtual bool surface_is_softbody_friendly(int p_idx) const;
virtual Array surface_get_arrays(int p_surface) const = 0;
virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0;
+ virtual Dictionary surface_get_lods(int p_surface) const = 0;
virtual uint32_t surface_get_format(int p_idx) const = 0;
virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0;
virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) = 0;
@@ -160,20 +156,29 @@ class ArrayMesh : public Mesh {
GDCLASS(ArrayMesh, Mesh);
RES_BASE_EXTENSION("mesh");
+ Array _get_surfaces() const;
+ void _set_surfaces(const Array &p_data);
+
private:
struct Surface {
+ uint32_t format;
+ int array_length;
+ int index_array_length;
+ PrimitiveType primitive;
+
String name;
AABB aabb;
Ref<Material> material;
bool is_2d;
};
Vector<Surface> surfaces;
- RID mesh;
+ mutable RID mesh;
AABB aabb;
BlendShapeMode blend_shape_mode;
Vector<StringName> blend_shapes;
AABB custom_aabb;
+ _FORCE_INLINE_ void _create_if_empty() const;
void _recompute_aabb();
protected:
@@ -186,11 +191,13 @@ protected:
static void _bind_methods();
public:
- void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT);
- void add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>());
+ void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT);
+
+ void add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<VS::SurfaceData::LOD> &p_lods = Vector<VS::SurfaceData::LOD>());
Array surface_get_arrays(int p_surface) const;
Array surface_get_blend_shape_arrays(int p_surface) const;
+ Dictionary surface_get_lods(int p_surface) const;
void add_blend_shape(const StringName &p_name);
int get_blend_shape_count() const;
@@ -205,6 +212,8 @@ public:
int get_surface_count() const;
void surface_remove(int p_idx);
+ void clear_surfaces();
+
void surface_set_custom_aabb(int p_idx, const AABB &p_aabb); //only recognized by driver
int surface_get_array_len(int p_idx) const;
@@ -220,8 +229,6 @@ public:
void surface_set_name(int p_idx, const String &p_name);
String surface_get_name(int p_idx) const;
- void add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data);
-
void set_custom_aabb(const AABB &p_custom);
AABB get_custom_aabb() const;
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index 754cad4def..ac016bec5d 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -104,7 +104,7 @@ void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::ARRAY, name + "shapes"));
p_list->push_back(PropertyInfo(Variant::OBJECT, name + "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"));
p_list->push_back(PropertyInfo(Variant::TRANSFORM, name + "navmesh_transform"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, name + "preview", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, name + "preview", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER));
}
}
@@ -162,7 +162,7 @@ void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_tran
_change_notify();
}
-void MeshLibrary::set_item_preview(int p_item, const Ref<Texture> &p_preview) {
+void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].preview = p_preview;
@@ -200,14 +200,14 @@ Transform MeshLibrary::get_item_navmesh_transform(int p_item) const {
return item_map[p_item].navmesh_transform;
}
-Ref<Texture> MeshLibrary::get_item_preview(int p_item) const {
+Ref<Texture2D> MeshLibrary::get_item_preview(int p_item) const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_PRINT("MeshLibrary item previews are only generated in an editor context, which means they aren't available in a running project.");
- return Ref<Texture>();
+ return Ref<Texture2D>();
}
- ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Texture>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
+ ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Texture2D>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].preview;
}
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index 471db74175..9155975f47 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -34,7 +34,7 @@
#include "core/map.h"
#include "core/resource.h"
#include "mesh.h"
-#include "scene/3d/navigation_mesh.h"
+#include "scene/3d/navigation_mesh_instance.h"
#include "shape.h"
class MeshLibrary : public Resource {
@@ -51,7 +51,7 @@ public:
String name;
Ref<Mesh> mesh;
Vector<ShapeData> shapes;
- Ref<Texture> preview;
+ Ref<Texture2D> preview;
Transform navmesh_transform;
Ref<NavigationMesh> navmesh;
};
@@ -75,13 +75,13 @@ public:
void set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh);
void set_item_navmesh_transform(int p_item, const Transform &p_transform);
void set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes);
- void set_item_preview(int p_item, const Ref<Texture> &p_preview);
+ void set_item_preview(int p_item, const Ref<Texture2D> &p_preview);
String get_item_name(int p_item) const;
Ref<Mesh> get_item_mesh(int p_item) const;
Ref<NavigationMesh> get_item_navmesh(int p_item) const;
Transform get_item_navmesh_transform(int p_item) const;
Vector<ShapeData> get_item_shapes(int p_item) const;
- Ref<Texture> get_item_preview(int p_item) const;
+ Ref<Texture2D> get_item_preview(int p_item) const;
void remove_item(int p_item);
bool has_item(int p_item) const;
diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp
index ee831f36f5..9c34ae0504 100644
--- a/scene/resources/multimesh.cpp
+++ b/scene/resources/multimesh.cpp
@@ -29,8 +29,12 @@
/*************************************************************************/
#include "multimesh.h"
+
#include "servers/visual_server.h"
+#ifndef DISABLE_DEPRECATED
+// Kept for compatibility from 3.x to 4.0.
+
void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) {
if (transform_format != TRANSFORM_3D)
return;
@@ -146,7 +150,7 @@ void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) {
PoolVector<Color> MultiMesh::_get_color_array() const {
- if (instance_count == 0 || color_format == COLOR_NONE)
+ if (instance_count == 0 || !use_colors)
return PoolVector<Color>();
PoolVector<Color> colors;
@@ -178,7 +182,7 @@ void MultiMesh::_set_custom_data_array(const PoolVector<Color> &p_array) {
PoolVector<Color> MultiMesh::_get_custom_data_array() const {
- if (instance_count == 0 || custom_data_format == CUSTOM_DATA_NONE)
+ if (instance_count == 0 || !use_custom_data)
return PoolVector<Color>();
PoolVector<Color> custom_datas;
@@ -191,6 +195,16 @@ PoolVector<Color> MultiMesh::_get_custom_data_array() const {
return custom_datas;
}
+#endif // DISABLE_DEPRECATED
+
+void MultiMesh::set_buffer(const PoolVector<float> &p_buffer) {
+ VS::get_singleton()->multimesh_set_buffer(multimesh, p_buffer);
+}
+
+PoolVector<float> MultiMesh::get_buffer() const {
+ return VS::get_singleton()->multimesh_get_buffer(multimesh);
+}
+
void MultiMesh::set_mesh(const Ref<Mesh> &p_mesh) {
mesh = p_mesh;
@@ -207,7 +221,7 @@ Ref<Mesh> MultiMesh::get_mesh() const {
void MultiMesh::set_instance_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
- VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), VS::MultimeshColorFormat(color_format), VS::MultimeshCustomDataFormat(custom_data_format));
+ VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data);
instance_count = p_count;
}
int MultiMesh::get_instance_count() const {
@@ -217,6 +231,7 @@ int MultiMesh::get_instance_count() const {
void MultiMesh::set_visible_instance_count(int p_count) {
ERR_FAIL_COND(p_count < -1);
+ ERR_FAIL_COND(p_count > instance_count);
VisualServer::get_singleton()->multimesh_set_visible_instances(multimesh, p_count);
visible_instance_count = p_count;
}
@@ -263,11 +278,6 @@ Color MultiMesh::get_instance_custom_data(int p_instance) const {
return VisualServer::get_singleton()->multimesh_instance_get_custom_data(multimesh, p_instance);
}
-void MultiMesh::set_as_bulk_array(const PoolVector<float> &p_array) {
-
- VisualServer::get_singleton()->multimesh_set_as_bulk_array(multimesh, p_array);
-}
-
AABB MultiMesh::get_aabb() const {
return VisualServer::get_singleton()->multimesh_get_aabb(multimesh);
@@ -278,26 +288,22 @@ RID MultiMesh::get_rid() const {
return multimesh;
}
-void MultiMesh::set_color_format(ColorFormat p_color_format) {
-
+void MultiMesh::set_use_colors(bool p_enable) {
ERR_FAIL_COND(instance_count > 0);
- color_format = p_color_format;
+ use_colors = p_enable;
}
-MultiMesh::ColorFormat MultiMesh::get_color_format() const {
-
- return color_format;
+bool MultiMesh::is_using_colors() const {
+ return use_colors;
}
-void MultiMesh::set_custom_data_format(CustomDataFormat p_custom_data_format) {
-
+void MultiMesh::set_use_custom_data(bool p_enable) {
ERR_FAIL_COND(instance_count > 0);
- custom_data_format = p_custom_data_format;
+ use_custom_data = p_enable;
}
-MultiMesh::CustomDataFormat MultiMesh::get_custom_data_format() const {
-
- return custom_data_format;
+bool MultiMesh::is_using_custom_data() const {
+ return use_custom_data;
}
void MultiMesh::set_transform_format(TransformFormat p_transform_format) {
@@ -314,10 +320,10 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MultiMesh::set_mesh);
ClassDB::bind_method(D_METHOD("get_mesh"), &MultiMesh::get_mesh);
- ClassDB::bind_method(D_METHOD("set_color_format", "format"), &MultiMesh::set_color_format);
- ClassDB::bind_method(D_METHOD("get_color_format"), &MultiMesh::get_color_format);
- ClassDB::bind_method(D_METHOD("set_custom_data_format", "format"), &MultiMesh::set_custom_data_format);
- ClassDB::bind_method(D_METHOD("get_custom_data_format"), &MultiMesh::get_custom_data_format);
+ ClassDB::bind_method(D_METHOD("set_use_colors", "enable"), &MultiMesh::set_use_colors);
+ ClassDB::bind_method(D_METHOD("is_using_colors"), &MultiMesh::is_using_colors);
+ ClassDB::bind_method(D_METHOD("set_use_custom_data", "enable"), &MultiMesh::set_use_custom_data);
+ ClassDB::bind_method(D_METHOD("is_using_custom_data"), &MultiMesh::is_using_custom_data);
ClassDB::bind_method(D_METHOD("set_transform_format", "format"), &MultiMesh::set_transform_format);
ClassDB::bind_method(D_METHOD("get_transform_format"), &MultiMesh::get_transform_format);
@@ -333,9 +339,21 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_instance_color", "instance"), &MultiMesh::get_instance_color);
ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data);
ClassDB::bind_method(D_METHOD("get_instance_custom_data", "instance"), &MultiMesh::get_instance_custom_data);
- ClassDB::bind_method(D_METHOD("set_as_bulk_array", "array"), &MultiMesh::set_as_bulk_array);
ClassDB::bind_method(D_METHOD("get_aabb"), &MultiMesh::get_aabb);
+ ClassDB::bind_method(D_METHOD("get_buffer"), &MultiMesh::get_buffer);
+ ClassDB::bind_method(D_METHOD("set_buffer", "buffer"), &MultiMesh::set_buffer);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_colors"), "set_use_colors", "is_using_colors");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_custom_data"), "set_use_custom_data", "is_using_custom_data");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "buffer", PROPERTY_HINT_NONE), "set_buffer", "get_buffer");
+
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
ClassDB::bind_method(D_METHOD("_set_transform_array"), &MultiMesh::_set_transform_array);
ClassDB::bind_method(D_METHOD("_get_transform_array"), &MultiMesh::_get_transform_array);
ClassDB::bind_method(D_METHOD("_set_transform_2d_array"), &MultiMesh::_set_transform_2d_array);
@@ -345,34 +363,21 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_custom_data_array"), &MultiMesh::_set_custom_data_array);
ClassDB::bind_method(D_METHOD("_get_custom_data_array"), &MultiMesh::_get_custom_data_array);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "color_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_color_format", "get_color_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_custom_data_format", "get_custom_data_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_array", "_get_transform_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "transform_2d_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_2d_array", "_get_transform_2d_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_color_array", "_get_color_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_custom_data_array", "_get_custom_data_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", 0), "_set_transform_array", "_get_transform_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "transform_2d_array", PROPERTY_HINT_NONE, "", 0), "_set_transform_2d_array", "_get_transform_2d_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", 0), "_set_color_array", "_get_color_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", 0), "_set_custom_data_array", "_get_custom_data_array");
+#endif
BIND_ENUM_CONSTANT(TRANSFORM_2D);
BIND_ENUM_CONSTANT(TRANSFORM_3D);
-
- BIND_ENUM_CONSTANT(COLOR_NONE);
- BIND_ENUM_CONSTANT(COLOR_8BIT);
- BIND_ENUM_CONSTANT(COLOR_FLOAT);
-
- BIND_ENUM_CONSTANT(CUSTOM_DATA_NONE);
- BIND_ENUM_CONSTANT(CUSTOM_DATA_8BIT);
- BIND_ENUM_CONSTANT(CUSTOM_DATA_FLOAT);
}
MultiMesh::MultiMesh() {
multimesh = VisualServer::get_singleton()->multimesh_create();
- color_format = COLOR_NONE;
- custom_data_format = CUSTOM_DATA_NONE;
+ use_colors = false;
+ use_custom_data = false;
transform_format = TRANSFORM_2D;
visible_instance_count = -1;
instance_count = 0;
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index 9394737799..5423e66358 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -45,30 +45,20 @@ public:
TRANSFORM_3D = VS::MULTIMESH_TRANSFORM_3D
};
- enum ColorFormat {
- COLOR_NONE = VS::MULTIMESH_COLOR_NONE,
- COLOR_8BIT = VS::MULTIMESH_COLOR_8BIT,
- COLOR_FLOAT = VS::MULTIMESH_COLOR_FLOAT,
- };
-
- enum CustomDataFormat {
- CUSTOM_DATA_NONE,
- CUSTOM_DATA_8BIT,
- CUSTOM_DATA_FLOAT,
- };
-
private:
Ref<Mesh> mesh;
RID multimesh;
TransformFormat transform_format;
- ColorFormat color_format;
- CustomDataFormat custom_data_format;
+ bool use_colors;
+ bool use_custom_data;
int instance_count;
int visible_instance_count;
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ // Kept for compatibility from 3.x to 4.0.
void _set_transform_array(const PoolVector<Vector3> &p_array);
PoolVector<Vector3> _get_transform_array() const;
@@ -80,16 +70,19 @@ protected:
void _set_custom_data_array(const PoolVector<Color> &p_array);
PoolVector<Color> _get_custom_data_array() const;
+#endif
+ void set_buffer(const PoolVector<float> &p_buffer);
+ PoolVector<float> get_buffer() const;
public:
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
- void set_color_format(ColorFormat p_color_format);
- ColorFormat get_color_format() const;
+ void set_use_colors(bool p_enable);
+ bool is_using_colors() const;
- void set_custom_data_format(CustomDataFormat p_custom_data_format);
- CustomDataFormat get_custom_data_format() const;
+ void set_use_custom_data(bool p_enable);
+ bool is_using_custom_data() const;
void set_transform_format(TransformFormat p_transform_format);
TransformFormat get_transform_format() const;
@@ -111,8 +104,6 @@ public:
void set_instance_custom_data(int p_instance, const Color &p_custom_data);
Color get_instance_custom_data(int p_instance) const;
- void set_as_bulk_array(const PoolVector<float> &p_array);
-
virtual AABB get_aabb() const;
virtual RID get_rid() const;
@@ -122,7 +113,5 @@ public:
};
VARIANT_ENUM_CAST(MultiMesh::TransformFormat);
-VARIANT_ENUM_CAST(MultiMesh::ColorFormat);
-VARIANT_ENUM_CAST(MultiMesh::CustomDataFormat);
#endif // MULTI_MESH_H
diff --git a/scene/3d/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp
index aaba91125e..e6544778bc 100644
--- a/scene/3d/navigation_mesh.cpp
+++ b/scene/resources/navigation_mesh.cpp
@@ -29,8 +29,6 @@
/*************************************************************************/
#include "navigation_mesh.h"
-#include "mesh_instance.h"
-#include "navigation.h"
void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
@@ -548,197 +546,3 @@ NavigationMesh::NavigationMesh() {
filter_ledge_spans = false;
filter_walkable_low_height_spans = false;
}
-
-void NavigationMeshInstance::set_enabled(bool p_enabled) {
-
- if (enabled == p_enabled)
- return;
- enabled = p_enabled;
-
- if (!is_inside_tree())
- return;
-
- if (!enabled) {
-
- if (nav_id != -1) {
- navigation->navmesh_remove(nav_id);
- nav_id = -1;
- }
- } else {
-
- if (navigation) {
-
- if (navmesh.is_valid()) {
-
- nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this);
- }
- }
- }
-
- if (debug_view) {
- MeshInstance *dm = Object::cast_to<MeshInstance>(debug_view);
- if (is_enabled()) {
- dm->set_material_override(get_tree()->get_debug_navigation_material());
- } else {
- dm->set_material_override(get_tree()->get_debug_navigation_disabled_material());
- }
- }
-
- update_gizmo();
-}
-
-bool NavigationMeshInstance::is_enabled() const {
-
- return enabled;
-}
-
-/////////////////////////////
-
-void NavigationMeshInstance::_notification(int p_what) {
-
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
-
- Spatial *c = this;
- while (c) {
-
- navigation = Object::cast_to<Navigation>(c);
- if (navigation) {
-
- if (enabled && navmesh.is_valid()) {
-
- nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this);
- }
- break;
- }
-
- c = c->get_parent_spatial();
- }
-
- if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
-
- MeshInstance *dm = memnew(MeshInstance);
- dm->set_mesh(navmesh->get_debug_mesh());
- if (is_enabled()) {
- dm->set_material_override(get_tree()->get_debug_navigation_material());
- } else {
- dm->set_material_override(get_tree()->get_debug_navigation_disabled_material());
- }
- add_child(dm);
- debug_view = dm;
- }
-
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
-
- if (navigation && nav_id != -1) {
- navigation->navmesh_set_transform(nav_id, get_relative_transform(navigation));
- }
-
- } break;
- case NOTIFICATION_EXIT_TREE: {
-
- if (navigation) {
-
- if (nav_id != -1) {
- navigation->navmesh_remove(nav_id);
- nav_id = -1;
- }
- }
-
- if (debug_view) {
- debug_view->queue_delete();
- debug_view = NULL;
- }
- navigation = NULL;
- } break;
- }
-}
-
-void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh) {
-
- if (p_navmesh == navmesh)
- return;
-
- if (navigation && nav_id != -1) {
- navigation->navmesh_remove(nav_id);
- nav_id = -1;
- }
-
- if (navmesh.is_valid()) {
- navmesh->remove_change_receptor(this);
- }
-
- navmesh = p_navmesh;
-
- if (navmesh.is_valid()) {
- navmesh->add_change_receptor(this);
- }
-
- if (navigation && navmesh.is_valid() && enabled) {
- nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this);
- }
-
- if (debug_view && navmesh.is_valid()) {
- Object::cast_to<MeshInstance>(debug_view)->set_mesh(navmesh->get_debug_mesh());
- }
-
- update_gizmo();
- update_configuration_warning();
-}
-
-Ref<NavigationMesh> NavigationMeshInstance::get_navigation_mesh() const {
-
- return navmesh;
-}
-
-String NavigationMeshInstance::get_configuration_warning() const {
-
- if (!is_visible_in_tree() || !is_inside_tree())
- return String();
-
- if (!navmesh.is_valid()) {
- return TTR("A NavigationMesh resource must be set or created for this node to work.");
- }
- const Spatial *c = this;
- while (c) {
-
- if (Object::cast_to<Navigation>(c))
- return String();
-
- c = Object::cast_to<Spatial>(c->get_parent());
- }
-
- return TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data.");
-}
-
-void NavigationMeshInstance::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationMeshInstance::set_navigation_mesh);
- ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationMeshInstance::get_navigation_mesh);
-
- ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationMeshInstance::set_enabled);
- ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationMeshInstance::is_enabled);
-
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
-}
-
-void NavigationMeshInstance::_changed_callback(Object *p_changed, const char *p_prop) {
- update_gizmo();
- update_configuration_warning();
-}
-
-NavigationMeshInstance::NavigationMeshInstance() {
-
- debug_view = NULL;
- navigation = NULL;
- nav_id = -1;
- enabled = true;
- set_notify_transform(true);
-}
-
-NavigationMeshInstance::~NavigationMeshInstance() {
- if (navmesh.is_valid())
- navmesh->remove_change_receptor(this);
-}
diff --git a/scene/3d/navigation_mesh.h b/scene/resources/navigation_mesh.h
index f9ab911bea..a2b1c62eab 100644
--- a/scene/3d/navigation_mesh.h
+++ b/scene/resources/navigation_mesh.h
@@ -31,7 +31,6 @@
#ifndef NAVIGATION_MESH_H
#define NAVIGATION_MESH_H
-#include "scene/3d/spatial.h"
#include "scene/resources/mesh.h"
class Mesh;
@@ -193,35 +192,4 @@ public:
NavigationMesh();
};
-class Navigation;
-
-class NavigationMeshInstance : public Spatial {
-
- GDCLASS(NavigationMeshInstance, Spatial);
-
- bool enabled;
- int nav_id;
- Navigation *navigation;
- Ref<NavigationMesh> navmesh;
-
- Node *debug_view;
-
-protected:
- void _notification(int p_what);
- static void _bind_methods();
- void _changed_callback(Object *p_changed, const char *p_prop);
-
-public:
- void set_enabled(bool p_enabled);
- bool is_enabled() const;
-
- void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh);
- Ref<NavigationMesh> get_navigation_mesh() const;
-
- String get_configuration_warning() const;
-
- NavigationMeshInstance();
- ~NavigationMeshInstance();
-};
-
#endif // NAVIGATION_MESH_H
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index 412b5c259c..d852dca7fa 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -316,14 +316,17 @@ void ParticlesMaterial::_update_shader() {
if (flags[FLAG_DISABLE_Z]) {
- code += " float angle1_rad = atan(direction.y, direction.x) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
+ code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
+ code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n";
code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n";
code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
} else {
//initiate velocity spread in 3D
- code += " float angle1_rad = atan(direction.x, direction.z) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
- code += " float angle2_rad = atan(direction.y, abs(direction.z)) + rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n";
+ code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
+ code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n";
+ code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n";
+ code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n";
code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n";
code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n";
code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n";
@@ -787,7 +790,7 @@ float ParticlesMaterial::get_param_randomness(Parameter p_param) const {
return randomness[p_param];
}
-static void _adjust_curve_range(const Ref<Texture> &p_texture, float p_min, float p_max) {
+static void _adjust_curve_range(const Ref<Texture2D> &p_texture, float p_min, float p_max) {
Ref<CurveTexture> curve_tex = p_texture;
if (!curve_tex.is_valid())
@@ -796,7 +799,7 @@ static void _adjust_curve_range(const Ref<Texture> &p_texture, float p_min, floa
curve_tex->ensure_default_setup(p_min, p_max);
}
-void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture> &p_texture) {
+void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
@@ -854,9 +857,9 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture>
_queue_shader_change();
}
-Ref<Texture> ParticlesMaterial::get_param_texture(Parameter p_param) const {
+Ref<Texture2D> ParticlesMaterial::get_param_texture(Parameter p_param) const {
- ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture2D>());
return tex_parameters[p_param];
}
@@ -872,7 +875,7 @@ Color ParticlesMaterial::get_color() const {
return color;
}
-void ParticlesMaterial::set_color_ramp(const Ref<Texture> &p_texture) {
+void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) {
color_ramp = p_texture;
VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture);
@@ -880,7 +883,7 @@ void ParticlesMaterial::set_color_ramp(const Ref<Texture> &p_texture) {
_change_notify();
}
-Ref<Texture> ParticlesMaterial::get_color_ramp() const {
+Ref<Texture2D> ParticlesMaterial::get_color_ramp() const {
return color_ramp;
}
@@ -918,19 +921,19 @@ void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) {
VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_box_extents, p_extents);
}
-void ParticlesMaterial::set_emission_point_texture(const Ref<Texture> &p_points) {
+void ParticlesMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) {
emission_point_texture = p_points;
VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, p_points);
}
-void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture> &p_normals) {
+void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) {
emission_normal_texture = p_normals;
VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, p_normals);
}
-void ParticlesMaterial::set_emission_color_texture(const Ref<Texture> &p_colors) {
+void ParticlesMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) {
emission_color_texture = p_colors;
VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, p_colors);
@@ -956,16 +959,16 @@ Vector3 ParticlesMaterial::get_emission_box_extents() const {
return emission_box_extents;
}
-Ref<Texture> ParticlesMaterial::get_emission_point_texture() const {
+Ref<Texture2D> ParticlesMaterial::get_emission_point_texture() const {
return emission_point_texture;
}
-Ref<Texture> ParticlesMaterial::get_emission_normal_texture() const {
+Ref<Texture2D> ParticlesMaterial::get_emission_normal_texture() const {
return emission_normal_texture;
}
-Ref<Texture> ParticlesMaterial::get_emission_color_texture() const {
+Ref<Texture2D> ParticlesMaterial::get_emission_color_texture() const {
return emission_color_texture;
}
@@ -1159,9 +1162,9 @@ void ParticlesMaterial::_bind_methods() {
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,or_greater"), "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::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_color_texture", "get_emission_color_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_point_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_point_texture", "get_emission_point_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_normal_texture", "get_emission_normal_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_color_texture", "get_emission_color_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);
diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h
index cc860b3812..246ce58a21 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -205,18 +205,18 @@ private:
float parameters[PARAM_MAX];
float randomness[PARAM_MAX];
- Ref<Texture> tex_parameters[PARAM_MAX];
+ Ref<Texture2D> tex_parameters[PARAM_MAX];
Color color;
- Ref<Texture> color_ramp;
+ Ref<Texture2D> 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;
- Ref<Texture> emission_color_texture;
+ Ref<Texture2D> emission_point_texture;
+ Ref<Texture2D> emission_normal_texture;
+ Ref<Texture2D> emission_color_texture;
int emission_point_count;
bool anim_loop;
@@ -252,14 +252,14 @@ public:
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_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> 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_color_ramp(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_color_ramp() const;
void set_flag(Flags p_flag, bool p_enable);
bool get_flag(Flags p_flag) const;
@@ -267,17 +267,17 @@ public:
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_color_texture(const Ref<Texture> &p_colors);
+ void set_emission_point_texture(const Ref<Texture2D> &p_points);
+ void set_emission_normal_texture(const Ref<Texture2D> &p_normals);
+ void set_emission_color_texture(const Ref<Texture2D> &p_colors);
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;
- Ref<Texture> get_emission_color_texture() const;
+ Ref<Texture2D> get_emission_point_texture() const;
+ Ref<Texture2D> get_emission_normal_texture() const;
+ Ref<Texture2D> get_emission_color_texture() const;
int get_emission_point_count() const;
void set_trail_divisor(int p_divisor);
diff --git a/scene/resources/plane_shape.h b/scene/resources/plane_shape.h
index 8bea1268e5..360f9dbbe9 100644
--- a/scene/resources/plane_shape.h
+++ b/scene/resources/plane_shape.h
@@ -47,6 +47,10 @@ public:
Plane get_plane() const;
virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const {
+ // Should be infinite?
+ return 0;
+ }
PlaneShape();
};
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 74df72619a..fa0ded12a1 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -57,9 +57,11 @@ void PrimitiveMesh::_update() const {
}
}
+ PoolVector<int> indices = arr[VS::ARRAY_INDEX];
+
if (flip_faces) {
PoolVector<Vector3> normals = arr[VS::ARRAY_NORMAL];
- PoolVector<int> indices = arr[VS::ARRAY_INDEX];
+
if (normals.size() && indices.size()) {
{
@@ -82,6 +84,8 @@ void PrimitiveMesh::_update() const {
}
}
+ array_len = pc;
+ index_array_len = indices.size();
// in with the new
VisualServer::get_singleton()->mesh_clear(mesh);
VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr);
@@ -114,7 +118,7 @@ int PrimitiveMesh::surface_get_array_len(int p_idx) const {
_update();
}
- return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, 0);
+ return array_len;
}
int PrimitiveMesh::surface_get_array_index_len(int p_idx) const {
@@ -123,7 +127,7 @@ int PrimitiveMesh::surface_get_array_index_len(int p_idx) const {
_update();
}
- return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, 0);
+ return index_array_len;
}
Array PrimitiveMesh::surface_get_arrays(int p_surface) const {
@@ -135,22 +139,18 @@ Array PrimitiveMesh::surface_get_arrays(int p_surface) const {
return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0);
}
+Dictionary PrimitiveMesh::surface_get_lods(int p_surface) const {
+ return Dictionary(); //not really supported
+}
Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const {
- ERR_FAIL_INDEX_V(p_surface, 1, Array());
- if (pending_request) {
- _update();
- }
- return Array();
+ return Array(); //not really supported
}
uint32_t PrimitiveMesh::surface_get_format(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, 1, 0);
- if (pending_request) {
- _update();
- }
- return VisualServer::get_singleton()->mesh_surface_get_format(mesh, 0);
+ return VS::ARRAY_COMPRESS_DEFAULT;
}
Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const {
@@ -206,7 +206,7 @@ void PrimitiveMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flip_faces", "flip_faces"), &PrimitiveMesh::set_flip_faces);
ClassDB::bind_method(D_METHOD("get_flip_faces"), &PrimitiveMesh::get_flip_faces);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces");
}
@@ -261,6 +261,9 @@ PrimitiveMesh::PrimitiveMesh() {
// make sure we do an update after we've finished constructing our object
pending_request = true;
+
+ array_len = 0;
+ index_array_len = 0;
}
PrimitiveMesh::~PrimitiveMesh() {
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 47126f1862..5f17680c9e 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -50,6 +50,9 @@ private:
mutable AABB aabb;
AABB custom_aabb;
+ mutable int array_len;
+ mutable int index_array_len;
+
Ref<Material> material;
bool flip_faces;
@@ -70,6 +73,7 @@ public:
virtual int surface_get_array_index_len(int p_idx) const;
virtual Array surface_get_arrays(int p_surface) const;
virtual Array surface_get_blend_shape_arrays(int p_surface) const;
+ virtual Dictionary surface_get_lods(int p_surface) const;
virtual uint32_t surface_get_format(int p_idx) const;
virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const;
virtual void surface_set_material(int p_idx, const Ref<Material> &p_material);
diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp
index 3062e96293..1a9b7e6dd2 100644
--- a/scene/resources/ray_shape.cpp
+++ b/scene/resources/ray_shape.cpp
@@ -41,6 +41,10 @@ Vector<Vector3> RayShape::get_debug_mesh_lines() {
return points;
}
+real_t RayShape::get_enclosing_radius() const {
+ return length;
+}
+
void RayShape::_update_shape() {
Dictionary d;
diff --git a/scene/resources/ray_shape.h b/scene/resources/ray_shape.h
index ddf9f56ea3..c89705ad7d 100644
--- a/scene/resources/ray_shape.h
+++ b/scene/resources/ray_shape.h
@@ -50,6 +50,7 @@ public:
bool get_slips_on_slope() const;
virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const;
RayShape();
};
diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp
index 0030e6dd4f..f8c8ffb289 100644
--- a/scene/resources/rectangle_shape_2d.cpp
+++ b/scene/resources/rectangle_shape_2d.cpp
@@ -59,6 +59,10 @@ Rect2 RectangleShape2D::get_rect() const {
return Rect2(-extents, extents * 2.0);
}
+real_t RectangleShape2D::get_enclosing_radius() const {
+ return extents.length();
+}
+
void RectangleShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &RectangleShape2D::set_extents);
diff --git a/scene/resources/rectangle_shape_2d.h b/scene/resources/rectangle_shape_2d.h
index 686b421a2a..68fc539085 100644
--- a/scene/resources/rectangle_shape_2d.h
+++ b/scene/resources/rectangle_shape_2d.h
@@ -48,6 +48,7 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
RectangleShape2D();
};
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index eb05defddd..a5475776a7 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -1281,7 +1281,7 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
ria->res_path = ria->local_path;
//ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) );
String r = ria->recognize(f);
- return r;
+ return ClassDB::get_compatibility_remapped_class(r);
}
void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
@@ -1377,14 +1377,14 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
switch (p_variant.get_type()) {
case Variant::OBJECT: {
- RES res = p_variant.operator RefPtr();
+ RES res = p_variant;
if (res.is_null() || external_resources.has(res))
return;
if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
if (res->get_path() == local_path) {
- ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded.");
+ ERR_PRINT("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded.");
return;
}
int index = external_resources.size();
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index 0070de72a2..3094d0f9bd 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -82,6 +82,10 @@ Rect2 SegmentShape2D::get_rect() const {
return rect;
}
+real_t SegmentShape2D::get_enclosing_radius() const {
+ return (a + b).length();
+}
+
void SegmentShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_a", "a"), &SegmentShape2D::set_a);
@@ -138,6 +142,10 @@ Rect2 RayShape2D::get_rect() const {
return rect;
}
+real_t RayShape2D::get_enclosing_radius() const {
+ return length;
+}
+
void RayShape2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length);
diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h
index aaf838ebfb..ca10c24f07 100644
--- a/scene/resources/segment_shape_2d.h
+++ b/scene/resources/segment_shape_2d.h
@@ -55,6 +55,7 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
SegmentShape2D();
};
@@ -79,6 +80,7 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
RayShape2D();
};
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 44c2a46065..79cb9754df 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -98,7 +98,7 @@ RID Shader::get_rid() const {
return shader;
}
-void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture> &p_texture) {
+void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture) {
if (p_texture.is_valid()) {
default_textures[p_param] = p_texture;
@@ -111,17 +111,17 @@ void Shader::set_default_texture_param(const StringName &p_param, const Ref<Text
emit_changed();
}
-Ref<Texture> Shader::get_default_texture_param(const StringName &p_param) const {
+Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param) const {
if (default_textures.has(p_param))
return default_textures[p_param];
else
- return Ref<Texture>();
+ return Ref<Texture2D>();
}
void Shader::get_default_texture_param_list(List<StringName> *r_textures) const {
- for (const Map<StringName, Ref<Texture> >::Element *E = default_textures.front(); E; E = E->next()) {
+ for (const Map<StringName, Ref<Texture2D> >::Element *E = default_textures.front(); E; E = E->next()) {
r_textures->push_back(E->key());
}
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index 67ae436a4c..702e58aedc 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -59,7 +59,7 @@ private:
// conversion fast and save memory.
mutable bool params_cache_dirty;
mutable Map<StringName, StringName> params_cache; //map a shader param to a material param..
- Map<StringName, Ref<Texture> > default_textures;
+ Map<StringName, Ref<Texture2D> > default_textures;
virtual void _update_shader() const; //used for visual shader
protected:
@@ -75,8 +75,8 @@ public:
void get_param_list(List<PropertyInfo> *p_params) const;
bool has_param(const StringName &p_param) const;
- void set_default_texture_param(const StringName &p_param, const Ref<Texture> &p_texture);
- Ref<Texture> get_default_texture_param(const StringName &p_param) const;
+ void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_default_texture_param(const StringName &p_param) const;
void get_default_texture_param_list(List<StringName> *r_textures) const;
virtual bool is_text_shader() const;
diff --git a/scene/resources/shape.h b/scene/resources/shape.h
index 8fc265f3bc..227a581c96 100644
--- a/scene/resources/shape.h
+++ b/scene/resources/shape.h
@@ -32,6 +32,7 @@
#define SHAPE_H
#include "core/resource.h"
+
class ArrayMesh;
class Shape : public Resource {
@@ -57,6 +58,8 @@ public:
Ref<ArrayMesh> get_debug_mesh();
virtual Vector<Vector3> get_debug_mesh_lines() = 0; // { return Vector<Vector3>(); }
+ /// Returns the radius of a sphere that fully enclose this shape
+ virtual real_t get_enclosing_radius() const = 0;
void add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform);
diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h
index 13ad7492ae..e2933ec031 100644
--- a/scene/resources/shape_2d.h
+++ b/scene/resources/shape_2d.h
@@ -58,6 +58,8 @@ public:
virtual void draw(const RID &p_to_rid, const Color &p_color) {}
virtual Rect2 get_rect() const { return Rect2(); }
+ /// Returns the radius of a circle that fully enclose this shape
+ virtual real_t get_enclosing_radius() const = 0;
virtual RID get_rid() const;
Shape2D();
~Shape2D();
diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp
index c20fbb4129..3e797a7bde 100644
--- a/scene/resources/sky.cpp
+++ b/scene/resources/sky.cpp
@@ -36,7 +36,10 @@ void Sky::set_radiance_size(RadianceSize p_size) {
ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX);
radiance_size = p_size;
- _radiance_changed();
+ static const int size[RADIANCE_SIZE_MAX] = {
+ 32, 64, 128, 256, 512, 1024, 2048
+ };
+ VS::get_singleton()->sky_set_radiance_size(sky, size[radiance_size]);
}
Sky::RadianceSize Sky::get_radiance_size() const {
@@ -44,12 +47,30 @@ Sky::RadianceSize Sky::get_radiance_size() const {
return radiance_size;
}
+void Sky::set_process_mode(ProcessMode p_mode) {
+ mode = p_mode;
+ VS::get_singleton()->sky_set_mode(sky, VS::SkyMode(mode));
+}
+
+Sky::ProcessMode Sky::get_process_mode() const {
+ return mode;
+}
+
+RID Sky::get_rid() const {
+
+ return sky;
+}
+
void Sky::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size);
ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size);
+ ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Sky::set_process_mode);
+ ClassDB::bind_method(D_METHOD("get_process_mode"), &Sky::get_process_mode);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "HighQuality,RealTime"), "set_process_mode", "get_process_mode");
BIND_ENUM_CONSTANT(RADIANCE_SIZE_32);
BIND_ENUM_CONSTANT(RADIANCE_SIZE_64);
@@ -59,77 +80,52 @@ void Sky::_bind_methods() {
BIND_ENUM_CONSTANT(RADIANCE_SIZE_1024);
BIND_ENUM_CONSTANT(RADIANCE_SIZE_2048);
BIND_ENUM_CONSTANT(RADIANCE_SIZE_MAX);
+
+ BIND_ENUM_CONSTANT(PROCESS_MODE_QUALITY);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_REALTIME);
}
Sky::Sky() {
+ mode = PROCESS_MODE_QUALITY;
radiance_size = RADIANCE_SIZE_128;
+ sky = VS::get_singleton()->sky_create();
}
-/////////////////////////////////////////
-
-void PanoramaSky::_radiance_changed() {
+Sky::~Sky() {
- if (panorama.is_valid()) {
- static const int size[RADIANCE_SIZE_MAX] = {
- 32, 64, 128, 256, 512, 1024, 2048
- };
- VS::get_singleton()->sky_set_texture(sky, panorama->get_rid(), size[get_radiance_size()]);
- }
+ VS::get_singleton()->free(sky);
}
-void PanoramaSky::set_panorama(const Ref<Texture> &p_panorama) {
-
- panorama = p_panorama;
+/////////////////////////////////////////
- if (panorama.is_valid()) {
+void PanoramaSky::set_panorama(const Ref<Texture2D> &p_panorama) {
- _radiance_changed();
+ panorama = p_panorama;
- } else {
- VS::get_singleton()->sky_set_texture(sky, RID(), 0);
- }
+ RID rid = p_panorama.is_valid() ? p_panorama->get_rid() : RID();
+ VS::get_singleton()->sky_set_texture(get_rid(), rid);
}
-Ref<Texture> PanoramaSky::get_panorama() const {
+Ref<Texture2D> PanoramaSky::get_panorama() const {
return panorama;
}
-RID PanoramaSky::get_rid() const {
-
- return sky;
-}
-
void PanoramaSky::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSky::set_panorama);
ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSky::get_panorama);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_panorama", "get_panorama");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama");
}
PanoramaSky::PanoramaSky() {
-
- sky = VS::get_singleton()->sky_create();
}
PanoramaSky::~PanoramaSky() {
-
- VS::get_singleton()->free(sky);
}
//////////////////////////////////
-void ProceduralSky::_radiance_changed() {
-
- if (update_queued)
- return; //do nothing yet
-
- static const int size[RADIANCE_SIZE_MAX] = {
- 32, 64, 128, 256, 512, 1024, 2048
- };
- VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]);
-}
-
Ref<Image> ProceduralSky::_generate_sky() {
update_queued = false;
@@ -390,10 +386,6 @@ ProceduralSky::TextureSize ProceduralSky::get_texture_size() const {
return texture_size;
}
-RID ProceduralSky::get_rid() const {
- return sky;
-}
-
void ProceduralSky::_update_sky() {
bool use_thread = true;
@@ -415,9 +407,13 @@ void ProceduralSky::_update_sky() {
} else {
Ref<Image> image = _generate_sky();
- VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
- VS::get_singleton()->texture_set_data(texture, image);
- _radiance_changed();
+ if (texture.is_valid()) {
+ RID new_texture = VS::get_singleton()->texture_2d_create(image);
+ VS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = VS::get_singleton()->texture_2d_create(image);
+ }
+ VS::get_singleton()->sky_set_texture(get_rid(), texture);
}
}
@@ -432,9 +428,15 @@ void ProceduralSky::_queue_update() {
void ProceduralSky::_thread_done(const Ref<Image> &p_image) {
- VS::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
- VS::get_singleton()->texture_set_data(texture, p_image);
- _radiance_changed();
+ if (texture.is_valid()) {
+ RID new_texture = VS::get_singleton()->texture_2d_create(p_image);
+ VS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = VS::get_singleton()->texture_2d_create(p_image);
+ }
+
+ VS::get_singleton()->sky_set_texture(get_rid(), texture);
+
Thread::wait_to_finish(sky_thread);
memdelete(sky_thread);
sky_thread = NULL;
@@ -525,7 +527,7 @@ void ProceduralSky::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy");
- ADD_GROUP("Texture", "texture_");
+ ADD_GROUP("Texture2D", "texture_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096"), "set_texture_size", "get_texture_size");
BIND_ENUM_CONSTANT(TEXTURE_SIZE_256);
@@ -538,9 +540,6 @@ void ProceduralSky::_bind_methods() {
ProceduralSky::ProceduralSky(bool p_desaturate) {
- sky = VS::get_singleton()->sky_create();
- texture = VS::get_singleton()->texture_create();
-
update_queued = false;
sky_top_color = Color::hex(0xa5d6f1ff);
sky_horizon_color = Color::hex(0xd6eafaff);
@@ -581,6 +580,7 @@ ProceduralSky::~ProceduralSky() {
memdelete(sky_thread);
sky_thread = NULL;
}
- VS::get_singleton()->free(sky);
- VS::get_singleton()->free(texture);
+ if (texture.is_valid()) {
+ VS::get_singleton()->free(texture);
+ }
}
diff --git a/scene/resources/sky.h b/scene/resources/sky.h
index 70ea9c4c18..09ebbd88a0 100644
--- a/scene/resources/sky.h
+++ b/scene/resources/sky.h
@@ -49,37 +49,47 @@ public:
RADIANCE_SIZE_MAX
};
+ enum ProcessMode {
+ PROCESS_MODE_QUALITY,
+ PROCESS_MODE_REALTIME
+ };
+
private:
+ RID sky;
+ ProcessMode mode;
RadianceSize radiance_size;
protected:
static void _bind_methods();
- virtual void _radiance_changed() = 0;
public:
void set_radiance_size(RadianceSize p_size);
RadianceSize get_radiance_size() const;
+
+ void set_process_mode(ProcessMode p_mode);
+ ProcessMode get_process_mode() const;
+
+ virtual RID get_rid() const;
+
Sky();
+ ~Sky();
};
VARIANT_ENUM_CAST(Sky::RadianceSize)
+VARIANT_ENUM_CAST(Sky::ProcessMode)
class PanoramaSky : public Sky {
GDCLASS(PanoramaSky, Sky);
private:
- RID sky;
- Ref<Texture> panorama;
+ Ref<Texture2D> panorama;
protected:
static void _bind_methods();
- virtual void _radiance_changed();
public:
- void set_panorama(const Ref<Texture> &p_panorama);
- Ref<Texture> get_panorama() const;
-
- virtual RID get_rid() const;
+ void set_panorama(const Ref<Texture2D> &p_panorama);
+ Ref<Texture2D> get_panorama() const;
PanoramaSky();
~PanoramaSky();
@@ -120,7 +130,6 @@ private:
TextureSize texture_size;
- RID sky;
RID texture;
bool update_queued;
@@ -133,7 +142,6 @@ private:
protected:
static void _bind_methods();
- virtual void _radiance_changed();
Ref<Image> _generate_sky();
void _update_sky();
@@ -189,8 +197,6 @@ public:
void set_texture_size(TextureSize p_size);
TextureSize get_texture_size() const;
- virtual RID get_rid() const;
-
ProceduralSky(bool p_desaturate = false);
~ProceduralSky();
};
diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp
index f408717834..56121b6941 100644
--- a/scene/resources/sphere_shape.cpp
+++ b/scene/resources/sphere_shape.cpp
@@ -55,6 +55,10 @@ Vector<Vector3> SphereShape::get_debug_mesh_lines() {
return points;
}
+real_t SphereShape::get_enclosing_radius() const {
+ return radius;
+}
+
void SphereShape::_update_shape() {
PhysicsServer::get_singleton()->shape_set_data(get_shape(), radius);
diff --git a/scene/resources/sphere_shape.h b/scene/resources/sphere_shape.h
index 6002a3baeb..07e8f1e233 100644
--- a/scene/resources/sphere_shape.h
+++ b/scene/resources/sphere_shape.h
@@ -48,6 +48,7 @@ public:
float get_radius() const;
virtual Vector<Vector3> get_debug_mesh_lines();
+ virtual real_t get_enclosing_radius() const;
SphereShape();
};
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 9408d1aa71..1766b531d5 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -118,7 +118,7 @@ StyleBox::StyleBox() {
}
}
-void StyleBoxTexture::set_texture(Ref<Texture> p_texture) {
+void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) {
if (texture == p_texture)
return;
@@ -133,12 +133,12 @@ void StyleBoxTexture::set_texture(Ref<Texture> p_texture) {
_change_notify("texture");
}
-Ref<Texture> StyleBoxTexture::get_texture() const {
+Ref<Texture2D> StyleBoxTexture::get_texture() const {
return texture;
}
-void StyleBoxTexture::set_normal_map(Ref<Texture> p_normal_map) {
+void StyleBoxTexture::set_normal_map(Ref<Texture2D> p_normal_map) {
if (normal_map == p_normal_map)
return;
@@ -146,7 +146,7 @@ void StyleBoxTexture::set_normal_map(Ref<Texture> p_normal_map) {
emit_changed();
}
-Ref<Texture> StyleBoxTexture::get_normal_map() const {
+Ref<Texture2D> StyleBoxTexture::get_normal_map() const {
return normal_map;
}
@@ -335,8 +335,8 @@ void StyleBoxTexture::_bind_methods() {
ADD_SIGNAL(MethodInfo("texture_changed"));
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_GROUP("Margin", "margin_");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_LEFT);
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 3e0fffdcd9..1aa1a00c55 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -92,8 +92,8 @@ private:
float expand_margin[4];
float margin[4];
Rect2 region_rect;
- Ref<Texture> texture;
- Ref<Texture> normal_map;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
bool draw_center;
Color modulate;
AxisStretchMode axis_h;
@@ -115,11 +115,11 @@ public:
void set_region_rect(const Rect2 &p_region_rect);
Rect2 get_region_rect() const;
- void set_texture(Ref<Texture> p_texture);
- Ref<Texture> get_texture() const;
+ void set_texture(Ref<Texture2D> p_texture);
+ Ref<Texture2D> get_texture() const;
- void set_normal_map(Ref<Texture> p_normal_map);
- Ref<Texture> get_normal_map() const;
+ void set_normal_map(Ref<Texture2D> p_normal_map);
+ Ref<Texture2D> get_normal_map() const;
void set_draw_center(bool p_enabled);
bool is_draw_center_enabled() const;
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index f921a9695c..a1e6430255 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -466,7 +466,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_
Array a = commit_to_arrays();
- mesh->add_surface_from_arrays(primitive, a, Array(), p_flags);
+ mesh->add_surface_from_arrays(primitive, a, Array(), Dictionary(), p_flags);
if (material.is_valid())
mesh->surface_set_material(surface, material);
diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h
index 666c088d04..76c80ba509 100644
--- a/scene/resources/text_file.h
+++ b/scene/resources/text_file.h
@@ -36,8 +36,6 @@
class TextFile : public Resource {
- GDCLASS(TextFile, Resource);
-
private:
String text;
String path;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 4d23f0eb41..4ddceed58e 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -38,31 +38,37 @@
#include "scene/resources/bit_map.h"
#include "servers/camera/camera_feed.h"
-Size2 Texture::get_size() const {
+Size2 Texture2D::get_size() const {
return Size2(get_width(), get_height());
}
-bool Texture::is_pixel_opaque(int p_x, int p_y) const {
+bool Texture2D::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+
+void Texture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void Texture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+
+void Texture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+
+void Texture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
-bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
+bool Texture2D::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
r_rect = p_rect;
r_src_rect = p_src_rect;
@@ -70,34 +76,21 @@ bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect
return true;
}
-void Texture::_bind_methods() {
+void Texture2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_width"), &Texture::get_width);
- ClassDB::bind_method(D_METHOD("get_height"), &Texture::get_height);
- ClassDB::bind_method(D_METHOD("get_size"), &Texture::get_size);
- ClassDB::bind_method(D_METHOD("has_alpha"), &Texture::has_alpha);
- ClassDB::bind_method(D_METHOD("set_flags", "flags"), &Texture::set_flags);
- ClassDB::bind_method(D_METHOD("get_flags"), &Texture::get_flags);
- ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose", "normal_map"), &Texture::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map"), &Texture::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_data"), &Texture::get_data);
+ ClassDB::bind_method(D_METHOD("get_width"), &Texture2D::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &Texture2D::get_height);
+ ClassDB::bind_method(D_METHOD("get_size"), &Texture2D::get_size);
+ ClassDB::bind_method(D_METHOD("has_alpha"), &Texture2D::has_alpha);
+ ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat"), &Texture2D::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT));
+ ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT));
+ ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("get_data"), &Texture2D::get_data);
- ADD_GROUP("Flags", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic Linear,Convert to Linear,Mirrored Repeat,Video Surface"), "set_flags", "get_flags");
ADD_GROUP("", "");
-
- BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
- BIND_ENUM_CONSTANT(FLAG_MIPMAPS);
- BIND_ENUM_CONSTANT(FLAG_REPEAT);
- BIND_ENUM_CONSTANT(FLAG_FILTER);
- BIND_ENUM_CONSTANT(FLAG_ANISOTROPIC_FILTER);
- BIND_ENUM_CONSTANT(FLAG_CONVERT_TO_LINEAR);
- BIND_ENUM_CONSTANT(FLAG_MIRRORED_REPEAT);
- BIND_ENUM_CONSTANT(FLAG_VIDEO_SURFACE);
}
-Texture::Texture() {
+Texture2D::Texture2D() {
}
/////////////////////
@@ -108,12 +101,11 @@ void ImageTexture::reload_from_file() {
if (!path.is_resource_file())
return;
- uint32_t flags = get_flags();
Ref<Image> img;
img.instance();
if (ImageLoader::load_image(path, img) == OK) {
- create_from_image(img, flags);
+ create_from_image(img);
} else {
Resource::reload_from_file();
_change_notify();
@@ -124,19 +116,12 @@ void ImageTexture::reload_from_file() {
bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
if (p_name == "image")
- create_from_image(p_value, flags);
- else if (p_name == "flags")
- if (w * h == 0)
- flags = p_value;
- else
- set_flags(p_value);
+ create_from_image(p_value);
else if (p_name == "size") {
Size2 s = p_value;
w = s.width;
h = s.height;
- VisualServer::get_singleton()->texture_set_size_override(texture, w, h, 0);
- } else if (p_name == "_data") {
- _set_data(p_value);
+ VisualServer::get_singleton()->texture_set_size_override(texture, w, h);
} else
return false;
@@ -145,12 +130,8 @@ bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
- if (p_name == "image_data") {
-
- } else if (p_name == "image")
+ if (p_name == "image")
r_ret = get_data();
- else if (p_name == "flags")
- r_ret = flags;
else if (p_name == "size")
r_ret = Size2(w, h);
else
@@ -161,7 +142,6 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
}
@@ -178,79 +158,51 @@ void ImageTexture::_reload_hook(const RID &p_hook) {
ERR_FAIL_COND_MSG(err != OK, "Cannot load image from path '" + path + "'.");
- VisualServer::get_singleton()->texture_set_data(texture, img);
+ RID new_texture = VisualServer::get_singleton()->texture_2d_create(img);
+ VisualServer::get_singleton()->texture_replace(texture, new_texture);
_change_notify();
emit_changed();
}
-void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
-
- flags = p_flags;
- VisualServer::get_singleton()->texture_allocate(texture, p_width, p_height, 0, p_format, VS::TEXTURE_TYPE_2D, p_flags);
- format = p_format;
- w = p_width;
- h = p_height;
- _change_notify();
- emit_changed();
-}
-void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags) {
+void ImageTexture::create_from_image(const Ref<Image> &p_image) {
ERR_FAIL_COND(p_image.is_null());
- flags = p_flags;
w = p_image->get_width();
h = p_image->get_height();
format = p_image->get_format();
+ mipmaps = p_image->has_mipmaps();
- VisualServer::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_flags);
- VisualServer::get_singleton()->texture_set_data(texture, p_image);
+ if (texture.is_null()) {
+ texture = VisualServer::get_singleton()->texture_2d_create(p_image);
+ } else {
+ RID new_texture = VisualServer::get_singleton()->texture_2d_create(p_image);
+ VisualServer::get_singleton()->texture_replace(texture, new_texture);
+ }
_change_notify();
emit_changed();
image_stored = true;
}
-void ImageTexture::set_flags(uint32_t p_flags) {
-
- if (flags == p_flags)
- return;
-
- flags = p_flags;
- if (w == 0 || h == 0) {
- return; //uninitialized, do not set to texture
- }
- VisualServer::get_singleton()->texture_set_flags(texture, p_flags);
- _change_notify("flags");
- emit_changed();
-}
-
-uint32_t ImageTexture::get_flags() const {
-
- return ImageTexture::flags;
-}
-
Image::Format ImageTexture::get_format() const {
return format;
}
-#ifndef DISABLE_DEPRECATED
-Error ImageTexture::load(const String &p_path) {
- WARN_DEPRECATED;
- Ref<Image> img;
- img.instance();
- Error err = img->load(p_path);
- if (err == OK) {
- create_from_image(img);
- }
- return err;
-}
-#endif
-void ImageTexture::set_data(const Ref<Image> &p_image) {
+void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) {
ERR_FAIL_COND(p_image.is_null());
+ ERR_FAIL_COND(texture.is_null());
+ ERR_FAIL_COND(p_image->get_width() != w || p_image->get_height() != h);
+ ERR_FAIL_COND(p_image->get_format() != format);
+ ERR_FAIL_COND(mipmaps != p_image->has_mipmaps());
- VisualServer::get_singleton()->texture_set_data(texture, p_image);
+ if (p_immediate) {
+ VisualServer::get_singleton()->texture_2d_update_immediate(texture, p_image);
+ } else {
+ VisualServer::get_singleton()->texture_2d_update(texture, p_image);
+ }
_change_notify();
emit_changed();
@@ -267,7 +219,7 @@ void ImageTexture::_resource_path_changed() {
Ref<Image> ImageTexture::get_data() const {
if (image_stored) {
- return VisualServer::get_singleton()->texture_get_data(texture);
+ return VisualServer::get_singleton()->texture_2d_get(texture);
} else {
return Ref<Image>();
}
@@ -285,6 +237,10 @@ int ImageTexture::get_height() const {
RID ImageTexture::get_rid() const {
+ if (texture.is_null()) {
+ //we are in trouble, create something temporary
+ texture = VisualServer::get_singleton()->texture_2d_placeholder_create();
+ }
return texture;
}
@@ -293,26 +249,29 @@ bool ImageTexture::has_alpha() const {
return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8);
}
-void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
if ((w | h) == 0)
return;
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
if ((w | h) == 0)
return;
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
if ((w | h) == 0)
return;
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
@@ -357,7 +316,7 @@ void ImageTexture::set_size_override(const Size2 &p_size) {
w = s.x;
if (s.y != 0)
h = s.y;
- VisualServer::get_singleton()->texture_set_size_override(texture, w, h, 0);
+ VisualServer::get_singleton()->texture_set_size_override(texture, w, h);
}
void ImageTexture::set_path(const String &p_path, bool p_take_over) {
@@ -369,230 +328,77 @@ void ImageTexture::set_path(const String &p_path, bool p_take_over) {
Resource::set_path(p_path, p_take_over);
}
-void ImageTexture::set_storage(Storage p_storage) {
-
- storage = p_storage;
-}
-
-ImageTexture::Storage ImageTexture::get_storage() const {
-
- return storage;
-}
-
-void ImageTexture::set_lossy_storage_quality(float p_lossy_storage_quality) {
-
- lossy_storage_quality = p_lossy_storage_quality;
-}
-
-float ImageTexture::get_lossy_storage_quality() const {
-
- return lossy_storage_quality;
-}
-
-void ImageTexture::_set_data(Dictionary p_data) {
-
- Ref<Image> img = p_data["image"];
- ERR_FAIL_COND(!img.is_valid());
- uint32_t flags = p_data["flags"];
-
- create_from_image(img, flags);
-
- set_storage(Storage(p_data["storage"].operator int()));
- set_lossy_storage_quality(p_data["lossy_quality"]);
-
- set_size_override(p_data["size"]);
-};
-
void ImageTexture::_bind_methods() {
- ClassDB::bind_method(D_METHOD("create", "width", "height", "format", "flags"), &ImageTexture::create, DEFVAL(FLAGS_DEFAULT));
- ClassDB::bind_method(D_METHOD("create_from_image", "image", "flags"), &ImageTexture::create_from_image, DEFVAL(FLAGS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
-#ifndef DISABLE_DEPRECATED
- ClassDB::bind_method(D_METHOD("load", "path"), &ImageTexture::load);
-#endif
- ClassDB::bind_method(D_METHOD("set_data", "image"), &ImageTexture::set_data);
- ClassDB::bind_method(D_METHOD("set_storage", "mode"), &ImageTexture::set_storage);
- ClassDB::bind_method(D_METHOD("get_storage"), &ImageTexture::get_storage);
- ClassDB::bind_method(D_METHOD("set_lossy_storage_quality", "quality"), &ImageTexture::set_lossy_storage_quality);
- ClassDB::bind_method(D_METHOD("get_lossy_storage_quality"), &ImageTexture::get_lossy_storage_quality);
+ ClassDB::bind_method(D_METHOD("update", "image", "immediate"), &ImageTexture::update, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "storage", PROPERTY_HINT_ENUM, "Uncompressed,Compress Lossy,Compress Lossless"), "set_storage", "get_storage");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "lossy_quality", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_lossy_storage_quality", "get_lossy_storage_quality");
-
- BIND_ENUM_CONSTANT(STORAGE_RAW);
- BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSY);
- BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSLESS);
}
ImageTexture::ImageTexture() {
w = h = 0;
- flags = FLAGS_DEFAULT;
- texture = VisualServer::get_singleton()->texture_create();
- storage = STORAGE_RAW;
- lossy_storage_quality = 0.7;
image_stored = false;
+ mipmaps = false;
format = Image::FORMAT_L8;
}
ImageTexture::~ImageTexture() {
- VisualServer::get_singleton()->free(texture);
-}
-
-//////////////////////////////////////////
-
-void StreamTexture::set_path(const String &p_path, bool p_take_over) {
-
if (texture.is_valid()) {
- VisualServer::get_singleton()->texture_set_path(texture, p_path);
+ VisualServer::get_singleton()->free(texture);
}
-
- Resource::set_path(p_path, p_take_over);
-}
-
-void StreamTexture::_requested_3d(void *p_ud) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
- ERR_FAIL_COND(!request_3d_callback);
- request_3d_callback(stex);
-}
-
-void StreamTexture::_requested_srgb(void *p_ud) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
- ERR_FAIL_COND(!request_srgb_callback);
- request_srgb_callback(stex);
-}
-
-void StreamTexture::_requested_normal(void *p_ud) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
- ERR_FAIL_COND(!request_normal_callback);
- request_normal_callback(stex);
-}
-
-StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL;
-StreamTexture::TextureFormatRequestCallback StreamTexture::request_srgb_callback = NULL;
-StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL;
-
-uint32_t StreamTexture::get_flags() const {
-
- return flags;
-}
-Image::Format StreamTexture::get_format() const {
-
- return format;
}
-Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit) {
-
- alpha_cache.unref();
-
- ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
-
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
-
- uint8_t header[4];
- f->get_buffer(header, 4);
- if (header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T') {
- memdelete(f);
- ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T', ERR_FILE_CORRUPT);
- }
-
- tw = f->get_16();
- tw_custom = f->get_16();
- th = f->get_16();
- th_custom = f->get_16();
-
- flags = f->get_32(); //texture flags!
- uint32_t df = f->get_32(); //data format
-
- /*
- print_line("width: " + itos(tw));
- print_line("height: " + itos(th));
- print_line("flags: " + itos(flags));
- print_line("df: " + itos(df));
- */
-#ifdef TOOLS_ENABLED
-
- if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) {
- //print_line("request detect 3D at " + p_path);
- VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this);
- } else {
- //print_line("not requesting detect 3D at " + p_path);
- VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL);
- }
+//////////////////////////////////////////
- if (request_srgb_callback && df & FORMAT_BIT_DETECT_SRGB) {
- //print_line("request detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_srgb_callback(texture, _requested_srgb, this);
- } else {
- //print_line("not requesting detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL);
- }
+Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit) {
- if (request_srgb_callback && df & FORMAT_BIT_DETECT_NORMAL) {
- //print_line("request detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
- } else {
- //print_line("not requesting detect normal at " + p_path);
- VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL);
- }
-#endif
- if (!(df & FORMAT_BIT_STREAM)) {
- p_size_limit = 0;
- }
+ uint32_t data_format = f->get_32();
+ uint32_t w = f->get_16();
+ uint32_t h = f->get_16();
+ uint32_t mipmaps = f->get_32();
+ Image::Format format = Image::Format(f->get_32());
- if (df & FORMAT_BIT_LOSSLESS || df & FORMAT_BIT_LOSSY) {
+ print_line("format: " + itos(data_format) + " size " + Size2i(w, h) + " mipmaps: " + itos(mipmaps));
+ if (data_format == DATA_FORMAT_LOSSLESS || data_format == DATA_FORMAT_LOSSY || data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
//look for a PNG or WEBP file inside
- int sw = tw;
- int sh = th;
-
- uint32_t mipmaps = f->get_32();
- uint32_t size = f->get_32();
-
- //print_line("mipmaps: " + itos(mipmaps));
-
- while (mipmaps > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) {
-
- f->seek(f->get_position() + size);
- mipmaps = f->get_32();
- size = f->get_32();
-
- sw = MAX(sw >> 1, 1);
- sh = MAX(sh >> 1, 1);
- mipmaps--;
- }
+ int sw = w;
+ int sh = h;
//mipmaps need to be read independently, they will be later combined
Vector<Ref<Image> > mipmap_images;
int total_size = 0;
- for (uint32_t i = 0; i < mipmaps; i++) {
+ bool first = true;
+
+ for (uint32_t i = 0; i < mipmaps + 1; i++) {
+
+ uint32_t size = f->get_32();
- if (i) {
- size = f->get_32();
+ if (p_size_limit > 0 && i < (mipmaps - 1) && (sw > p_size_limit || sh > p_size_limit)) {
+ //can't load this due to size limit
+ sw = MAX(sw >> 1, 1);
+ sh = MAX(sh >> 1, 1);
+ f->seek(f->get_position() + size);
+ continue;
}
PoolVector<uint8_t> pv;
pv.resize(size);
{
- PoolVector<uint8_t>::Write w = pv.write();
- f->get_buffer(w.ptr(), size);
+ PoolVector<uint8_t>::Write wr = pv.write();
+ f->get_buffer(wr.ptr(), size);
}
Ref<Image> img;
- if (df & FORMAT_BIT_LOSSLESS) {
+ if (data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
+ img = Image::basis_universal_unpacker(pv);
+ } else if (data_format == DATA_FORMAT_LOSSLESS) {
img = Image::lossless_unpacker(pv);
} else {
img = Image::lossy_unpacker(pv);
@@ -600,29 +406,43 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
if (img.is_null() || img->empty()) {
memdelete(f);
- ERR_FAIL_COND_V(img.is_null() || img->empty(), ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(img.is_null() || img->empty(), Ref<Image>());
+ }
+
+ if (first) {
+ //format will actually be the format of the first image,
+ //as it may have changed on compression
+ format = img->get_format();
+ first = false;
+ } else if (img->get_format() != format) {
+ img->convert(format); //all needs to be the same format
}
total_size += img->get_data().size();
mipmap_images.push_back(img);
+
+ sw = MAX(sw >> 1, 1);
+ sh = MAX(sh >> 1, 1);
}
//print_line("mipmap read total: " + itos(mipmap_images.size()));
- memdelete(f); //no longer needed
+ Ref<Image> image;
+ image.instance();
if (mipmap_images.size() == 1) {
-
+ //only one image (which will most likely be the case anyway for this format)
image = mipmap_images[0];
- return OK;
+ return image;
} else {
+ //rarer use case, but needs to be supported
PoolVector<uint8_t> img_data;
img_data.resize(total_size);
{
- PoolVector<uint8_t>::Write w = img_data.write();
+ PoolVector<uint8_t>::Write wr = img_data.write();
int ofs = 0;
for (int i = 0; i < mipmap_images.size(); i++) {
@@ -630,116 +450,213 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
PoolVector<uint8_t> id = mipmap_images[i]->get_data();
int len = id.size();
PoolVector<uint8_t>::Read r = id.read();
- copymem(&w[ofs], r.ptr(), len);
+ copymem(&wr[ofs], r.ptr(), len);
ofs += len;
}
}
- image->create(sw, sh, true, mipmap_images[0]->get_format(), img_data);
- return OK;
+ image->create(w, h, true, mipmap_images[0]->get_format(), img_data);
+ return image;
}
- } else {
+ } else if (data_format == DATA_FORMAT_IMAGE) {
- //look for regular format
- Image::Format format = (Image::Format)(df & FORMAT_MASK_IMAGE_FORMAT);
- bool mipmaps = df & FORMAT_BIT_HAS_MIPMAPS;
+ int size = Image::get_image_data_size(w, h, format, mipmaps ? true : false);
- if (!mipmaps) {
- int size = Image::get_image_data_size(tw, th, format, false);
+ for (uint32_t i = 0; i < mipmaps + 1; i++) {
+ int tw, th;
+ int ofs = Image::get_image_mipmap_offset_and_dimensions(w, h, format, i, tw, th);
- PoolVector<uint8_t> img_data;
- img_data.resize(size);
+ if (p_size_limit > 0 && i < mipmaps && (p_size_limit > tw || p_size_limit > th)) {
+ if (ofs) {
+ f->seek(f->get_position() + ofs);
+ }
+ continue; //oops, size limit enforced, go to next
+ }
+
+ PoolVector<uint8_t> data;
+ data.resize(size - ofs);
{
- PoolVector<uint8_t>::Write w = img_data.write();
- f->get_buffer(w.ptr(), size);
+ PoolVector<uint8_t>::Write wr = data.write();
+ f->get_buffer(wr.ptr(), data.size());
}
- memdelete(f);
+ Ref<Image> image;
+ image.instance();
- image->create(tw, th, false, format, img_data);
- return OK;
- } else {
+ image->create(tw, th, mipmaps - i ? true : false, format, data);
- int sw = tw;
- int sh = th;
+ return image;
+ }
+ }
- int mipmaps2 = Image::get_image_required_mipmaps(tw, th, format);
- int total_size = Image::get_image_data_size(tw, th, format, true);
- int idx = 0;
+ return Ref<Image>();
+}
- while (mipmaps2 > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) {
+void StreamTexture::set_path(const String &p_path, bool p_take_over) {
- sw = MAX(sw >> 1, 1);
- sh = MAX(sh >> 1, 1);
- mipmaps2--;
- idx++;
- }
+ if (texture.is_valid()) {
+ VisualServer::get_singleton()->texture_set_path(texture, p_path);
+ }
- int ofs = Image::get_image_mipmap_offset(tw, th, format, idx);
+ Resource::set_path(p_path, p_take_over);
+}
- if (total_size - ofs <= 0) {
- memdelete(f);
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- }
+void StreamTexture::_requested_3d(void *p_ud) {
- f->seek(f->get_position() + ofs);
+ StreamTexture *st = (StreamTexture *)p_ud;
+ Ref<StreamTexture> stex(st);
+ ERR_FAIL_COND(!request_3d_callback);
+ request_3d_callback(stex);
+}
- PoolVector<uint8_t> img_data;
- img_data.resize(total_size - ofs);
+void StreamTexture::_requested_roughness(void *p_ud, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_roughness_channel) {
- {
- PoolVector<uint8_t>::Write w = img_data.write();
- int bytes = f->get_buffer(w.ptr(), total_size - ofs);
- //print_line("requested read: " + itos(total_size - ofs) + " but got: " + itos(bytes));
+ StreamTexture *st = (StreamTexture *)p_ud;
+ Ref<StreamTexture> stex(st);
+ ERR_FAIL_COND(!request_roughness_callback);
+ request_roughness_callback(stex, p_normal_path, p_roughness_channel);
+}
- memdelete(f);
+void StreamTexture::_requested_normal(void *p_ud) {
- int expected = total_size - ofs;
- if (bytes < expected) {
- //this is a compatibility workaround for older format, which saved less mipmaps2. It is still recommended the image is reimported.
- zeromem(w.ptr() + bytes, (expected - bytes));
- } else if (bytes != expected) {
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- }
- }
+ StreamTexture *st = (StreamTexture *)p_ud;
+ Ref<StreamTexture> stex(st);
+ ERR_FAIL_COND(!request_normal_callback);
+ request_normal_callback(stex);
+}
- image->create(sw, sh, true, format, img_data);
+StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL;
+StreamTexture::TextureFormatRoughnessRequestCallback StreamTexture::request_roughness_callback = NULL;
+StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL;
- return OK;
- }
+Image::Format StreamTexture::get_format() const {
+
+ return format;
+}
+
+Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) {
+
+ alpha_cache.unref();
+
+ ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
+
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+
+ uint8_t header[4];
+ f->get_buffer(header, 4);
+ if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != '2') {
+ memdelete(f);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is corrupt (Bad header).");
+ }
+
+ uint32_t version = f->get_32();
+
+ if (version > FORMAT_VERSION) {
+ memdelete(f);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
+ }
+ tw_custom = f->get_32();
+ th_custom = f->get_32();
+ uint32_t df = f->get_32(); //data format
+
+ //skip reserved
+ mipmap_limit = int(f->get_32());
+ //reserved
+ f->get_32();
+ f->get_32();
+ f->get_32();
+
+#ifdef TOOLS_ENABLED
+
+ r_request_3d = request_3d_callback && df & FORMAT_BIT_DETECT_3D;
+ r_request_roughness = request_roughness_callback && df & FORMAT_BIT_DETECT_ROUGNESS;
+ r_request_normal = request_normal_callback && df & FORMAT_BIT_DETECT_NORMAL;
+
+#else
+
+ r_request_3d = false;
+ r_request_roughness = false;
+ r_request_normal = false;
+
+#endif
+ if (!(df & FORMAT_BIT_STREAM)) {
+ p_size_limit = 0;
}
- return ERR_BUG; //unreachable
+ image = load_image_from_file(f, p_size_limit);
+
+ if (image.is_null() || image->empty()) {
+ return ERR_CANT_OPEN;
+ }
+
+ return OK;
}
Error StreamTexture::load(const String &p_path) {
- int lw, lh, lwc, lhc, lflags;
+ int lw, lh, lwc, lhc;
Ref<Image> image;
image.instance();
- Error err = _load_data(p_path, lw, lh, lwc, lhc, lflags, image);
+
+ bool request_3d;
+ bool request_normal;
+ bool request_roughness;
+ int mipmap_limit;
+
+ Error err = _load_data(p_path, lw, lh, lwc, lhc, image, request_3d, request_normal, request_roughness, mipmap_limit);
if (err)
return err;
- if (get_path() == String()) {
- //temporarily set path if no path set for resource, helps find errors
- VisualServer::get_singleton()->texture_set_path(texture, p_path);
+ if (texture.is_valid()) {
+ RID new_texture = VS::get_singleton()->texture_2d_create(image);
+ VS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = VS::get_singleton()->texture_2d_create(image);
}
- VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, image->get_format(), VS::TEXTURE_TYPE_2D, lflags);
- VS::get_singleton()->texture_set_data(texture, image);
if (lwc || lhc) {
- VS::get_singleton()->texture_set_size_override(texture, lwc, lhc, 0);
- } else {
+ VS::get_singleton()->texture_set_size_override(texture, lwc, lhc);
}
w = lwc ? lwc : lw;
h = lhc ? lhc : lh;
- flags = lflags;
path_to_file = p_path;
format = image->get_format();
+ if (get_path() == String()) {
+ //temporarily set path if no path set for resource, helps find errors
+ VisualServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+#ifdef TOOLS_ENABLED
+
+ if (request_3d) {
+ //print_line("request detect 3D at " + p_path);
+ VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this);
+ } else {
+ //print_line("not requesting detect 3D at " + p_path);
+ VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL);
+ }
+
+ if (request_roughness) {
+ //print_line("request detect srgb at " + p_path);
+ VS::get_singleton()->texture_set_detect_roughness_callback(texture, _requested_roughness, this);
+ } else {
+ //print_line("not requesting detect srgb at " + p_path);
+ VS::get_singleton()->texture_set_detect_roughness_callback(texture, NULL, NULL);
+ }
+
+ if (request_normal) {
+ //print_line("request detect srgb at " + p_path);
+ VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
+ } else {
+ //print_line("not requesting detect normal at " + p_path);
+ VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL);
+ }
+
+#endif
_change_notify();
emit_changed();
return OK;
@@ -759,29 +676,35 @@ int StreamTexture::get_height() const {
}
RID StreamTexture::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = VS::get_singleton()->texture_2d_placeholder_create();
+ }
return texture;
}
-void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
if ((w | h) == 0)
return;
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
if ((w | h) == 0)
return;
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
if ((w | h) == 0)
return;
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
bool StreamTexture::has_alpha() const {
@@ -791,7 +714,11 @@ bool StreamTexture::has_alpha() const {
Ref<Image> StreamTexture::get_data() const {
- return VS::get_singleton()->texture_get_data(texture);
+ if (texture.is_valid()) {
+ return VS::get_singleton()->texture_2d_get(texture);
+ } else {
+ return Ref<Image>();
+ }
}
bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
@@ -829,12 +756,6 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void StreamTexture::set_flags(uint32_t p_flags) {
- flags = p_flags;
- VS::get_singleton()->texture_set_flags(texture, flags);
- _change_notify("flags");
- emit_changed();
-}
void StreamTexture::reload_from_file() {
@@ -851,9 +772,6 @@ void StreamTexture::reload_from_file() {
}
void StreamTexture::_validate_property(PropertyInfo &property) const {
- if (property.name == "flags") {
- property.usage = PROPERTY_USAGE_NOEDITOR;
- }
}
void StreamTexture::_bind_methods() {
@@ -867,16 +785,15 @@ void StreamTexture::_bind_methods() {
StreamTexture::StreamTexture() {
format = Image::FORMAT_MAX;
- flags = 0;
w = 0;
h = 0;
-
- texture = VS::get_singleton()->texture_create();
}
StreamTexture::~StreamTexture() {
- VS::get_singleton()->free(texture);
+ if (texture.is_valid()) {
+ VS::get_singleton()->free(texture);
+ }
}
RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error) {
@@ -944,21 +861,7 @@ bool AtlasTexture::has_alpha() const {
return false;
}
-void AtlasTexture::set_flags(uint32_t p_flags) {
-
- if (atlas.is_valid())
- atlas->set_flags(p_flags);
-}
-
-uint32_t AtlasTexture::get_flags() const {
-
- if (atlas.is_valid())
- return atlas->get_flags();
-
- return 0;
-}
-
-void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) {
+void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) {
ERR_FAIL_COND(p_atlas == this);
if (atlas == p_atlas)
@@ -967,7 +870,7 @@ void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) {
emit_changed();
_change_notify("atlas");
}
-Ref<Texture> AtlasTexture::get_atlas() const {
+Ref<Texture2D> AtlasTexture::get_atlas() const {
return atlas;
}
@@ -1026,13 +929,13 @@ void AtlasTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_filter_clip", "enable"), &AtlasTexture::set_filter_clip);
ClassDB::bind_method(D_METHOD("has_filter_clip"), &AtlasTexture::has_filter_clip);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_atlas", "get_atlas");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_atlas", "get_atlas");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region"), "set_region", "get_region");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_clip"), "set_filter_clip", "has_filter_clip");
}
-void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
if (!atlas.is_valid())
return;
@@ -1048,10 +951,11 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m
}
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, filter_clip);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
}
-void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
if (!atlas.is_valid())
return;
@@ -1070,9 +974,10 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale);
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, filter_clip);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
}
-void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
//this might not necessarily work well if using a rect, needs to be fixed properly
if (!atlas.is_valid())
@@ -1083,7 +988,8 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
get_rect_region(p_rect, p_src_rect, dr, src_c);
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, filter_clip);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
}
bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
@@ -1157,13 +1063,6 @@ bool MeshTexture::has_alpha() const {
return false;
}
-void MeshTexture::set_flags(uint32_t p_flags) {
-}
-
-uint32_t MeshTexture::get_flags() const {
- return 0;
-}
-
void MeshTexture::set_mesh(const Ref<Mesh> &p_mesh) {
mesh = p_mesh;
}
@@ -1180,15 +1079,15 @@ Size2 MeshTexture::get_image_size() const {
return size;
}
-void MeshTexture::set_base_texture(const Ref<Texture> &p_texture) {
+void MeshTexture::set_base_texture(const Ref<Texture2D> &p_texture) {
base_texture = p_texture;
}
-Ref<Texture> MeshTexture::get_base_texture() const {
+Ref<Texture2D> MeshTexture::get_base_texture() const {
return base_texture;
}
-void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
if (mesh.is_null() || base_texture.is_null()) {
return;
@@ -1200,9 +1099,10 @@ void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_mo
SWAP(xform.elements[0][0], xform.elements[1][1]);
}
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
if (mesh.is_null() || base_texture.is_null()) {
return;
}
@@ -1222,9 +1122,10 @@ void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile,
SWAP(xform.elements[0][0], xform.elements[1][1]);
}
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
if (mesh.is_null() || base_texture.is_null()) {
return;
@@ -1245,7 +1146,8 @@ void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const
SWAP(xform.elements[0][0], xform.elements[1][1]);
}
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
+ RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
bool MeshTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
r_rect = p_rect;
@@ -1266,7 +1168,7 @@ void MeshTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_base_texture"), &MeshTexture::get_base_texture);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base_texture", "get_base_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base_texture", "get_base_texture");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "image_size", PROPERTY_HINT_RANGE, "0,16384,1"), "set_image_size", "get_image_size");
}
@@ -1298,22 +1200,7 @@ bool LargeTexture::has_alpha() const {
return false;
}
-void LargeTexture::set_flags(uint32_t p_flags) {
-
- for (int i = 0; i < pieces.size(); i++) {
- pieces.write[i].texture->set_flags(p_flags);
- }
-}
-
-uint32_t LargeTexture::get_flags() const {
-
- if (pieces.size())
- return pieces[0].texture->get_flags();
-
- return 0;
-}
-
-int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture> &p_texture) {
+int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND_V(p_texture.is_null(), -1);
Piece p;
@@ -1330,7 +1217,7 @@ void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) {
pieces.write[p_idx].offset = p_offset;
};
-void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture> &p_texture) {
+void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(p_texture == this);
ERR_FAIL_COND(p_texture.is_null());
@@ -1378,9 +1265,9 @@ Vector2 LargeTexture::get_piece_offset(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, pieces.size(), Vector2());
return pieces[p_idx].offset;
}
-Ref<Texture> LargeTexture::get_piece_texture(int p_idx) const {
+Ref<Texture2D> LargeTexture::get_piece_texture(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture>());
+ ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture2D>());
return pieces[p_idx].texture;
}
Ref<Image> LargeTexture::to_image() const {
@@ -1413,16 +1300,16 @@ void LargeTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
-void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
for (int i = 0; i < pieces.size(); i++) {
// TODO
- pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map);
+ pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
}
-void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
+void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
//tiling not supported for this
if (size.x == 0 || size.y == 0)
@@ -1433,10 +1320,10 @@ void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
for (int i = 0; i < pieces.size(); i++) {
// TODO
- pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map);
+ pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
}
-void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
+void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
//tiling not supported for this
if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0)
@@ -1455,7 +1342,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
target.size *= scale;
target.position = p_rect.position + (p_src_rect.position + rect.position) * scale;
local.position -= rect.position;
- pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, false);
+ pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat, false);
}
}
@@ -1479,211 +1366,7 @@ bool LargeTexture::is_pixel_opaque(int p_x, int p_y) const {
LargeTexture::LargeTexture() {
}
-///////////////////////////////////////////////
-
-void CubeMap::set_flags(uint32_t p_flags) {
-
- flags = p_flags;
- if (_is_valid())
- VS::get_singleton()->texture_set_flags(cubemap, flags);
-}
-
-uint32_t CubeMap::get_flags() const {
-
- return flags;
-}
-
-void CubeMap::set_side(Side p_side, const Ref<Image> &p_image) {
-
- ERR_FAIL_COND(p_image.is_null());
- ERR_FAIL_COND(p_image->empty());
- ERR_FAIL_INDEX(p_side, 6);
-
- if (!_is_valid()) {
- format = p_image->get_format();
- w = p_image->get_width();
- h = p_image->get_height();
- VS::get_singleton()->texture_allocate(cubemap, w, h, 0, p_image->get_format(), VS::TEXTURE_TYPE_CUBEMAP, flags);
- }
-
- VS::get_singleton()->texture_set_data(cubemap, p_image, VS::CubeMapSide(p_side));
- valid[p_side] = true;
-}
-
-Ref<Image> CubeMap::get_side(Side p_side) const {
-
- ERR_FAIL_INDEX_V(p_side, 6, Ref<Image>());
- if (!valid[p_side])
- return Ref<Image>();
- return VS::get_singleton()->texture_get_data(cubemap, VS::CubeMapSide(p_side));
-}
-
-Image::Format CubeMap::get_format() const {
-
- return format;
-}
-int CubeMap::get_width() const {
-
- return w;
-}
-int CubeMap::get_height() const {
-
- return h;
-}
-
-RID CubeMap::get_rid() const {
-
- return cubemap;
-}
-
-void CubeMap::set_storage(Storage p_storage) {
-
- storage = p_storage;
-}
-
-CubeMap::Storage CubeMap::get_storage() const {
-
- return storage;
-}
-
-void CubeMap::set_lossy_storage_quality(float p_lossy_storage_quality) {
-
- lossy_storage_quality = p_lossy_storage_quality;
-}
-
-float CubeMap::get_lossy_storage_quality() const {
-
- return lossy_storage_quality;
-}
-
-void CubeMap::set_path(const String &p_path, bool p_take_over) {
-
- if (cubemap.is_valid()) {
- VisualServer::get_singleton()->texture_set_path(cubemap, p_path);
- }
-
- Resource::set_path(p_path, p_take_over);
-}
-
-bool CubeMap::_set(const StringName &p_name, const Variant &p_value) {
-
- if (p_name == "side/left") {
- set_side(SIDE_LEFT, p_value);
- } else if (p_name == "side/right") {
- set_side(SIDE_RIGHT, p_value);
- } else if (p_name == "side/bottom") {
- set_side(SIDE_BOTTOM, p_value);
- } else if (p_name == "side/top") {
- set_side(SIDE_TOP, p_value);
- } else if (p_name == "side/front") {
- set_side(SIDE_FRONT, p_value);
- } else if (p_name == "side/back") {
- set_side(SIDE_BACK, p_value);
- } else if (p_name == "storage") {
- storage = Storage(p_value.operator int());
- } else if (p_name == "lossy_quality") {
- lossy_storage_quality = p_value;
- } else
- return false;
-
- return true;
-}
-
-bool CubeMap::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (p_name == "side/left") {
- r_ret = get_side(SIDE_LEFT);
- } else if (p_name == "side/right") {
- r_ret = get_side(SIDE_RIGHT);
- } else if (p_name == "side/bottom") {
- r_ret = get_side(SIDE_BOTTOM);
- } else if (p_name == "side/top") {
- r_ret = get_side(SIDE_TOP);
- } else if (p_name == "side/front") {
- r_ret = get_side(SIDE_FRONT);
- } else if (p_name == "side/back") {
- r_ret = get_side(SIDE_BACK);
- } else if (p_name == "storage") {
- r_ret = storage;
- } else if (p_name == "lossy_quality") {
- r_ret = lossy_storage_quality;
- } else
- return false;
-
- return true;
-}
-
-void CubeMap::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/left", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/right", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/bottom", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/top", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/front", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "side/back", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
-}
-
-void CubeMap::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("get_width"), &CubeMap::get_width);
- ClassDB::bind_method(D_METHOD("get_height"), &CubeMap::get_height);
- ClassDB::bind_method(D_METHOD("set_flags", "flags"), &CubeMap::set_flags);
- ClassDB::bind_method(D_METHOD("get_flags"), &CubeMap::get_flags);
- ClassDB::bind_method(D_METHOD("set_side", "side", "image"), &CubeMap::set_side);
- ClassDB::bind_method(D_METHOD("get_side", "side"), &CubeMap::get_side);
- ClassDB::bind_method(D_METHOD("set_storage", "mode"), &CubeMap::set_storage);
- ClassDB::bind_method(D_METHOD("get_storage"), &CubeMap::get_storage);
- ClassDB::bind_method(D_METHOD("set_lossy_storage_quality", "quality"), &CubeMap::set_lossy_storage_quality);
- ClassDB::bind_method(D_METHOD("get_lossy_storage_quality"), &CubeMap::get_lossy_storage_quality);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "storage_mode", PROPERTY_HINT_ENUM, "Raw,Lossy Compressed,Lossless Compressed"), "set_storage", "get_storage");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "lossy_storage_quality"), "set_lossy_storage_quality", "get_lossy_storage_quality");
-
- BIND_ENUM_CONSTANT(STORAGE_RAW);
- BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSY);
- BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSLESS);
-
- BIND_ENUM_CONSTANT(SIDE_LEFT);
- BIND_ENUM_CONSTANT(SIDE_RIGHT);
- BIND_ENUM_CONSTANT(SIDE_BOTTOM);
- BIND_ENUM_CONSTANT(SIDE_TOP);
- BIND_ENUM_CONSTANT(SIDE_FRONT);
- BIND_ENUM_CONSTANT(SIDE_BACK);
-
- BIND_ENUM_CONSTANT(FLAG_MIPMAPS);
- BIND_ENUM_CONSTANT(FLAG_REPEAT);
- BIND_ENUM_CONSTANT(FLAG_FILTER);
- BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
-}
-
-CubeMap::CubeMap() {
-
- w = h = 0;
- flags = FLAGS_DEFAULT;
- for (int i = 0; i < 6; i++)
- valid[i] = false;
- cubemap = VisualServer::get_singleton()->texture_create();
- storage = STORAGE_RAW;
- lossy_storage_quality = 0.7;
- format = Image::FORMAT_BPTC_RGBA;
-}
-
-CubeMap::~CubeMap() {
-
- VisualServer::get_singleton()->free(cubemap);
-}
-
-/* BIND_ENUM(CubeMapSize);
- BIND_ENUM_CONSTANT( FLAG_CUBEMAP );
- BIND_ENUM_CONSTANT( CUBEMAP_LEFT );
- BIND_ENUM_CONSTANT( CUBEMAP_RIGHT );
- BIND_ENUM_CONSTANT( CUBEMAP_BOTTOM );
- BIND_ENUM_CONSTANT( CUBEMAP_TOP );
- BIND_ENUM_CONSTANT( CUBEMAP_FRONT );
- BIND_ENUM_CONSTANT( CUBEMAP_BACK );
-*/
-///////////////////////////
+///////////////////
void CurveTexture::_bind_methods() {
@@ -1761,8 +1444,12 @@ void CurveTexture::_update() {
Ref<Image> image = memnew(Image(_width, 1, false, Image::FORMAT_RF, data));
- VS::get_singleton()->texture_allocate(_texture, _width, 1, 0, Image::FORMAT_RF, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
- VS::get_singleton()->texture_set_data(_texture, image);
+ if (_texture.is_valid()) {
+ RID new_texture = VS::get_singleton()->texture_2d_create(image);
+ VS::get_singleton()->texture_replace(_texture, new_texture);
+ } else {
+ _texture = VS::get_singleton()->texture_2d_create(image);
+ }
emit_changed();
}
@@ -1774,15 +1461,19 @@ Ref<Curve> CurveTexture::get_curve() const {
RID CurveTexture::get_rid() const {
+ if (!_texture.is_valid()) {
+ _texture = VS::get_singleton()->texture_2d_placeholder_create();
+ }
return _texture;
}
CurveTexture::CurveTexture() {
_width = 2048;
- _texture = VS::get_singleton()->texture_create();
}
CurveTexture::~CurveTexture() {
- VS::get_singleton()->free(_texture);
+ if (_texture.is_valid()) {
+ VS::get_singleton()->free(_texture);
+ }
}
//////////////////
@@ -1796,12 +1487,13 @@ GradientTexture::GradientTexture() {
update_pending = false;
width = 2048;
- texture = VS::get_singleton()->texture_create();
_queue_update();
}
GradientTexture::~GradientTexture() {
- VS::get_singleton()->free(texture);
+ if (texture.is_valid()) {
+ VS::get_singleton()->free(texture);
+ }
}
void GradientTexture::_bind_methods() {
@@ -1871,8 +1563,12 @@ void GradientTexture::_update() {
Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
- VS::get_singleton()->texture_allocate(texture, width, 1, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
- VS::get_singleton()->texture_set_data(texture, image);
+ if (texture.is_valid()) {
+ RID new_texture = VS::get_singleton()->texture_2d_create(image);
+ VS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = VS::get_singleton()->texture_2d_create(image);
+ }
emit_changed();
}
@@ -1888,7 +1584,10 @@ int GradientTexture::get_width() const {
}
Ref<Image> GradientTexture::get_data() const {
- return VisualServer::get_singleton()->texture_get_data(texture);
+ if (!texture.is_valid()) {
+ return Ref<Image>();
+ }
+ return VisualServer::get_singleton()->texture_2d_get(texture);
}
//////////////////////////////////////
@@ -1898,21 +1597,28 @@ void ProxyTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_base", "base"), &ProxyTexture::set_base);
ClassDB::bind_method(D_METHOD("get_base"), &ProxyTexture::get_base);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base", "get_base");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base", "get_base");
}
-void ProxyTexture::set_base(const Ref<Texture> &p_texture) {
+void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(p_texture == this);
+
base = p_texture;
if (base.is_valid()) {
- VS::get_singleton()->texture_set_proxy(proxy, base->get_rid());
- } else {
- VS::get_singleton()->texture_set_proxy(proxy, RID());
+ if (proxy_ph.is_valid()) {
+ VS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
+ VS::get_singleton()->free(proxy_ph);
+ proxy_ph = RID();
+ } else if (proxy.is_valid()) {
+ VS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
+ } else {
+ proxy = VS::get_singleton()->texture_proxy_create(base->get_rid());
+ }
}
}
-Ref<Texture> ProxyTexture::get_base() const {
+Ref<Texture2D> ProxyTexture::get_base() const {
return base;
}
@@ -1931,6 +1637,10 @@ int ProxyTexture::get_height() const {
}
RID ProxyTexture::get_rid() const {
+ if (proxy.is_null()) {
+ proxy_ph = VS::get_singleton()->texture_2d_placeholder_create();
+ proxy = VS::get_singleton()->texture_proxy_create(proxy_ph);
+ }
return proxy;
}
@@ -1941,24 +1651,19 @@ bool ProxyTexture::has_alpha() const {
return false;
}
-void ProxyTexture::set_flags(uint32_t p_flags) {
-}
-
-uint32_t ProxyTexture::get_flags() const {
-
- if (base.is_valid())
- return base->get_flags();
- return 0;
-}
-
ProxyTexture::ProxyTexture() {
- proxy = VS::get_singleton()->texture_create();
+ //proxy = VS::get_singleton()->texture_create();
}
ProxyTexture::~ProxyTexture() {
- VS::get_singleton()->free(proxy);
+ if (proxy_ph.is_valid()) {
+ VS::get_singleton()->free(proxy_ph);
+ }
+ if (proxy.is_valid()) {
+ VS::get_singleton()->free(proxy);
+ }
}
//////////////////////////////////////////////
@@ -2003,7 +1708,7 @@ void AnimatedTexture::_update_proxy() {
}
if (frames[current_frame].texture.is_valid()) {
- VisualServer::get_singleton()->texture_set_proxy(proxy, frames[current_frame].texture->get_rid());
+ VisualServer::get_singleton()->texture_proxy_update(proxy, frames[current_frame].texture->get_rid());
}
}
@@ -2018,7 +1723,7 @@ int AnimatedTexture::get_frames() const {
return frame_count;
}
-void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) {
+void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(p_texture == this);
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
@@ -2027,8 +1732,8 @@ void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_textu
frames[p_frame].texture = p_texture;
}
-Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const {
- ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture>());
+Ref<Texture2D> AnimatedTexture::get_frame_texture(int p_frame) const {
+ ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture2D>());
RWLockRead r(rw_lock);
@@ -2113,19 +1818,6 @@ bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void AnimatedTexture::set_flags(uint32_t p_flags) {
-}
-uint32_t AnimatedTexture::get_flags() const {
-
- RWLockRead r(rw_lock);
-
- if (!frames[current_frame].texture.is_valid()) {
- return 0;
- }
-
- return frames[current_frame].texture->get_flags();
-}
-
void AnimatedTexture::_validate_property(PropertyInfo &property) const {
String prop = property.name;
@@ -2156,7 +1848,7 @@ void AnimatedTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps");
for (int i = 0; i < MAX_FRAMES; i++) {
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i);
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i);
}
@@ -2164,7 +1856,10 @@ void AnimatedTexture::_bind_methods() {
}
AnimatedTexture::AnimatedTexture() {
- proxy = VS::get_singleton()->texture_create();
+ //proxy = VS::get_singleton()->texture_create();
+ proxy_ph = VS::get_singleton()->texture_2d_placeholder_create();
+ proxy = VS::get_singleton()->texture_proxy_create(proxy_ph);
+
VisualServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
time = 0;
frame_count = 1;
@@ -2182,24 +1877,13 @@ AnimatedTexture::AnimatedTexture() {
AnimatedTexture::~AnimatedTexture() {
VS::get_singleton()->free(proxy);
+ VS::get_singleton()->free(proxy_ph);
if (rw_lock) {
memdelete(rw_lock);
}
}
///////////////////////////////
-void TextureLayered::set_flags(uint32_t p_flags) {
- flags = p_flags;
-
- if (texture.is_valid()) {
- VS::get_singleton()->texture_set_flags(texture, flags);
- }
-}
-
-uint32_t TextureLayered::get_flags() const {
- return flags;
-}
-
Image::Format TextureLayered::get_format() const {
return format;
}
@@ -2212,82 +1896,93 @@ uint32_t TextureLayered::get_height() const {
return height;
}
-uint32_t TextureLayered::get_depth() const {
- return depth;
+uint32_t TextureLayered::get_layers() const {
+ return layers;
}
-void TextureLayered::_set_data(const Dictionary &p_data) {
- ERR_FAIL_COND(!p_data.has("width"));
- ERR_FAIL_COND(!p_data.has("height"));
- ERR_FAIL_COND(!p_data.has("depth"));
- ERR_FAIL_COND(!p_data.has("format"));
- ERR_FAIL_COND(!p_data.has("flags"));
- ERR_FAIL_COND(!p_data.has("layers"));
- int w = p_data["width"];
- int h = p_data["height"];
- int d = p_data["depth"];
- Image::Format format = Image::Format(int(p_data["format"]));
- int flags = p_data["flags"];
- Array layers = p_data["layers"];
- ERR_FAIL_COND(layers.size() != d);
+Error TextureLayered::_create_from_images(const Array &p_images) {
+ Vector<Ref<Image> > images;
+ for (int i = 0; i < p_images.size(); i++) {
+ Ref<Image> img = p_images[i];
+ ERR_FAIL_COND_V(img.is_null(), ERR_INVALID_PARAMETER);
+ images.push_back(img);
+ }
- create(w, h, d, format, flags);
+ return create_from_images(images);
+}
- for (int i = 0; i < layers.size(); i++) {
- Ref<Image> img = layers[i];
- ERR_CONTINUE(!img.is_valid());
- ERR_CONTINUE(img->get_format() != format);
- ERR_CONTINUE(img->get_width() != w);
- ERR_CONTINUE(img->get_height() != h);
- set_layer_data(img, i);
+Array TextureLayered::_get_images() const {
+ Array images;
+ for (int i = 0; i < layers; i++) {
+ images.push_back(get_layer_data(i));
}
+ return images;
}
-Dictionary TextureLayered::_get_data() const {
- Dictionary d;
- d["width"] = width;
- d["height"] = height;
- d["depth"] = depth;
- d["flags"] = flags;
- d["format"] = format;
+Error TextureLayered::create_from_images(Vector<Ref<Image> > p_images) {
- Array layers;
- for (int i = 0; i < depth; i++) {
- layers.push_back(get_layer_data(i));
+ int new_layers = p_images.size();
+ ERR_FAIL_COND_V(new_layers == 0, ERR_INVALID_PARAMETER);
+ if (layered_type == VS::TEXTURE_LAYERED_CUBEMAP) {
+ ERR_FAIL_COND_V_MSG(new_layers != 6, ERR_INVALID_PARAMETER,
+ "Cubemaps require exactly 6 layers");
+ } else if (layered_type == VS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {
+ ERR_FAIL_COND_V_MSG((new_layers % 6) != 0, ERR_INVALID_PARAMETER,
+ "Cubemap array layers must be a multiple of 6");
}
- d["layers"] = layers;
- return d;
-}
-void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags) {
- VS::get_singleton()->texture_allocate(texture, p_width, p_height, p_depth, p_format, is_3d ? VS::TEXTURE_TYPE_3D : VS::TEXTURE_TYPE_2D_ARRAY, p_flags);
+ ERR_FAIL_COND_V(p_images[0].is_null() || p_images[0]->empty(), ERR_INVALID_PARAMETER);
- width = p_width;
- height = p_height;
- depth = p_depth;
- format = p_format;
- flags = p_flags;
-}
+ Image::Format new_format = p_images[0]->get_format();
+ int new_width = p_images[0]->get_width();
+ int new_height = p_images[0]->get_height();
+ bool new_mipmaps = p_images[0]->has_mipmaps();
-void TextureLayered::set_layer_data(const Ref<Image> &p_image, int p_layer) {
- ERR_FAIL_COND(!texture.is_valid());
- ERR_FAIL_COND(!p_image.is_valid());
- VS::get_singleton()->texture_set_data(texture, p_image, p_layer);
-}
+ for (int i = 1; i < p_images.size(); i++) {
+ ERR_FAIL_COND_V_MSG(p_images[i]->get_format() != new_format, ERR_INVALID_PARAMETER,
+ "All images must share the same format");
+ ERR_FAIL_COND_V_MSG(p_images[i]->get_width() != new_width || p_images[i]->get_height() != new_height, ERR_INVALID_PARAMETER,
+ "All images must share the same dimensions");
+ ERR_FAIL_COND_V_MSG(p_images[i]->has_mipmaps() != new_mipmaps, ERR_INVALID_PARAMETER,
+ "All images must share the usage of mipmaps");
+ }
-Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
+ if (texture.is_valid()) {
+ RID new_texture = VS::get_singleton()->texture_2d_layered_create(p_images, layered_type);
+ ERR_FAIL_COND_V(!new_texture.is_valid(), ERR_CANT_CREATE);
+ VS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = VS::get_singleton()->texture_2d_layered_create(p_images, layered_type);
+ ERR_FAIL_COND_V(!texture.is_valid(), ERR_CANT_CREATE);
+ }
- ERR_FAIL_COND_V(!texture.is_valid(), Ref<Image>());
- return VS::get_singleton()->texture_get_data(texture, p_layer);
+ format = new_format;
+ width = new_width;
+ height = new_height;
+ layers = new_layers;
+ mipmaps = new_mipmaps;
+ return OK;
}
-void TextureLayered::set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap) {
- ERR_FAIL_COND(!texture.is_valid());
- ERR_FAIL_COND(!p_image.is_valid());
- VS::get_singleton()->texture_set_data_partial(texture, p_image, 0, 0, p_image->get_width(), p_image->get_height(), p_x_ofs, p_y_ofs, p_mipmap, p_z);
+void TextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
+ ERR_FAIL_COND(texture.is_valid());
+ ERR_FAIL_COND(p_image.is_null());
+ ERR_FAIL_COND(p_image->get_format() != format);
+ ERR_FAIL_COND(p_image->get_width() != width || p_image->get_height() != height);
+ ERR_FAIL_INDEX(p_layer, layers);
+ ERR_FAIL_COND(p_image->has_mipmaps() != mipmaps);
+ VS::get_singleton()->texture_2d_update(texture, p_image, p_layer);
+}
+
+Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
+ ERR_FAIL_INDEX_V(p_layer, layers, Ref<Image>());
+ return VS::get_singleton()->texture_2d_layer_get(texture, p_layer);
}
RID TextureLayered::get_rid() const {
+ if (texture.is_null()) {
+ texture = VS::get_singleton()->texture_2d_layered_placeholder_create();
+ }
return texture;
}
@@ -2300,42 +1995,29 @@ void TextureLayered::set_path(const String &p_path, bool p_take_over) {
}
void TextureLayered::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextureLayered::set_flags);
- ClassDB::bind_method(D_METHOD("get_flags"), &TextureLayered::get_flags);
ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width);
ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height);
- ClassDB::bind_method(D_METHOD("get_depth"), &TextureLayered::get_depth);
+ ClassDB::bind_method(D_METHOD("get_layers"), &TextureLayered::get_layers);
- ClassDB::bind_method(D_METHOD("create", "width", "height", "depth", "format", "flags"), &TextureLayered::create, DEFVAL(FLAGS_DEFAULT));
- ClassDB::bind_method(D_METHOD("set_layer_data", "image", "layer"), &TextureLayered::set_layer_data);
+ ClassDB::bind_method(D_METHOD("create_from_images", "images"), &TextureLayered::_create_from_images);
+ ClassDB::bind_method(D_METHOD("update_layer", "image", "layer"), &TextureLayered::update_layer);
ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data);
- ClassDB::bind_method(D_METHOD("set_data_partial", "image", "x_offset", "y_offset", "layer", "mipmap"), &TextureLayered::set_data_partial, DEFVAL(0));
- ClassDB::bind_method(D_METHOD("_set_data", "data"), &TextureLayered::_set_data);
- ClassDB::bind_method(D_METHOD("_get_data"), &TextureLayered::_get_data);
+ ClassDB::bind_method(D_METHOD("_get_images"), &TextureLayered::_get_images);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags");
- ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
-
- BIND_ENUM_CONSTANT(FLAG_MIPMAPS);
- BIND_ENUM_CONSTANT(FLAG_REPEAT);
- BIND_ENUM_CONSTANT(FLAG_FILTER);
- BIND_ENUM_CONSTANT(FLAGS_DEFAULT);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images");
}
-TextureLayered::TextureLayered(bool p_3d) {
- is_3d = p_3d;
+TextureLayered::TextureLayered(VisualServer::TextureLayeredType p_layered_type) {
+ layered_type = p_layered_type;
format = Image::FORMAT_MAX;
- flags = FLAGS_DEFAULT;
width = 0;
height = 0;
- depth = 0;
-
- texture = VS::get_singleton()->texture_create();
+ layers = 0;
}
TextureLayered::~TextureLayered() {
@@ -2351,15 +2033,19 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String
}
Ref<TextureLayered> lt;
- Ref<Texture3D> tex3d;
- Ref<TextureArray> texarr;
-
- if (p_path.ends_with("tex3d")) {
- tex3d.instance();
- lt = tex3d;
- } else if (p_path.ends_with("texarr")) {
- texarr.instance();
- lt = texarr;
+
+ if (p_path.ends_with("cube")) {
+ Ref<Cubemap> cube;
+ cube.instance();
+ lt = cube;
+ } else if (p_path.ends_with("cubearr")) {
+ Ref<CubemapArray> cubearr;
+ cubearr.instance();
+ lt = cubearr;
+ } else if (p_path.ends_with("tex2darr")) {
+ Ref<Texture2DArray> t2darr;
+ t2darr.instance();
+ lt = t2darr;
} else {
ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture extension.");
}
@@ -2367,21 +2053,18 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");
- uint8_t header[5] = { 0, 0, 0, 0, 0 };
- f->get_buffer(header, 4);
+ char header[5] = { 0, 0, 0, 0, 0 };
+ f->get_buffer((uint8_t *)header, 4);
- if (header[0] == 'G' && header[1] == 'D' && header[2] == '3' && header[3] == 'T') {
- if (tex3d.is_null()) {
- f->close();
- memdelete(f);
- ERR_FAIL_COND_V(tex3d.is_null(), RES())
- }
- } else if (header[0] == 'G' && header[1] == 'D' && header[2] == 'A' && header[3] == 'T') {
- if (texarr.is_null()) {
- f->close();
- memdelete(f);
- ERR_FAIL_COND_V(texarr.is_null(), RES())
+ if (String(header) != "GDLT") {
+ f->close();
+ memdelete(f);
+ if (r_error) {
+ *r_error = ERR_FILE_CORRUPT;
}
+ // FIXME: It's bogus that we fail in both branches. Seen while rebasing
+ // vulkan branch on master branch.
+ ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture.");
} else {
f->close();
@@ -2392,12 +2075,11 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String
int tw = f->get_32();
int th = f->get_32();
int td = f->get_32();
- int flags = f->get_32(); //texture flags!
+ bool use_mipmaps = f->get_32() != 0; //texture flags (deprecated)
Image::Format format = Image::Format(f->get_32());
uint32_t compression = f->get_32(); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
- lt->create(tw, th, td, format, flags);
-
+ Vector<Ref<Image> > images;
for (int layer = 0; layer < td; layer++) {
Ref<Image> image;
@@ -2470,8 +2152,8 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String
} else {
//look for regular format
- bool mipmaps = (flags & Texture::FLAG_MIPMAPS);
- int total_size = Image::get_image_data_size(tw, th, format, mipmaps);
+
+ int total_size = Image::get_image_data_size(tw, th, format, use_mipmaps);
PoolVector<uint8_t> img_data;
img_data.resize(total_size);
@@ -2489,35 +2171,47 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String
}
}
- image->create(tw, th, mipmaps, format, img_data);
+ image->create(tw, th, use_mipmaps, format, img_data);
}
- lt->set_layer_data(image, layer);
+ images.push_back(image);
}
- if (r_error)
- *r_error = OK;
+ Error err = lt->create_from_images(images);
+ if (err != OK) {
+ *r_error = err;
+ return RES();
+ } else {
+
+ if (r_error)
+ *r_error = OK;
+ }
return lt;
}
void ResourceFormatLoaderTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
- p_extensions->push_back("tex3d");
- p_extensions->push_back("texarr");
+ p_extensions->push_back("cube");
+ p_extensions->push_back("cubearr");
+ p_extensions->push_back("tex2darr");
}
bool ResourceFormatLoaderTextureLayered::handles_type(const String &p_type) const {
- return p_type == "Texture3D" || p_type == "TextureArray";
+ return p_type == "Texture2DArray" || p_type == "Cubemap" || p_type == "CubemapArray";
}
String ResourceFormatLoaderTextureLayered::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "tex3d")
- return "Texture3D";
- if (p_path.get_extension().to_lower() == "texarr")
- return "TextureArray";
+ if (p_path.get_extension().to_lower() == "cube")
+ return "Cubemap";
+ if (p_path.get_extension().to_lower() == "cubearr")
+ return "CubemapArray";
+ if (p_path.get_extension().to_lower() == "tex2darr")
+ return "Texture2DArray";
return "";
}
+///////////////////////////////
+
void CameraTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_camera_feed_id", "feed_id"), &CameraTexture::set_camera_feed_id);
ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &CameraTexture::get_camera_feed_id);
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index fa698d387b..b42b770903 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -33,6 +33,7 @@
#include "core/io/resource_loader.h"
#include "core/math/rect2.h"
+#include "core/os/file_access.h"
#include "core/os/mutex.h"
#include "core/os/rw_lock.h"
#include "core/os/thread_safe.h"
@@ -43,25 +44,21 @@
#include "servers/visual_server.h"
class Texture : public Resource {
-
GDCLASS(Texture, Resource);
- OBJ_SAVE_TYPE(Texture); // Saves derived classes with common type so they can be interchanged.
+
+public:
+ Texture() {}
+};
+
+class Texture2D : public Texture {
+
+ GDCLASS(Texture2D, Resource);
+ OBJ_SAVE_TYPE(Texture2D); // Saves derived classes with common type so they can be interchanged.
protected:
static void _bind_methods();
public:
- enum Flags {
- FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS,
- FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT,
- FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER,
- FLAG_ANISOTROPIC_FILTER = VisualServer::TEXTURE_FLAG_ANISOTROPIC_FILTER,
- FLAG_CONVERT_TO_LINEAR = VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR,
- FLAG_VIDEO_SURFACE = VisualServer::TEXTURE_FLAG_USED_FOR_STREAMING,
- FLAGS_DEFAULT = FLAG_MIPMAPS | FLAG_REPEAT | FLAG_FILTER,
- FLAG_MIRRORED_REPEAT = VisualServer::TEXTURE_FLAG_MIRRORED_REPEAT
- };
-
virtual int get_width() const = 0;
virtual int get_height() const = 0;
virtual Size2 get_size() const;
@@ -71,43 +68,28 @@ public:
virtual bool has_alpha() const = 0;
- virtual void set_flags(uint32_t p_flags) = 0;
- virtual uint32_t get_flags() const = 0;
-
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
virtual Ref<Image> get_data() const { return Ref<Image>(); }
- Texture();
+ Texture2D();
};
-VARIANT_ENUM_CAST(Texture::Flags);
-
class BitMap;
-class ImageTexture : public Texture {
+class ImageTexture : public Texture2D {
- GDCLASS(ImageTexture, Texture);
+ GDCLASS(ImageTexture, Texture2D);
RES_BASE_EXTENSION("tex");
-public:
- enum Storage {
- STORAGE_RAW,
- STORAGE_COMPRESS_LOSSY,
- STORAGE_COMPRESS_LOSSLESS
- };
-
-private:
- RID texture;
+ mutable RID texture;
Image::Format format;
- uint32_t flags;
+ bool mipmaps;
int w, h;
- Storage storage;
Size2 size_override;
- float lossy_storage_quality;
mutable Ref<BitMap> alpha_cache;
bool image_stored;
@@ -122,19 +104,12 @@ protected:
virtual void _resource_path_changed();
static void _bind_methods();
- void _set_data(Dictionary p_data);
-
public:
- void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT);
- void create_from_image(const Ref<Image> &p_image, uint32_t p_flags = FLAGS_DEFAULT);
+ void create_from_image(const Ref<Image> &p_image);
- void set_flags(uint32_t p_flags);
- uint32_t get_flags() const;
Image::Format get_format() const;
-#ifndef DISABLE_DEPRECATED
- Error load(const String &p_path);
-#endif
- void set_data(const Ref<Image> &p_image);
+
+ void update(const Ref<Image> &p_image, bool p_immediate = false);
Ref<Image> get_data() const;
int get_width() const;
@@ -143,17 +118,12 @@ public:
virtual RID get_rid() const;
bool has_alpha() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
- void set_storage(Storage p_storage);
- Storage get_storage() const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const;
bool is_pixel_opaque(int p_x, int p_y) const;
- void set_lossy_storage_quality(float p_lossy_storage_quality);
- float get_lossy_storage_quality() const;
-
void set_size_override(const Size2 &p_size);
virtual void set_path(const String &p_path, bool p_take_over = false);
@@ -162,15 +132,20 @@ public:
~ImageTexture();
};
-class StreamTexture : public Texture {
+class StreamTexture : public Texture2D {
- GDCLASS(StreamTexture, Texture);
+ GDCLASS(StreamTexture, Texture2D);
public:
enum DataFormat {
DATA_FORMAT_IMAGE,
DATA_FORMAT_LOSSLESS,
- DATA_FORMAT_LOSSY
+ DATA_FORMAT_LOSSY,
+ DATA_FORMAT_BASIS_UNIVERSAL,
+ };
+
+ enum {
+ FORMAT_VERSION = 1
};
enum FormatBits {
@@ -180,23 +155,23 @@ public:
FORMAT_BIT_STREAM = 1 << 22,
FORMAT_BIT_HAS_MIPMAPS = 1 << 23,
FORMAT_BIT_DETECT_3D = 1 << 24,
- FORMAT_BIT_DETECT_SRGB = 1 << 25,
+ //FORMAT_BIT_DETECT_SRGB = 1 << 25,
FORMAT_BIT_DETECT_NORMAL = 1 << 26,
+ FORMAT_BIT_DETECT_ROUGNESS = 1 << 27,
};
private:
- Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit = 0);
+ Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit = 0);
String path_to_file;
- RID texture;
+ mutable RID texture;
Image::Format format;
- uint32_t flags;
int w, h;
mutable Ref<BitMap> alpha_cache;
virtual void reload_from_file();
static void _requested_3d(void *p_ud);
- static void _requested_srgb(void *p_ud);
+ static void _requested_roughness(void *p_ud, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_roughness_channel);
static void _requested_normal(void *p_ud);
protected:
@@ -204,13 +179,15 @@ protected:
void _validate_property(PropertyInfo &property) const;
public:
+ static Ref<Image> load_image_from_file(FileAccess *p_file, int p_size_limit);
+
typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture> &);
+ typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<StreamTexture> &, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_roughness_channel);
static TextureFormatRequestCallback request_3d_callback;
- static TextureFormatRequestCallback request_srgb_callback;
+ static TextureFormatRoughnessRequestCallback request_roughness_callback;
static TextureFormatRequestCallback request_normal_callback;
- uint32_t get_flags() const;
Image::Format get_format() const;
Error load(const String &p_path);
String get_load_path() const;
@@ -221,12 +198,11 @@ public:
virtual void set_path(const String &p_path, bool p_take_over);
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const;
virtual bool has_alpha() const;
- virtual void set_flags(uint32_t p_flags);
bool is_pixel_opaque(int p_x, int p_y) const;
virtual Ref<Image> get_data() const;
@@ -243,15 +219,13 @@ public:
virtual String get_resource_type(const String &p_path) const;
};
-VARIANT_ENUM_CAST(ImageTexture::Storage);
-
-class AtlasTexture : public Texture {
+class AtlasTexture : public Texture2D {
- GDCLASS(AtlasTexture, Texture);
+ GDCLASS(AtlasTexture, Texture2D);
RES_BASE_EXTENSION("atlastex");
protected:
- Ref<Texture> atlas;
+ Ref<Texture2D> atlas;
Rect2 region;
Rect2 margin;
bool filter_clip;
@@ -265,11 +239,8 @@ public:
virtual bool has_alpha() const;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
- void set_atlas(const Ref<Texture> &p_atlas);
- Ref<Texture> get_atlas() const;
+ void set_atlas(const Ref<Texture2D> &p_atlas);
+ Ref<Texture2D> get_atlas() const;
void set_region(const Rect2 &p_region);
Rect2 get_region() const;
@@ -280,9 +251,9 @@ public:
void set_filter_clip(const bool p_enable);
bool has_filter_clip() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
bool is_pixel_opaque(int p_x, int p_y) const;
@@ -292,12 +263,12 @@ public:
class Mesh;
-class MeshTexture : public Texture {
+class MeshTexture : public Texture2D {
- GDCLASS(MeshTexture, Texture);
+ GDCLASS(MeshTexture, Texture2D);
RES_BASE_EXTENSION("meshtex");
- Ref<Texture> base_texture;
+ Ref<Texture2D> base_texture;
Ref<Mesh> mesh;
Size2i size;
@@ -311,21 +282,18 @@ public:
virtual bool has_alpha() const;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
void set_image_size(const Size2 &p_size);
Size2 get_image_size() const;
- void set_base_texture(const Ref<Texture> &p_texture);
- Ref<Texture> get_base_texture() const;
+ void set_base_texture(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_base_texture() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
bool is_pixel_opaque(int p_x, int p_y) const;
@@ -333,16 +301,16 @@ public:
MeshTexture();
};
-class LargeTexture : public Texture {
+class LargeTexture : public Texture2D {
- GDCLASS(LargeTexture, Texture);
+ GDCLASS(LargeTexture, Texture2D);
RES_BASE_EXTENSION("largetex");
protected:
struct Piece {
Point2 offset;
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
};
Vector<Piece> pieces;
@@ -359,179 +327,90 @@ public:
virtual bool has_alpha() const;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
- int add_piece(const Point2 &p_offset, const Ref<Texture> &p_texture);
+ int add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_texture);
void set_piece_offset(int p_idx, const Point2 &p_offset);
- void set_piece_texture(int p_idx, const Ref<Texture> &p_texture);
+ void set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture);
void set_size(const Size2 &p_size);
void clear();
int get_piece_count() const;
Vector2 get_piece_offset(int p_idx) const;
- Ref<Texture> get_piece_texture(int p_idx) const;
+ Ref<Texture2D> get_piece_texture(int p_idx) const;
Ref<Image> to_image() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const;
bool is_pixel_opaque(int p_x, int p_y) const;
LargeTexture();
};
-class CubeMap : public Resource {
-
- GDCLASS(CubeMap, Resource);
- RES_BASE_EXTENSION("cubemap");
-
-public:
- enum Storage {
- STORAGE_RAW,
- STORAGE_COMPRESS_LOSSY,
- STORAGE_COMPRESS_LOSSLESS
- };
-
- enum Side {
-
- SIDE_LEFT,
- SIDE_RIGHT,
- SIDE_BOTTOM,
- SIDE_TOP,
- SIDE_FRONT,
- SIDE_BACK
- };
-
- enum Flags {
- FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS,
- FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT,
- FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER,
- FLAGS_DEFAULT = FLAG_MIPMAPS | FLAG_REPEAT | FLAG_FILTER,
- };
-
-private:
- bool valid[6];
- RID cubemap;
- Image::Format format;
- uint32_t flags;
- int w, h;
- Storage storage;
- Size2 size_override;
- float lossy_storage_quality;
-
- _FORCE_INLINE_ bool _is_valid() const {
- for (int i = 0; i < 6; i++) {
- if (valid[i]) return true;
- }
- return false;
- }
-
-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();
-
-public:
- void set_flags(uint32_t p_flags);
- uint32_t get_flags() const;
- void set_side(Side p_side, const Ref<Image> &p_image);
- Ref<Image> get_side(Side p_side) const;
-
- Image::Format get_format() const;
- int get_width() const;
- int get_height() const;
-
- virtual RID get_rid() const;
-
- void set_storage(Storage p_storage);
- Storage get_storage() const;
-
- void set_lossy_storage_quality(float p_lossy_storage_quality);
- float get_lossy_storage_quality() const;
-
- virtual void set_path(const String &p_path, bool p_take_over = false);
-
- CubeMap();
- ~CubeMap();
-};
-
-VARIANT_ENUM_CAST(CubeMap::Flags)
-VARIANT_ENUM_CAST(CubeMap::Side)
-VARIANT_ENUM_CAST(CubeMap::Storage)
-
-class TextureLayered : public Resource {
+class TextureLayered : public Texture {
GDCLASS(TextureLayered, Resource);
-public:
- enum Flags {
- FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS,
- FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT,
- FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER,
- FLAG_CONVERT_TO_LINEAR = VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR,
- FLAGS_DEFAULT = FLAG_FILTER,
- };
+ VS::TextureLayeredType layered_type;
-private:
- bool is_3d;
- RID texture;
+ mutable RID texture;
Image::Format format;
- uint32_t flags;
int width;
int height;
- int depth;
+ int layers;
+ bool mipmaps;
- void _set_data(const Dictionary &p_data);
- Dictionary _get_data() const;
+ Error _create_from_images(const Array &p_images);
+
+ Array _get_images() const;
protected:
static void _bind_methods();
public:
- void set_flags(uint32_t p_flags);
- uint32_t get_flags() const;
-
Image::Format get_format() const;
uint32_t get_width() const;
uint32_t get_height() const;
- uint32_t get_depth() const;
+ uint32_t get_layers() const;
+ bool has_mipmaps() const;
- void create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT);
- void set_layer_data(const Ref<Image> &p_image, int p_layer);
+ Error create_from_images(Vector<Ref<Image> > p_images);
+ void update_layer(const Ref<Image> &p_image, int p_layer);
Ref<Image> get_layer_data(int p_layer) const;
- void set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap = 0);
virtual RID get_rid() const;
virtual void set_path(const String &p_path, bool p_take_over = false);
- TextureLayered(bool p_3d = false);
+ TextureLayered(VS::TextureLayeredType p_layered_type);
~TextureLayered();
};
-VARIANT_ENUM_CAST(TextureLayered::Flags)
+class Texture2DArray : public TextureLayered {
-class Texture3D : public TextureLayered {
+ GDCLASS(Texture2DArray, TextureLayered)
+public:
+ Texture2DArray() :
+ TextureLayered(VS::TEXTURE_LAYERED_2D_ARRAY) {}
+};
+
+class Cubemap : public TextureLayered {
- GDCLASS(Texture3D, TextureLayered);
+ GDCLASS(Cubemap, TextureLayered);
public:
- Texture3D() :
- TextureLayered(true) {}
+ Cubemap() :
+ TextureLayered(VS::TEXTURE_LAYERED_CUBEMAP) {}
};
-class TextureArray : public TextureLayered {
+class CubemapArray : public TextureLayered {
- GDCLASS(TextureArray, TextureLayered);
+ GDCLASS(CubemapArray, TextureLayered);
public:
- TextureArray() :
- TextureLayered(false) {}
+ CubemapArray() :
+ TextureLayered(VS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {}
};
class ResourceFormatLoaderTextureLayered : public ResourceFormatLoader {
@@ -548,13 +427,13 @@ public:
virtual String get_resource_type(const String &p_path) const;
};
-class CurveTexture : public Texture {
+class CurveTexture : public Texture2D {
- GDCLASS(CurveTexture, Texture);
+ GDCLASS(CurveTexture, Texture2D);
RES_BASE_EXTENSION("curvetex")
private:
- RID _texture;
+ mutable RID _texture;
Ref<Curve> _curve;
int _width;
@@ -577,9 +456,6 @@ public:
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();
};
@@ -597,8 +473,8 @@ public:
*/
//VARIANT_ENUM_CAST( Texture::CubeMapSide );
-class GradientTexture : public Texture {
- GDCLASS(GradientTexture, Texture);
+class GradientTexture : public Texture2D {
+ GDCLASS(GradientTexture, Texture2D);
public:
struct Point {
@@ -633,28 +509,26 @@ public:
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; }
-
virtual Ref<Image> get_data() const;
GradientTexture();
virtual ~GradientTexture();
};
-class ProxyTexture : public Texture {
- GDCLASS(ProxyTexture, Texture);
+class ProxyTexture : public Texture2D {
+ GDCLASS(ProxyTexture, Texture2D);
private:
- RID proxy;
- Ref<Texture> base;
+ mutable RID proxy_ph;
+ mutable RID proxy;
+ Ref<Texture2D> base;
protected:
static void _bind_methods();
public:
- void set_base(const Ref<Texture> &p_texture);
- Ref<Texture> get_base() const;
+ void set_base(const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_base() const;
virtual int get_width() const;
virtual int get_height() const;
@@ -662,15 +536,12 @@ public:
virtual bool has_alpha() const;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
ProxyTexture();
~ProxyTexture();
};
-class AnimatedTexture : public Texture {
- GDCLASS(AnimatedTexture, Texture);
+class AnimatedTexture : public Texture2D {
+ GDCLASS(AnimatedTexture, Texture2D);
//use readers writers lock for this, since its far more times read than written to
RWLock *rw_lock;
@@ -680,11 +551,12 @@ private:
MAX_FRAMES = 256
};
+ RID proxy_ph;
RID proxy;
struct Frame {
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
float delay_sec;
Frame() {
@@ -712,8 +584,8 @@ public:
void set_frames(int p_frames);
int get_frames() const;
- void set_frame_texture(int p_frame, const Ref<Texture> &p_texture);
- Ref<Texture> get_frame_texture(int p_frame) const;
+ void set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> get_frame_texture(int p_frame) const;
void set_frame_delay(int p_frame, float p_delay_sec);
float get_frame_delay(int p_frame) const;
@@ -727,9 +599,6 @@ public:
virtual bool has_alpha() const;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
virtual Ref<Image> get_data() const;
bool is_pixel_opaque(int p_x, int p_y) const;
@@ -738,8 +607,8 @@ public:
~AnimatedTexture();
};
-class CameraTexture : public Texture {
- GDCLASS(CameraTexture, Texture);
+class CameraTexture : public Texture2D {
+ GDCLASS(CameraTexture, Texture2D);
private:
int camera_feed_id;
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 1f2fa1d60b..75903c1383 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -196,7 +196,7 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
if (type == "icons") {
if (!has_icon(name, node_type))
- r_ret = Ref<Texture>();
+ r_ret = Ref<Texture2D>();
else
r_ret = get_icon(name, node_type);
} else if (type == "styles") {
@@ -238,7 +238,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
while ((key2 = icon_map[*key].next(key2))) {
- list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
+ list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
}
}
@@ -322,7 +322,7 @@ Ref<Font> Theme::get_default_theme_font() const {
Ref<Theme> Theme::project_default_theme;
Ref<Theme> Theme::default_theme;
-Ref<Texture> Theme::default_icon;
+Ref<Texture2D> Theme::default_icon;
Ref<StyleBox> Theme::default_style;
Ref<Font> Theme::default_font;
@@ -346,7 +346,7 @@ void Theme::set_project_default(const Ref<Theme> &p_project_default) {
project_default_theme = p_project_default;
}
-void Theme::set_default_icon(const Ref<Texture> &p_icon) {
+void Theme::set_default_icon(const Ref<Texture2D> &p_icon) {
default_icon = p_icon;
}
@@ -359,7 +359,7 @@ void Theme::set_default_font(const Ref<Font> &p_font) {
default_font = p_font;
}
-void Theme::set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture> &p_icon) {
+void Theme::set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture2D> &p_icon) {
//ERR_FAIL_COND(p_icon.is_null());
@@ -380,7 +380,7 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_type, const R
emit_changed();
}
}
-Ref<Texture> Theme::get_icon(const StringName &p_name, const StringName &p_type) const {
+Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_type) const {
if (icon_map.has(p_type) && icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) {
@@ -720,7 +720,7 @@ void Theme::clear() {
while ((K = icon_map.next(K))) {
const StringName *L = NULL;
while ((L = icon_map[*K].next(L))) {
- Ref<Texture> icon = icon_map[*K][*L];
+ Ref<Texture2D> icon = icon_map[*K][*L];
if (icon.is_valid()) {
icon->disconnect("changed", this, "_emit_theme_changed");
}
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 4bb614b24e..e60734b144 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -45,7 +45,7 @@ class Theme : public Resource {
void _emit_theme_changed();
- HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map;
+ HashMap<StringName, HashMap<StringName, Ref<Texture2D> > > icon_map;
HashMap<StringName, HashMap<StringName, Ref<StyleBox> > > style_map;
HashMap<StringName, HashMap<StringName, Ref<Font> > > font_map;
HashMap<StringName, HashMap<StringName, Ref<Shader> > > shader_map;
@@ -67,7 +67,7 @@ protected:
static Ref<Theme> project_default_theme;
static Ref<Theme> default_theme;
- static Ref<Texture> default_icon;
+ static Ref<Texture2D> default_icon;
static Ref<StyleBox> default_style;
static Ref<Font> default_font;
@@ -82,15 +82,15 @@ public:
static Ref<Theme> get_project_default();
static void set_project_default(const Ref<Theme> &p_project_default);
- static void set_default_icon(const Ref<Texture> &p_icon);
+ static void set_default_icon(const Ref<Texture2D> &p_icon);
static void set_default_style(const Ref<StyleBox> &p_style);
static void set_default_font(const Ref<Font> &p_font);
void set_default_theme_font(const Ref<Font> &p_default_font);
Ref<Font> get_default_theme_font() const;
- void set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture> &p_icon);
- Ref<Texture> get_icon(const StringName &p_name, const StringName &p_type) const;
+ void set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_type) const;
bool has_icon(const StringName &p_name, const StringName &p_type) const;
void clear_icon(const StringName &p_name, const StringName &p_type);
void get_icon_list(StringName p_type, List<StringName> *p_list) const;
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 555e90ed3c..7383e18473 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -325,14 +325,14 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
int id = E->key();
String pre = itos(id) + "/";
- 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::OBJECT, pre + "normal_map", 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, "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::INT, pre + "tile_mode", PROPERTY_HINT_ENUM, "SINGLE_TILE,AUTO_TILE,ATLAS_TILE"));
+ p_list->push_back(PropertyInfo(Variant::STRING, pre + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "tex_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::COLOR, pre + "modulate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::RECT2, pre + "region", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "tile_mode", PROPERTY_HINT_ENUM, "SINGLE_TILE,AUTO_TILE,ATLAS_TILE", PROPERTY_USAGE_NOEDITOR));
if (tile_get_tile_mode(id) == AUTO_TILE) {
p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/bitmask_mode", PROPERTY_HINT_ENUM, "2X2,3X3 (minimal),3X3", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/bitmask_flags", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
@@ -352,17 +352,17 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/z_index_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "navigation_offset"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "navigation", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::BOOL, pre + "shape_one_way", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::REAL, pre + "shape_one_way_margin", PROPERTY_HINT_RANGE, "0,128,0.01", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "navigation_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "navigation", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::BOOL, pre + "shape_one_way", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::REAL, pre + "shape_one_way_margin", PROPERTY_HINT_RANGE, "0,128,0.01", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "shapes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::INT, pre + "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"));
+ p_list->push_back(PropertyInfo(Variant::INT, pre + "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1", PROPERTY_USAGE_NOEDITOR));
}
}
@@ -387,7 +387,7 @@ TileSet::BitmaskMode TileSet::autotile_get_bitmask_mode(int p_id) const {
return tile_map[p_id].autotile_data.bitmask_mode;
}
-void TileSet::tile_set_texture(int p_id, const Ref<Texture> &p_texture) {
+void TileSet::tile_set_texture(int p_id, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].texture = p_texture;
@@ -395,22 +395,22 @@ void TileSet::tile_set_texture(int p_id, const Ref<Texture> &p_texture) {
_change_notify("texture");
}
-Ref<Texture> TileSet::tile_get_texture(int p_id) const {
+Ref<Texture2D> TileSet::tile_get_texture(int p_id) const {
- ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture>());
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture2D>());
return tile_map[p_id].texture;
}
-void TileSet::tile_set_normal_map(int p_id, const Ref<Texture> &p_normal_map) {
+void TileSet::tile_set_normal_map(int p_id, const Ref<Texture2D> &p_normal_map) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].normal_map = p_normal_map;
emit_changed();
}
-Ref<Texture> TileSet::tile_get_normal_map(int p_id) const {
+Ref<Texture2D> TileSet::tile_get_normal_map(int p_id) const {
- ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture>());
+ ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture2D>());
return tile_map[p_id].normal_map;
}
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index eab40ce467..8b540982a4 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -114,8 +114,8 @@ private:
struct TileData {
String name;
- Ref<Texture> texture;
- Ref<Texture> normal_map;
+ Ref<Texture2D> texture;
+ Ref<Texture2D> normal_map;
Vector2 offset;
Rect2i region;
Vector<ShapeData> shapes_data;
@@ -158,11 +158,11 @@ public:
void tile_set_name(int p_id, const String &p_name);
String tile_get_name(int p_id) const;
- void tile_set_texture(int p_id, const Ref<Texture> &p_texture);
- Ref<Texture> tile_get_texture(int p_id) const;
+ void tile_set_texture(int p_id, const Ref<Texture2D> &p_texture);
+ Ref<Texture2D> tile_get_texture(int p_id) const;
- void tile_set_normal_map(int p_id, const Ref<Texture> &p_normal_map);
- Ref<Texture> tile_get_normal_map(int p_id) const;
+ void tile_set_normal_map(int p_id, const Ref<Texture2D> &p_normal_map);
+ Ref<Texture2D> tile_get_normal_map(int p_id) const;
void tile_set_texture_offset(int p_id, const Vector2 &p_offset);
Vector2 tile_get_texture_offset(int p_id) const;
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index 444bb698ae..a9b96214c3 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -58,7 +58,8 @@ public:
virtual void set_audio_track(int p_idx) = 0;
- virtual Ref<Texture> get_texture() const = 0;
+ virtual Ref<Texture2D> get_texture() const = 0;
+
virtual void update(float p_delta) = 0;
virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata) = 0;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index d8cac0c202..f80fe9f791 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -276,6 +276,7 @@ void VisualShaderNodeCustom::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_port_name", PropertyInfo(Variant::INT, "port")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_code", PropertyInfo(Variant::ARRAY, "input_vars"), PropertyInfo(Variant::ARRAY, "output_vars"), PropertyInfo(Variant::INT, "mode"), PropertyInfo(Variant::INT, "type")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_global_code", PropertyInfo(Variant::INT, "mode")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_highend"));
}
VisualShaderNodeCustom::VisualShaderNodeCustom() {
@@ -2644,7 +2645,7 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
code += output_initializer;
code += "\t{";
code += _expression;
- code += "\n\t}";
+ code += "\n\t}\n";
return code;
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index f35318e090..1ee75a4cb7 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -58,7 +58,7 @@ public:
struct DefaultTextureParam {
StringName name;
- Ref<Texture> param;
+ Ref<Texture2D> param;
};
private:
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index a22bb34d12..95a8155c31 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -357,7 +357,7 @@ VisualShaderNodeTransformConstant::VisualShaderNodeTransformConstant() {
////////////// Texture
String VisualShaderNodeTexture::get_caption() const {
- return "Texture";
+ return "Texture2D";
}
int VisualShaderNodeTexture::get_input_port_count() const {
@@ -649,13 +649,13 @@ VisualShaderNodeTexture::Source VisualShaderNodeTexture::get_source() const {
return source;
}
-void VisualShaderNodeTexture::set_texture(Ref<Texture> p_value) {
+void VisualShaderNodeTexture::set_texture(Ref<Texture2D> p_value) {
texture = p_value;
emit_changed();
}
-Ref<Texture> VisualShaderNodeTexture::get_texture() const {
+Ref<Texture2D> VisualShaderNodeTexture::get_texture() const {
return texture;
}
@@ -727,7 +727,7 @@ void VisualShaderNodeTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTexture::get_texture_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort"), "set_source", "get_source");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type");
BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
@@ -746,17 +746,17 @@ VisualShaderNodeTexture::VisualShaderNodeTexture() {
source = SOURCE_TEXTURE;
}
-////////////// CubeMap
+////////////// Cubemap
-String VisualShaderNodeCubeMap::get_caption() const {
- return "CubeMap";
+String VisualShaderNodeCubemap::get_caption() const {
+ return "Cubemap";
}
-int VisualShaderNodeCubeMap::get_input_port_count() const {
+int VisualShaderNodeCubemap::get_input_port_count() const {
return 3;
}
-VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const {
+VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_input_port_type(int p_port) const {
switch (p_port) {
case 0:
return PORT_TYPE_VECTOR;
@@ -769,7 +769,7 @@ VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(i
}
}
-String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
+String VisualShaderNodeCubemap::get_input_port_name(int p_port) const {
switch (p_port) {
case 0:
return "uv";
@@ -782,19 +782,19 @@ String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
}
}
-int VisualShaderNodeCubeMap::get_output_port_count() const {
+int VisualShaderNodeCubemap::get_output_port_count() const {
return 2;
}
-VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_output_port_type(int p_port) const {
+VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
-String VisualShaderNodeCubeMap::get_output_port_name(int p_port) const {
+String VisualShaderNodeCubemap::get_output_port_name(int p_port) const {
return p_port == 0 ? "rgb" : "alpha";
}
-Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubemap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
VisualShader::DefaultTextureParam dtp;
dtp.name = make_unique_id(p_type, p_id, "cube");
dtp.param = cube_map;
@@ -803,7 +803,7 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_t
return ret;
}
-String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
if (source == SOURCE_TEXTURE) {
String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube");
@@ -817,7 +817,7 @@ String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShade
return String();
}
-String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
String id;
@@ -860,44 +860,44 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader:
return code;
}
-String VisualShaderNodeCubeMap::get_input_port_default_hint(int p_port) const {
+String VisualShaderNodeCubemap::get_input_port_default_hint(int p_port) const {
if (p_port == 0) {
return "vec3(UV, 0.0)";
}
return "";
}
-void VisualShaderNodeCubeMap::set_source(Source p_source) {
+void VisualShaderNodeCubemap::set_source(Source p_source) {
source = p_source;
emit_changed();
emit_signal("editor_refresh_request");
}
-VisualShaderNodeCubeMap::Source VisualShaderNodeCubeMap::get_source() const {
+VisualShaderNodeCubemap::Source VisualShaderNodeCubemap::get_source() const {
return source;
}
-void VisualShaderNodeCubeMap::set_cube_map(Ref<CubeMap> p_value) {
+void VisualShaderNodeCubemap::set_cube_map(Ref<Cubemap> p_value) {
cube_map = p_value;
emit_changed();
}
-Ref<CubeMap> VisualShaderNodeCubeMap::get_cube_map() const {
+Ref<Cubemap> VisualShaderNodeCubemap::get_cube_map() const {
return cube_map;
}
-void VisualShaderNodeCubeMap::set_texture_type(TextureType p_type) {
+void VisualShaderNodeCubemap::set_texture_type(TextureType p_type) {
texture_type = p_type;
emit_changed();
}
-VisualShaderNodeCubeMap::TextureType VisualShaderNodeCubeMap::get_texture_type() const {
+VisualShaderNodeCubemap::TextureType VisualShaderNodeCubemap::get_texture_type() const {
return texture_type;
}
-Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const {
+Vector<StringName> VisualShaderNodeCubemap::get_editable_properties() const {
Vector<StringName> props;
props.push_back("source");
if (source == SOURCE_TEXTURE) {
@@ -907,19 +907,19 @@ Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const {
return props;
}
-void VisualShaderNodeCubeMap::_bind_methods() {
+void VisualShaderNodeCubemap::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubeMap::set_source);
- ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubeMap::get_source);
+ ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubemap::set_source);
+ ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubemap::get_source);
- ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubeMap::set_cube_map);
- ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubeMap::get_cube_map);
+ ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubemap::set_cube_map);
+ ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubemap::get_cube_map);
- ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubeMap::set_texture_type);
- ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubeMap::get_texture_type);
+ ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubemap::set_texture_type);
+ ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubemap::get_texture_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "CubeMap"), "set_cube_map", "get_cube_map");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "Cubemap"), "set_cube_map", "get_cube_map");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type");
BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
@@ -930,7 +930,7 @@ void VisualShaderNodeCubeMap::_bind_methods() {
BIND_ENUM_CONSTANT(TYPE_NORMALMAP);
}
-VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() {
+VisualShaderNodeCubemap::VisualShaderNodeCubemap() {
texture_type = TYPE_DATA;
source = SOURCE_TEXTURE;
simple_decl = false;
@@ -3039,6 +3039,11 @@ String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const {
}
String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ if (hint == HINT_RANGE) {
+ return "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
+ } else if (hint == HINT_RANGE_STEP) {
+ return "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
+ }
return "uniform float " + get_uniform_name() + ";\n";
}
@@ -3046,7 +3051,83 @@ String VisualShaderNodeScalarUniform::generate_code(Shader::Mode p_mode, VisualS
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+void VisualShaderNodeScalarUniform::set_hint(Hint p_hint) {
+ hint = p_hint;
+ emit_changed();
+}
+
+VisualShaderNodeScalarUniform::Hint VisualShaderNodeScalarUniform::get_hint() const {
+ return hint;
+}
+
+void VisualShaderNodeScalarUniform::set_min(float p_value) {
+ hint_range_min = p_value;
+ emit_changed();
+}
+
+float VisualShaderNodeScalarUniform::get_min() const {
+ return hint_range_min;
+}
+
+void VisualShaderNodeScalarUniform::set_max(float p_value) {
+ hint_range_max = p_value;
+ emit_changed();
+}
+
+float VisualShaderNodeScalarUniform::get_max() const {
+ return hint_range_max;
+}
+
+void VisualShaderNodeScalarUniform::set_step(float p_value) {
+ hint_range_step = p_value;
+ emit_changed();
+}
+
+float VisualShaderNodeScalarUniform::get_step() const {
+ return hint_range_step;
+}
+
+void VisualShaderNodeScalarUniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeScalarUniform::set_hint);
+ ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeScalarUniform::get_hint);
+
+ ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeScalarUniform::set_min);
+ ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeScalarUniform::get_min);
+
+ ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeScalarUniform::set_max);
+ ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeScalarUniform::get_max);
+
+ ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeScalarUniform::set_step);
+ ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeScalarUniform::get_step);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "min"), "set_min", "get_min");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "max"), "set_max", "get_max");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "step"), "set_step", "get_step");
+
+ BIND_ENUM_CONSTANT(HINT_NONE);
+ BIND_ENUM_CONSTANT(HINT_RANGE);
+ BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
+}
+
+Vector<StringName> VisualShaderNodeScalarUniform::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("hint");
+ if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
+ props.push_back("min");
+ props.push_back("max");
+ }
+ if (hint == HINT_RANGE_STEP) {
+ props.push_back("step");
+ }
+ return props;
+}
+
VisualShaderNodeScalarUniform::VisualShaderNodeScalarUniform() {
+ hint = HINT_NONE;
+ hint_range_min = 0.0;
+ hint_range_max = 1.0;
+ hint_range_step = 0.1;
}
////////////// Boolean Uniform
@@ -3471,41 +3552,41 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_default_hint(int
VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() {
}
-////////////// CubeMap Uniform
+////////////// Cubemap Uniform
-String VisualShaderNodeCubeMapUniform::get_caption() const {
- return "CubeMapUniform";
+String VisualShaderNodeCubemapUniform::get_caption() const {
+ return "CubemapUniform";
}
-int VisualShaderNodeCubeMapUniform::get_output_port_count() const {
+int VisualShaderNodeCubemapUniform::get_output_port_count() const {
return 1;
}
-VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const {
+VisualShaderNodeCubemapUniform::PortType VisualShaderNodeCubemapUniform::get_output_port_type(int p_port) const {
return PORT_TYPE_SAMPLER;
}
-String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const {
+String VisualShaderNodeCubemapUniform::get_output_port_name(int p_port) const {
return "samplerCube";
}
-int VisualShaderNodeCubeMapUniform::get_input_port_count() const {
+int VisualShaderNodeCubemapUniform::get_input_port_count() const {
return 0;
}
-VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const {
+VisualShaderNodeCubemapUniform::PortType VisualShaderNodeCubemapUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const {
+String VisualShaderNodeCubemapUniform::get_input_port_name(int p_port) const {
return "";
}
-String VisualShaderNodeCubeMapUniform::get_input_port_default_hint(int p_port) const {
+String VisualShaderNodeCubemapUniform::get_input_port_default_hint(int p_port) const {
return "";
}
-String VisualShaderNodeCubeMapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code = "uniform samplerCube " + get_uniform_name();
switch (texture_type) {
@@ -3528,11 +3609,11 @@ String VisualShaderNodeCubeMapUniform::generate_global(Shader::Mode p_mode, Visu
return code;
}
-String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeCubemapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return String();
}
-VisualShaderNodeCubeMapUniform::VisualShaderNodeCubeMapUniform() {
+VisualShaderNodeCubemapUniform::VisualShaderNodeCubemapUniform() {
}
////////////// If
@@ -3764,7 +3845,7 @@ String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader:
view = p_input_vars[1];
}
- return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));";
+ return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n";
}
String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const {
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index cca37273d9..85782bc509 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -191,7 +191,7 @@ public:
class VisualShaderNodeTexture : public VisualShaderNode {
GDCLASS(VisualShaderNodeTexture, VisualShaderNode);
- Ref<Texture> texture;
+ Ref<Texture2D> texture;
public:
enum Source {
@@ -236,8 +236,8 @@ public:
void set_source(Source p_source);
Source get_source() const;
- void set_texture(Ref<Texture> p_value);
- Ref<Texture> get_texture() const;
+ void set_texture(Ref<Texture2D> p_value);
+ Ref<Texture2D> get_texture() const;
void set_texture_type(TextureType p_type);
TextureType get_texture_type() const;
@@ -254,9 +254,9 @@ VARIANT_ENUM_CAST(VisualShaderNodeTexture::Source)
///////////////////////////////////////
-class VisualShaderNodeCubeMap : public VisualShaderNode {
- GDCLASS(VisualShaderNodeCubeMap, VisualShaderNode);
- Ref<CubeMap> cube_map;
+class VisualShaderNodeCubemap : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeCubemap, VisualShaderNode);
+ Ref<Cubemap> cube_map;
public:
enum Source {
@@ -296,19 +296,19 @@ public:
void set_source(Source p_source);
Source get_source() const;
- void set_cube_map(Ref<CubeMap> p_value);
- Ref<CubeMap> get_cube_map() const;
+ void set_cube_map(Ref<Cubemap> p_value);
+ Ref<Cubemap> get_cube_map() const;
void set_texture_type(TextureType p_type);
TextureType get_texture_type() const;
virtual Vector<StringName> get_editable_properties() const;
- VisualShaderNodeCubeMap();
+ VisualShaderNodeCubemap();
};
-VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::TextureType)
-VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::Source)
+VARIANT_ENUM_CAST(VisualShaderNodeCubemap::TextureType)
+VARIANT_ENUM_CAST(VisualShaderNodeCubemap::Source)
///////////////////////////////////////
/// OPS
@@ -1301,6 +1301,22 @@ class VisualShaderNodeScalarUniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeScalarUniform, VisualShaderNodeUniform);
public:
+ enum Hint {
+ HINT_NONE,
+ HINT_RANGE,
+ HINT_RANGE_STEP,
+ };
+
+private:
+ Hint hint;
+ float hint_range_min;
+ float hint_range_max;
+ float hint_range_step;
+
+protected:
+ static void _bind_methods();
+
+public:
virtual String get_caption() const;
virtual int get_input_port_count() const;
@@ -1314,9 +1330,25 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ void set_hint(Hint p_hint);
+ Hint get_hint() const;
+
+ void set_min(float p_value);
+ float get_min() const;
+
+ void set_max(float p_value);
+ float get_max() const;
+
+ void set_step(float p_value);
+ float get_step() const;
+
+ virtual Vector<StringName> get_editable_properties() const;
+
VisualShaderNodeScalarUniform();
};
+VARIANT_ENUM_CAST(VisualShaderNodeScalarUniform::Hint)
+
///////////////////////////////////////
class VisualShaderNodeBooleanUniform : public VisualShaderNodeUniform {
@@ -1482,8 +1514,8 @@ public:
///////////////////////////////////////
-class VisualShaderNodeCubeMapUniform : public VisualShaderNodeTextureUniform {
- GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNodeTextureUniform);
+class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform {
+ GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform);
public:
virtual String get_caption() const;
@@ -1500,7 +1532,7 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeCubeMapUniform();
+ VisualShaderNodeCubemapUniform();
};
///////////////////////////////////////
diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp
index 1099852098..78c08080b5 100644
--- a/scene/resources/world.cpp
+++ b/scene/resources/world.cpp
@@ -262,6 +262,7 @@ RID World::get_space() const {
return space;
}
+
RID World::get_scenario() const {
return scenario;
@@ -305,6 +306,20 @@ Ref<Environment> World::get_fallback_environment() const {
return fallback_environment;
}
+void World::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) {
+
+ camera_effects = p_camera_effects;
+ if (camera_effects.is_valid())
+ VS::get_singleton()->scenario_set_camera_effects(scenario, camera_effects->get_rid());
+ else
+ VS::get_singleton()->scenario_set_camera_effects(scenario, RID());
+}
+
+Ref<CameraEffects> World::get_camera_effects() const {
+
+ return camera_effects;
+}
+
PhysicsDirectSpaceState *World::get_direct_space_state() {
return PhysicsServer::get_singleton()->space_get_direct_state(space);
@@ -325,9 +340,12 @@ void World::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_environment"), &World::get_environment);
ClassDB::bind_method(D_METHOD("set_fallback_environment", "env"), &World::set_fallback_environment);
ClassDB::bind_method(D_METHOD("get_fallback_environment"), &World::get_fallback_environment);
+ ClassDB::bind_method(D_METHOD("set_camera_effects", "env"), &World::set_camera_effects);
+ ClassDB::bind_method(D_METHOD("get_camera_effects"), &World::get_camera_effects);
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World::get_direct_space_state);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects");
ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
ADD_PROPERTY(PropertyInfo(Variant::_RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState", 0), "", "get_direct_space_state");
diff --git a/scene/resources/world.h b/scene/resources/world.h
index b6248b28c8..6fd79abaaf 100644
--- a/scene/resources/world.h
+++ b/scene/resources/world.h
@@ -50,6 +50,7 @@ private:
SpatialIndexer *indexer;
Ref<Environment> environment;
Ref<Environment> fallback_environment;
+ Ref<CameraEffects> camera_effects;
protected:
static void _bind_methods();
@@ -77,6 +78,9 @@ public:
void set_fallback_environment(const Ref<Environment> &p_environment);
Ref<Environment> get_fallback_environment() const;
+ void set_camera_effects(const Ref<CameraEffects> &p_camera_effects);
+ Ref<CameraEffects> get_camera_effects() const;
+
void get_camera_list(List<Camera *> *r_cameras);
PhysicsDirectSpaceState *get_direct_space_state();