summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp62
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h5
-rw-r--r--drivers/gles3/shaders/copy.glsl5
-rw-r--r--editor/script_create_dialog.cpp2
-rw-r--r--scene/2d/collision_object_2d.cpp4
-rw-r--r--scene/2d/physics_body_2d.cpp422
-rw-r--r--scene/2d/physics_body_2d.h78
-rw-r--r--scene/3d/scenario_fx.cpp35
-rw-r--r--scene/3d/scenario_fx.h4
-rw-r--r--scene/gui/rich_text_label.cpp4
-rw-r--r--scene/main/viewport.cpp11
-rw-r--r--servers/physics_2d/space_2d_sw.cpp1
-rw-r--r--servers/physics_2d_server.h1
-rw-r--r--servers/visual/rasterizer.h4
-rw-r--r--servers/visual/visual_server_scene.cpp12
-rw-r--r--servers/visual/visual_server_scene.h1
-rw-r--r--servers/visual/visual_server_viewport.cpp68
17 files changed, 351 insertions, 368 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 913aa62452..96c3da99f0 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -977,6 +977,27 @@ void RasterizerSceneGLES3::environment_set_fog_height(RID p_env, bool p_enable,
env->fog_height_curve = p_height_curve;
}
+bool RasterizerSceneGLES3::is_environment(RID p_env) {
+
+ return environment_owner.owns(p_env);
+}
+
+VS::EnvironmentBG RasterizerSceneGLES3::environment_get_background(RID p_env) {
+
+ const Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, VS::ENV_BG_MAX);
+
+ return env->bg_mode;
+}
+
+int RasterizerSceneGLES3::environment_get_canvas_max_layer(RID p_env) {
+
+ const Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, -1);
+
+ return env->canvas_max_layer;
+}
+
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
LightInstance *light_instance = memnew(LightInstance);
@@ -3561,7 +3582,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
glUniform2iv(state.exposure_shader.get_uniform(ExposureShaderGLES3::SOURCE_RENDER_SIZE), 1, ss);
glUniform2iv(state.exposure_shader.get_uniform(ExposureShaderGLES3::TARGET_SIZE), 1, ds);
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->buffers.diffuse);
+ glBindTexture(GL_TEXTURE_2D, composite_from);
glBindFramebuffer(GL_FRAMEBUFFER, exposure_shrink[0].fbo);
glViewport(0, 0, exposure_shrink_size, exposure_shrink_size);
@@ -3957,6 +3978,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS];
use_mrt = use_mrt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW;
+ use_mrt = use_mrt && env && (env->bg_mode != VS::ENV_BG_KEEP && env->bg_mode != VS::ENV_BG_CANVAS);
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
@@ -4020,6 +4042,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
storage->frame.clear_request = false;
}
+ } else if (env->bg_mode == VS::ENV_BG_CANVAS) {
+
+ clear_color = env->bg_color.to_linear();
+ storage->frame.clear_request = false;
} else if (env->bg_mode == VS::ENV_BG_COLOR) {
clear_color = env->bg_color.to_linear();
@@ -4037,7 +4063,39 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
storage->frame.clear_request = false;
}
- glClearBufferfv(GL_COLOR, 0, clear_color.components); // specular
+ if (!env || env->bg_mode != VS::ENV_BG_KEEP) {
+ glClearBufferfv(GL_COLOR, 0, clear_color.components); // specular
+ }
+
+ if (env && env->bg_mode == VS::ENV_BG_CANVAS) {
+ //copy canvas to 3d buffer and convert it to linear
+
+ glDisable(GL_BLEND);
+ glDepthMask(GL_FALSE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
+
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, true);
+
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::SRGB_TO_LINEAR, true);
+
+ storage->shaders.copy.bind();
+
+ _copy_screen();
+
+ //turn off everything used
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::SRGB_TO_LINEAR, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false);
+
+ //restore
+ glEnable(GL_BLEND);
+ glDepthMask(GL_TRUE);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ }
state.texscreen_copied = false;
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 3e15da52ab..c52a00bf17 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -536,6 +536,11 @@ public:
virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve);
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve);
+ virtual bool is_environment(RID p_env);
+
+ virtual VS::EnvironmentBG environment_get_background(RID p_env);
+ virtual int environment_get_canvas_max_layer(RID p_env);
+
/* LIGHT INSTANCE */
struct LightDataUBO {
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index 4c8648903e..b0fb525e20 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -129,6 +129,11 @@ void main() {
color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
#endif
+#ifdef SRGB_TO_LINEAR
+
+ color.rgb = mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1 + 0.055)),vec3(2.4)),color.rgb * (1.0 / 12.92),lessThan(color.rgb,vec3(0.04045)));
+#endif
+
#ifdef DEBUG_GRADIENT
color.rg=uv_interp;
color.b=0.0;
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index dbd0758256..0f3f5500a8 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -245,7 +245,7 @@ void ScriptCreateDialog::_lang_changed(int l) {
template_menu->clear();
template_menu->add_item(TTR("Default"));
for (int i = 0; i < template_list.size(); i++) {
- template_menu->add_item(template_list[i]);
+ template_menu->add_item(template_list[i].capitalize());
}
}
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 045f1f51aa..c5c274e225 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -160,9 +160,9 @@ void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transf
sd.xform = p_transform;
for (int i = 0; i < sd.shapes.size(); i++) {
if (area) {
- Physics2DServer::get_singleton()->area_set_shape_transform(rid, i, p_transform);
+ Physics2DServer::get_singleton()->area_set_shape_transform(rid, sd.shapes[i].index, p_transform);
} else {
- Physics2DServer::get_singleton()->body_set_shape_transform(rid, i, p_transform);
+ Physics2DServer::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform);
}
}
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 2540a5b6a3..fd261117e1 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -941,248 +941,105 @@ RigidBody2D::~RigidBody2D() {
//////////////////////////
-Variant KinematicBody2D::_get_collider() const {
-
- ObjectID oid = get_collider();
- if (oid == 0)
- return Variant();
- Object *obj = ObjectDB::get_instance(oid);
- if (!obj)
- return Variant();
-
- Reference *ref = obj->cast_to<Reference>();
- if (ref) {
- return Ref<Reference>(ref);
- }
+Dictionary KinematicBody2D::_move(const Vector2 &p_motion) {
+
+ Collision col;
+ if (move(p_motion, col)) {
+ Dictionary d;
+ d["position"] = col.collision;
+ d["normal"] = col.collision;
+ d["local_shape"] = col.local_shape;
+ d["travel"] = col.travel;
+ d["remainder"] = col.remainder;
+ d["collider_id"] = col.collider;
+ if (col.collider) {
+ d["collider"] = ObjectDB::get_instance(col.collider);
+ } else {
+ d["collider"] = Variant();
+ }
- return obj;
-}
+ d["collider_shape_index"] = col.collider_shape;
+ d["collider_metadata"] = col.collider_metadata;
-void KinematicBody2D::revert_motion() {
+ return d;
- Transform2D gt = get_global_transform();
- gt.elements[2] -= travel;
- travel = Vector2();
- set_global_transform(gt);
-}
-
-Vector2 KinematicBody2D::get_travel() const {
-
- return travel;
+ } else {
+ return Dictionary();
+ }
}
-Vector2 KinematicBody2D::move(const Vector2 &p_motion) {
-
-#if 1
+bool KinematicBody2D::move(const Vector2 &p_motion, Collision &r_collision) {
Transform2D gt = get_global_transform();
Physics2DServer::MotionResult result;
- colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, margin, &result);
-
- collider_metadata = result.collider_metadata;
- collider_shape = result.collider_shape;
- collider_vel = result.collider_velocity;
- collision = result.collision_point;
- normal = result.collision_normal;
- collider = result.collider_id;
-
- gt.elements[2] += result.motion;
- set_global_transform(gt);
- travel = result.motion;
-
- return result.remainder;
-
-#else
- //give me back regular physics engine logic
- //this is madness
- //and most people using this function will think
- //what it does is simpler than using physics
- //this took about a week to get right..
- //but is it right? who knows at this point..
-
- colliding = false;
- ERR_FAIL_COND_V(!is_inside_tree(), Vector2());
- Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space());
- ERR_FAIL_COND_V(!dss, Vector2());
- const int max_shapes = 32;
- Vector2 sr[max_shapes * 2];
- int res_shapes;
-
- Set<RID> exclude;
- exclude.insert(get_rid());
-
- //recover first
- int recover_attempts = 4;
-
- bool collided = false;
- uint32_t mask = 0;
- if (true)
- mask |= Physics2DDirectSpaceState::TYPE_MASK_STATIC_BODY;
- if (true)
- mask |= Physics2DDirectSpaceState::TYPE_MASK_KINEMATIC_BODY;
- if (true)
- mask |= Physics2DDirectSpaceState::TYPE_MASK_RIGID_BODY;
- if (true)
- mask |= Physics2DDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
-
- //print_line("margin: "+rtos(margin));
- do {
-
- //motion recover
- for (int i = 0; i < get_shape_count(); i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
- if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), Vector2(), margin, sr, max_shapes, res_shapes, exclude, get_layer_mask(), mask))
- collided = true;
- }
-
- if (!collided)
- break;
-
- Vector2 recover_motion;
-
- for (int i = 0; i < res_shapes; i++) {
-
- Vector2 a = sr[i * 2 + 0];
- Vector2 b = sr[i * 2 + 1];
-
- float d = a.distance_to(b);
-
- /*
- if (d<margin)
- continue;
- */
- recover_motion += (b - a) * 0.4;
- }
-
- if (recover_motion == Vector2()) {
- collided = false;
- break;
- }
-
- Transform2D gt = get_global_transform();
- gt.elements[2] += recover_motion;
- set_global_transform(gt);
-
- recover_attempts--;
-
- } while (recover_attempts);
-
- //move second
- float safe = 1.0;
- float unsafe = 1.0;
- int best_shape = -1;
-
- for (int i = 0; i < get_shape_count(); i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
-
- float lsafe, lunsafe;
- bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0, lsafe, lunsafe, exclude, get_layer_mask(), mask);
- //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
- if (!valid) {
-
- safe = 0;
- unsafe = 0;
- best_shape = i; //sadly it's the best
- break;
- }
- if (lsafe == 1.0) {
- continue;
- }
- if (lsafe < safe) {
-
- safe = lsafe;
- unsafe = lunsafe;
- best_shape = i;
- }
- }
-
- //print_line("best shape: "+itos(best_shape)+" motion "+p_motion);
-
- if (safe >= 1) {
- //not collided
- colliding = false;
-
- } else {
-
- //it collided, let's get the rest info in unsafe advance
- Transform2D ugt = get_global_transform();
- ugt.elements[2] += p_motion * unsafe;
- Physics2DDirectSpaceState::ShapeRestInfo rest_info;
- bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt * get_shape_transform(best_shape), Vector2(), margin, &rest_info, exclude, get_layer_mask(), mask);
- if (!c2) {
- //should not happen, but floating point precision is so weird..
-
- colliding = false;
- } else {
-
- //print_line("Travel: "+rtos(travel));
- colliding = true;
- collision = rest_info.point;
- normal = rest_info.normal;
- collider = rest_info.collider_id;
- collider_vel = rest_info.linear_velocity;
- collider_shape = rest_info.shape;
- collider_metadata = rest_info.metadata;
- }
+ bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, margin, &result);
+
+ if (colliding) {
+ r_collision.collider_metadata = result.collider_metadata;
+ r_collision.collider_shape = result.collider_shape;
+ r_collision.collider_vel = result.collider_velocity;
+ r_collision.collision = result.collision_point;
+ r_collision.normal = result.collision_normal;
+ r_collision.collider = result.collider_id;
+ r_collision.travel = result.motion;
+ r_collision.remainder = result.remainder;
+ r_collision.local_shape = result.collision_local_shape;
}
- Vector2 motion = p_motion * safe;
- Transform2D gt = get_global_transform();
- gt.elements[2] += motion;
+ gt.elements[2] += result.motion;
set_global_transform(gt);
- return p_motion - motion;
-#endif
+ return colliding;
}
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) {
- Vector2 motion = (move_and_slide_floor_velocity + p_linear_velocity) * get_fixed_process_delta_time();
+ Vector2 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time();
Vector2 lv = p_linear_velocity;
- move_and_slide_on_floor = false;
- move_and_slide_on_ceiling = false;
- move_and_slide_on_wall = false;
- move_and_slide_colliders.clear();
- move_and_slide_floor_velocity = Vector2();
+ on_floor = false;
+ on_ceiling = false;
+ on_wall = false;
+ colliders.clear();
+ floor_velocity = Vector2();
while (p_max_bounces) {
- motion = move(motion);
+ Collision collision;
- if (is_colliding()) {
+ bool collided = move(motion, collision);
+
+ if (collided) {
+
+ motion = collision.remainder;
if (p_floor_direction == Vector2()) {
//all is a wall
- move_and_slide_on_wall = true;
+ on_wall = true;
} else {
- if (get_collision_normal().dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
+ if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
- move_and_slide_on_floor = true;
- move_and_slide_floor_velocity = get_collider_velocity();
+ on_floor = true;
+ floor_velocity = collision.collider_vel;
- if (get_travel().length() < 1 && ABS((lv.x - move_and_slide_floor_velocity.x)) < p_slope_stop_min_velocity) {
- revert_motion();
+ if (collision.travel.length() < 1 && ABS((lv.x - floor_velocity.x)) < p_slope_stop_min_velocity) {
+ Transform2D gt = get_global_transform();
+ gt.elements[2] -= collision.travel;
+ set_global_transform(gt);
return Vector2();
}
- } else if (get_collision_normal().dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling
- move_and_slide_on_ceiling = true;
+ } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling
+ on_ceiling = true;
} else {
- move_and_slide_on_wall = true;
+ on_wall = true;
}
}
- Vector2 n = get_collision_normal();
+ Vector2 n = collision.normal;
motion = motion.slide(n);
lv = lv.slide(n);
- Variant collider = _get_collider();
- if (collider.get_type() != Variant::NIL) {
- move_and_slide_colliders.push_back(collider);
- }
+
+ colliders.push_back(collision);
} else {
break;
@@ -1196,26 +1053,22 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
return lv;
}
-bool KinematicBody2D::is_move_and_slide_on_floor() const {
+bool KinematicBody2D::is_on_floor() const {
- return move_and_slide_on_floor;
+ return on_floor;
}
-bool KinematicBody2D::is_move_and_slide_on_wall() const {
+bool KinematicBody2D::is_on_wall() const {
- return move_and_slide_on_wall;
+ return on_wall;
}
-bool KinematicBody2D::is_move_and_slide_on_ceiling() const {
+bool KinematicBody2D::is_on_ceiling() const {
- return move_and_slide_on_ceiling;
+ return on_ceiling;
}
-Array KinematicBody2D::get_move_and_slide_colliders() const {
- return move_and_slide_colliders;
-}
+Vector2 KinematicBody2D::get_floor_velocity() const {
-Vector2 KinematicBody2D::move_to(const Vector2 &p_position) {
-
- return move(p_position - get_global_position());
+ return floor_velocity;
}
bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion) {
@@ -1225,98 +1078,123 @@ bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_moti
return Physics2DServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, margin);
}
-Vector2 KinematicBody2D::get_collision_pos() const {
+void KinematicBody2D::set_safe_margin(float p_margin) {
- ERR_FAIL_COND_V(!colliding, Vector2());
- return collision;
+ margin = p_margin;
}
-Vector2 KinematicBody2D::get_collision_normal() const {
+float KinematicBody2D::get_safe_margin() const {
- ERR_FAIL_COND_V(!colliding, Vector2());
- return normal;
+ return margin;
}
-Vector2 KinematicBody2D::get_collider_velocity() const {
+int KinematicBody2D::get_collision_count() const {
- return collider_vel;
+ return colliders.size();
}
+Vector2 KinematicBody2D::get_collision_position(int p_collision) const {
-ObjectID KinematicBody2D::get_collider() const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
- ERR_FAIL_COND_V(!colliding, 0);
- return collider;
+ return colliders[p_collision].collision;
}
-
-int KinematicBody2D::get_collider_shape() const {
-
- ERR_FAIL_COND_V(!colliding, 0);
- return collider_shape;
+Vector2 KinematicBody2D::get_collision_normal(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
+ return colliders[p_collision].normal;
}
-Variant KinematicBody2D::get_collider_metadata() const {
-
- ERR_FAIL_COND_V(!colliding, 0);
- return collider_metadata;
+Vector2 KinematicBody2D::get_collision_travel(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
+ return colliders[p_collision].travel;
}
-
-bool KinematicBody2D::is_colliding() const {
-
- return colliding;
+Vector2 KinematicBody2D::get_collision_remainder(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
+ return colliders[p_collision].remainder;
}
+Object *KinematicBody2D::get_collision_local_shape(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
+ uint32_t owner = shape_find_owner(colliders[p_collision].local_shape);
+ return shape_owner_get_owner(owner);
+}
+Object *KinematicBody2D::get_collision_collider(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
-void KinematicBody2D::set_collision_margin(float p_margin) {
+ if (colliders[p_collision].collider) {
+ return ObjectDB::get_instance(colliders[p_collision].collider);
+ }
- margin = p_margin;
+ return NULL;
}
+ObjectID KinematicBody2D::get_collision_collider_id(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0);
-float KinematicBody2D::get_collision_margin() const {
+ return colliders[p_collision].collider;
+}
+Object *KinematicBody2D::get_collision_collider_shape(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
+ Object *collider = get_collision_collider(p_collision);
+ if (collider) {
+ CollisionObject2D *obj2d = collider->cast_to<CollisionObject2D>();
+ if (obj2d) {
+ uint32_t owner = shape_find_owner(colliders[p_collision].collider_shape);
+ return obj2d->shape_owner_get_owner(owner);
+ }
+ }
- return margin;
+ return NULL;
+}
+int KinematicBody2D::get_collision_collider_shape_index(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1);
+ return colliders[p_collision].collider_shape;
+}
+Vector2 KinematicBody2D::get_collision_collider_velocity(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector2());
+ return colliders[p_collision].collider_vel;
+}
+Variant KinematicBody2D::get_collision_collider_metadata(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Variant());
+ return colliders[p_collision].collider_metadata;
}
void KinematicBody2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody2D::move);
- ClassDB::bind_method(D_METHOD("move_to", "position"), &KinematicBody2D::move_to);
+ ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody2D::_move);
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody2D::test_move);
- ClassDB::bind_method(D_METHOD("get_travel"), &KinematicBody2D::get_travel);
- ClassDB::bind_method(D_METHOD("revert_motion"), &KinematicBody2D::revert_motion);
- ClassDB::bind_method(D_METHOD("is_colliding"), &KinematicBody2D::is_colliding);
+ ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor);
+ ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling);
+ ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody2D::is_on_wall);
+ ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody2D::get_floor_velocity);
- ClassDB::bind_method(D_METHOD("get_collision_pos"), &KinematicBody2D::get_collision_pos);
- ClassDB::bind_method(D_METHOD("get_collision_normal"), &KinematicBody2D::get_collision_normal);
- ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicBody2D::get_collider_velocity);
- ClassDB::bind_method(D_METHOD("get_collider:Variant"), &KinematicBody2D::_get_collider);
- ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicBody2D::get_collider_shape);
- ClassDB::bind_method(D_METHOD("get_collider_metadata:Variant"), &KinematicBody2D::get_collider_metadata);
- ClassDB::bind_method(D_METHOD("get_move_and_slide_colliders"), &KinematicBody2D::get_move_and_slide_colliders);
- ClassDB::bind_method(D_METHOD("is_move_and_slide_on_floor"), &KinematicBody2D::is_move_and_slide_on_floor);
- ClassDB::bind_method(D_METHOD("is_move_and_slide_on_ceiling"), &KinematicBody2D::is_move_and_slide_on_ceiling);
- ClassDB::bind_method(D_METHOD("is_move_and_slide_on_wall"), &KinematicBody2D::is_move_and_slide_on_wall);
+ ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin);
+ ClassDB::bind_method(D_METHOD("get_safe_margin", "pixels"), &KinematicBody2D::get_safe_margin);
- ClassDB::bind_method(D_METHOD("set_collision_margin", "pixels"), &KinematicBody2D::set_collision_margin);
- ClassDB::bind_method(D_METHOD("get_collision_margin", "pixels"), &KinematicBody2D::get_collision_margin);
+ ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody2D::get_collision_count);
+ ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody2D::get_collision_position);
+ ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody2D::get_collision_normal);
+ ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody2D::get_collision_travel);
+ ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody2D::get_collision_remainder);
+ ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody2D::get_collision_local_shape);
+ ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody2D::get_collision_collider);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody2D::get_collision_collider_id);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody2D::get_collision_collider_shape);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody2D::get_collision_collider_shape_index);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody2D::get_collision_collider_velocity);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody2D::get_collision_collider_metadata);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_collision_margin", "get_collision_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
KinematicBody2D::KinematicBody2D()
: PhysicsBody2D(Physics2DServer::BODY_MODE_KINEMATIC) {
- colliding = false;
- collider = 0;
-
- collider_shape = 0;
-
margin = 0.08;
- move_and_slide_on_floor = false;
- move_and_slide_on_ceiling = false;
- move_and_slide_on_wall = false;
+ on_floor = false;
+ on_ceiling = false;
+ on_wall = false;
}
KinematicBody2D::~KinematicBody2D() {
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 9871a56fe2..8c8e4ebc77 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -264,54 +264,60 @@ class KinematicBody2D : public PhysicsBody2D {
GDCLASS(KinematicBody2D, PhysicsBody2D);
+public:
+ struct Collision {
+ Vector2 collision;
+ Vector2 normal;
+ Vector2 collider_vel;
+ ObjectID collider;
+ int collider_shape;
+ Variant collider_metadata;
+ Vector2 remainder;
+ Vector2 travel;
+ int local_shape;
+ };
+
+private:
float margin;
- bool colliding;
- Vector2 collision;
- Vector2 normal;
- Vector2 collider_vel;
- ObjectID collider;
- int collider_shape;
- Variant collider_metadata;
- Vector2 travel;
-
- Vector2 move_and_slide_floor_velocity;
- bool move_and_slide_on_floor;
- bool move_and_slide_on_ceiling;
- bool move_and_slide_on_wall;
- Array move_and_slide_colliders;
-
- Variant _get_collider() const;
+
+ Vector2 floor_velocity;
+ bool on_floor;
+ bool on_ceiling;
+ bool on_wall;
+ Vector<Collision> colliders;
_FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const;
+ Dictionary _move(const Vector2 &p_motion);
+
protected:
static void _bind_methods();
public:
- Vector2 move(const Vector2 &p_motion);
- Vector2 move_to(const Vector2 &p_position);
-
+ bool move(const Vector2 &p_motion, Collision &r_collision);
bool test_move(const Transform2D &p_from, const Vector2 &p_motion);
- bool is_colliding() const;
-
- Vector2 get_travel() const;
- void revert_motion();
-
- Vector2 get_collision_pos() const;
- Vector2 get_collision_normal() const;
- Vector2 get_collider_velocity() const;
- ObjectID get_collider() const;
- int get_collider_shape() const;
- Variant get_collider_metadata() const;
- void set_collision_margin(float p_margin);
- float get_collision_margin() const;
+ void set_safe_margin(float p_margin);
+ float get_safe_margin() const;
Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45));
- bool is_move_and_slide_on_floor() const;
- bool is_move_and_slide_on_wall() const;
- bool is_move_and_slide_on_ceiling() const;
- Array get_move_and_slide_colliders() const;
+ bool is_on_floor() const;
+ bool is_on_wall() const;
+ bool is_on_ceiling() const;
+ Vector2 get_floor_velocity() const;
+
+ int get_collision_count() const;
+ Vector2 get_collision_position(int p_collision) const;
+ Vector2 get_collision_normal(int p_collision) const;
+ Vector2 get_collision_travel(int p_collision) const;
+ Vector2 get_collision_remainder(int p_collision) const;
+ Object *get_collision_local_shape(int p_collision) const;
+ Object *get_collision_collider(int p_collision) const;
+ ObjectID get_collision_collider_id(int p_collision) const;
+ Object *get_collision_collider_shape(int p_collision) const;
+ int get_collision_collider_shape_index(int p_collision) const;
+ Vector2 get_collision_collider_velocity(int p_collision) const;
+ Variant get_collision_collider_metadata(int p_collision) const;
KinematicBody2D();
~KinematicBody2D();
diff --git a/scene/3d/scenario_fx.cpp b/scene/3d/scenario_fx.cpp
index 874c21546d..abc7766ecb 100644
--- a/scene/3d/scenario_fx.cpp
+++ b/scene/3d/scenario_fx.cpp
@@ -28,43 +28,44 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "scenario_fx.h"
+#include "scene/main/viewport.h"
void WorldEnvironment::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_WORLD) {
+ if (p_what == Spatial::NOTIFICATION_ENTER_WORLD || p_what == Spatial::NOTIFICATION_ENTER_TREE) {
if (environment.is_valid()) {
- if (get_world()->get_environment().is_valid()) {
+ if (get_viewport()->find_world()->get_environment().is_valid()) {
WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
}
- get_world()->set_environment(environment);
- add_to_group("_world_environment_" + itos(get_world()->get_scenario().get_id()));
+ get_viewport()->find_world()->set_environment(environment);
+ add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
}
- } else if (p_what == NOTIFICATION_EXIT_WORLD) {
+ } else if (p_what == Spatial::NOTIFICATION_EXIT_WORLD || p_what == Spatial::NOTIFICATION_EXIT_TREE) {
- if (environment.is_valid() && get_world()->get_environment() == environment) {
- get_world()->set_environment(Ref<Environment>());
- remove_from_group("_world_environment_" + itos(get_world()->get_scenario().get_id()));
+ 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()));
}
}
}
void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) {
- if (is_inside_world() && environment.is_valid() && get_world()->get_environment() == environment) {
- get_world()->set_environment(Ref<Environment>());
- remove_from_group("_world_environment_" + itos(get_world()->get_scenario().get_id()));
+ if (is_inside_tree() && 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()));
//clean up
}
environment = p_environment;
- if (is_inside_world() && environment.is_valid()) {
- if (get_world()->get_environment().is_valid()) {
+ if (is_inside_tree() && environment.is_valid()) {
+ if (get_viewport()->find_world()->get_environment().is_valid()) {
WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
}
- get_world()->set_environment(environment);
- add_to_group("_world_environment_" + itos(get_world()->get_scenario().get_id()));
+ get_viewport()->find_world()->set_environment(environment);
+ add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
}
update_configuration_warning();
@@ -77,11 +78,11 @@ Ref<Environment> WorldEnvironment::get_environment() const {
String WorldEnvironment::get_configuration_warning() const {
- if (!is_visible_in_tree() || !is_inside_tree() || !environment.is_valid())
+ if (/*!is_visible_in_tree() ||*/ !is_inside_tree() || !environment.is_valid())
return String();
List<Node *> nodes;
- get_tree()->get_nodes_in_group("_world_environment_" + itos(get_world()->get_scenario().get_id()), &nodes);
+ get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()), &nodes);
if (nodes.size() > 1) {
return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes).");
diff --git a/scene/3d/scenario_fx.h b/scene/3d/scenario_fx.h
index b2a4bc5472..d1e0a63130 100644
--- a/scene/3d/scenario_fx.h
+++ b/scene/3d/scenario_fx.h
@@ -36,9 +36,9 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
-class WorldEnvironment : public Spatial {
+class WorldEnvironment : public Node {
- GDCLASS(WorldEnvironment, Spatial);
+ GDCLASS(WorldEnvironment, Node);
Ref<Environment> environment;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 0b8595de42..78ede6e494 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1831,7 +1831,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_image", "image:Texture"), &RichTextLabel::add_image);
ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);
ClassDB::bind_method(D_METHOD("remove_line"), &RichTextLabel::remove_line);
- ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
+ ClassDB::bind_method(D_METHOD("push_font", "font:Font"), &RichTextLabel::push_font);
ClassDB::bind_method(D_METHOD("push_color", "color"), &RichTextLabel::push_color);
ClassDB::bind_method(D_METHOD("push_align", "align"), &RichTextLabel::push_align);
ClassDB::bind_method(D_METHOD("push_indent", "level"), &RichTextLabel::push_indent);
@@ -1854,7 +1854,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_scroll_follow", "follow"), &RichTextLabel::set_scroll_follow);
ClassDB::bind_method(D_METHOD("is_scroll_following"), &RichTextLabel::is_scroll_following);
- ClassDB::bind_method(D_METHOD("get_v_scroll"), &RichTextLabel::get_v_scroll);
+ ClassDB::bind_method(D_METHOD("get_v_scroll:VScrollBar"), &RichTextLabel::get_v_scroll);
ClassDB::bind_method(D_METHOD("scroll_to_line", "line"), &RichTextLabel::scroll_to_line);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 714327c5b7..a87c83f17c 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -49,6 +49,7 @@
#include "scene/scene_string_names.h"
#include "global_config.h"
+#include "scene/3d/scenario_fx.h"
void ViewportTexture::setup_local_to_scene() {
@@ -1017,10 +1018,9 @@ void Viewport::_propagate_enter_world(Node *p_node) {
if (!p_node->is_inside_tree()) //may not have entered scene yet
return;
- Spatial *s = p_node->cast_to<Spatial>();
- if (s) {
+ if (p_node->cast_to<Spatial>() || p_node->cast_to<WorldEnvironment>()) {
- s->notification(Spatial::NOTIFICATION_ENTER_WORLD);
+ p_node->notification(Spatial::NOTIFICATION_ENTER_WORLD);
} else {
Viewport *v = p_node->cast_to<Viewport>();
if (v) {
@@ -1055,10 +1055,9 @@ void Viewport::_propagate_exit_world(Node *p_node) {
if (!p_node->is_inside_tree()) //may have exited scene already
return;
- Spatial *s = p_node->cast_to<Spatial>();
- if (s) {
+ if (p_node->cast_to<Spatial>() || p_node->cast_to<WorldEnvironment>()) {
- s->notification(Spatial::NOTIFICATION_EXIT_WORLD, true);
+ p_node->notification(Spatial::NOTIFICATION_EXIT_WORLD);
} else {
Viewport *v = p_node->cast_to<Viewport>();
if (v) {
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index b197ba5905..0b31ff144b 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -781,6 +781,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
r_result->collider = rcd.best_object->get_self();
r_result->collider_id = rcd.best_object->get_instance_id();
r_result->collider_shape = rcd.best_shape;
+ r_result->collision_local_shape = best_shape;
r_result->collision_normal = rcd.best_normal;
r_result->collision_point = rcd.best_contact;
r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index f25f05bafc..f50faa42eb 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -474,6 +474,7 @@ public:
Vector2 collision_point;
Vector2 collision_normal;
Vector2 collider_velocity;
+ int collision_local_shape;
ObjectID collider_id;
RID collider;
int collider_shape;
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 43452b714c..2ce83e6c64 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -75,6 +75,10 @@ public:
virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+ virtual bool is_environment(RID p_env) = 0;
+ virtual VS::EnvironmentBG environment_get_background(RID p_env) = 0;
+ virtual int environment_get_canvas_max_layer(RID p_env) = 0;
+
struct InstanceBase : RID_Data {
VS::InstanceType base_type;
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 6d1f698a5c..fb1c66d0b9 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -2162,6 +2162,18 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
VSG::scene_render->render_scene(p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, environment, p_shadow_atlas, scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
}
+void VisualServerScene::render_empty_scene(RID p_scenario, RID p_shadow_atlas) {
+
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+
+ RID environment;
+ if (scenario->environment.is_valid())
+ environment = scenario->environment;
+ else
+ environment = scenario->fallback_environment;
+ VSG::scene_render->render_scene(Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, environment, p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
+}
+
bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 92c6421987..d13c24ae24 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -519,6 +519,7 @@ public:
_FORCE_INLINE_ void _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario);
void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
+ void render_empty_scene(RID p_scenario, RID p_shadow_atlas);
void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
void update_dirty_instances();
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 2fbbcd225f..2c2bd2b167 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -35,23 +35,24 @@
void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
-/* Camera should always be BEFORE any other 3D */
-#if 0
- bool scenario_draw_canvas_bg=false;
- int scenario_canvas_max_layer=0;
+ /* Camera should always be BEFORE any other 3D */
- if (!p_viewport->hide_canvas && !p_viewport->disable_environment && scenario_owner.owns(p_viewport->scenario)) {
+ bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front
+ int scenario_canvas_max_layer = 0;
- Scenario *scenario=scenario_owner.get(p_viewport->scenario);
- if (scenario->environment.is_valid()) {
- if (rasterizer->is_environment(scenario->environment)) {
- scenario_draw_canvas_bg=rasterizer->environment_get_background(scenario->environment)==VS::ENV_BG_CANVAS;
- scenario_canvas_max_layer=rasterizer->environment_get_background_param(scenario->environment,VS::ENV_BG_PARAM_CANVAS_MAX_LAYER);
- }
+ if (!p_viewport->hide_canvas && !p_viewport->disable_environment && VSG::scene->scenario_owner.owns(p_viewport->scenario)) {
+
+ VisualServerScene::Scenario *scenario = VSG::scene->scenario_owner.get(p_viewport->scenario);
+ if (VSG::scene_render->is_environment(scenario->environment)) {
+ scenario_draw_canvas_bg = VSG::scene_render->environment_get_background(scenario->environment) == VS::ENV_BG_CANVAS;
+
+ scenario_canvas_max_layer = VSG::scene_render->environment_get_canvas_max_layer(scenario->environment);
}
}
- bool can_draw_3d=!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario);
+ bool can_draw_3d = !p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && VSG::scene->camera_owner.owns(p_viewport->camera);
+#if 0
+
if (scenario_draw_canvas_bg) {
@@ -88,7 +89,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
}
}
- if (!p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && p_viewport->camera.is_valid()) {
+ if (!scenario_draw_canvas_bg && can_draw_3d) {
VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
@@ -199,14 +200,15 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
VSG::rasterizer->restore_render_target();
-#if 0
- if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer>scenario_canvas_max_layer) {
-
- _draw_viewport_camera(p_viewport,!can_draw_3d);
- scenario_draw_canvas_bg=false;
+ if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer > scenario_canvas_max_layer) {
+ if (can_draw_3d) {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ }
+ scenario_draw_canvas_bg = false;
}
-#endif
for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) {
@@ -229,19 +231,29 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect);
i++;
-#if 0
- if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) {
- _draw_viewport_camera(p_viewport,!can_draw_3d);
- scenario_draw_canvas_bg=false;
+
+ if (scenario_draw_canvas_bg && E->key().layer >= scenario_canvas_max_layer) {
+
+ if (can_draw_3d) {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ }
+
+ scenario_draw_canvas_bg = false;
}
-#endif
}
-#if 0
+
if (scenario_draw_canvas_bg) {
- _draw_viewport_camera(p_viewport,!can_draw_3d);
- scenario_draw_canvas_bg=false;
+
+ if (can_draw_3d) {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ }
+
+ scenario_draw_canvas_bg = false;
}
-#endif
//VSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow);
}