summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/physics/joints/cone_twist_joint_sw.cpp1
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp15
-rw-r--r--servers/physics_2d/body_2d_sw.cpp2
-rw-r--r--servers/physics_2d/body_2d_sw.h15
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp15
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp3
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h15
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp52
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h12
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h11
-rw-r--r--servers/physics_2d/space_2d_sw.cpp107
-rw-r--r--servers/physics_2d_server.cpp11
-rw-r--r--servers/physics_2d_server.h13
-rw-r--r--servers/visual/rasterizer.h26
-rw-r--r--servers/visual/shader_types.cpp1
-rw-r--r--servers/visual/visual_server_canvas.cpp31
-rw-r--r--servers/visual/visual_server_canvas.h9
-rw-r--r--servers/visual/visual_server_raster.h6
-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
-rw-r--r--servers/visual/visual_server_wrap_mt.h4
-rw-r--r--servers/visual_server.cpp10
-rw-r--r--servers/visual_server.h9
24 files changed, 235 insertions, 214 deletions
diff --git a/servers/physics/joints/cone_twist_joint_sw.cpp b/servers/physics/joints/cone_twist_joint_sw.cpp
index 7e13909592..51bc27ea7d 100644
--- a/servers/physics/joints/cone_twist_joint_sw.cpp
+++ b/servers/physics/joints/cone_twist_joint_sw.cpp
@@ -100,6 +100,7 @@ ConeTwistJointSW::ConeTwistJointSW(BodySW *rbA, BodySW *rbB, const Transform &rb
m_biasFactor = 0.3f;
m_relaxationFactor = 1.0f;
+ m_angularOnly = false;
m_solveTwistLimit = false;
m_solveSwingLimit = false;
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index c98375fc44..184db944da 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -32,7 +32,13 @@
bool AreaPair2DSW::setup(real_t p_step) {
- bool result = area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), NULL, this);
+ bool result = false;
+
+ if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
+ result = false;
+ } else if (area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), NULL, this)) {
+ result = true;
+ }
if (result != colliding) {
@@ -90,7 +96,12 @@ AreaPair2DSW::~AreaPair2DSW() {
bool Area2Pair2DSW::setup(real_t p_step) {
- bool result = area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), NULL, this);
+ bool result = false;
+ if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
+ result = false;
+ } else if (area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), NULL, this)) {
+ result = true;
+ }
if (result != colliding) {
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index 03ad66d4e9..538ea10211 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -676,8 +676,6 @@ Body2DSW::Body2DSW()
area_linear_damp = 0;
contact_count = 0;
gravity_scale = 1.0;
- using_one_way_cache = false;
- one_way_collision_max_depth = 0.1;
first_integration = false;
still_time = 0;
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 23adebbad6..9e5deef3f2 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -67,9 +67,6 @@ class Body2DSW : public CollisionObject2DSW {
Vector2 applied_force;
real_t applied_torque;
- Vector2 one_way_collision_direction;
- real_t one_way_collision_max_depth;
-
SelfList<Body2DSW> active_list;
SelfList<Body2DSW> inertia_update_list;
SelfList<Body2DSW> direct_state_query_list;
@@ -81,7 +78,6 @@ class Body2DSW : public CollisionObject2DSW {
bool can_sleep;
bool first_time_kinematic;
bool first_integration;
- bool using_one_way_cache;
void _update_inertia();
virtual void _shapes_changed();
Transform2D new_transform;
@@ -246,17 +242,6 @@ public:
_FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode = p_mode; }
_FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; }
- void set_one_way_collision_direction(const Vector2 &p_dir) {
- one_way_collision_direction = p_dir;
- using_one_way_cache = one_way_collision_direction != Vector2();
- }
- Vector2 get_one_way_collision_direction() const { return one_way_collision_direction; }
-
- void set_one_way_collision_max_depth(real_t p_depth) { one_way_collision_max_depth = p_depth; }
- real_t get_one_way_collision_max_depth() const { return one_way_collision_max_depth; }
-
- _FORCE_INLINE_ bool is_using_one_way_collision() const { return using_one_way_cache; }
-
void set_space(Space2DSW *p_space);
void update_inertias();
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index 47e9afbde6..484d4503d0 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -225,6 +225,11 @@ bool BodyPair2DSW::setup(real_t p_step) {
return false;
}
+ if (A->is_shape_set_as_disabled(shape_A) || B->is_shape_set_as_disabled(shape_B)) {
+ collided = false;
+ return false;
+ }
+
//use local A coordinates to avoid numerical issues on collision detection
offset_B = B->get_transform().get_origin() - A->get_transform().get_origin();
@@ -280,8 +285,8 @@ bool BodyPair2DSW::setup(real_t p_step) {
//if (!prev_collided) {
{
- if (A->is_using_one_way_collision()) {
- Vector2 direction = A->get_one_way_collision_direction();
+ if (A->is_shape_set_as_one_way_collision(shape_A)) {
+ Vector2 direction = xform_A.get_axis(1).normalized();
bool valid = false;
if (B->get_linear_velocity().dot(direction) >= 0) {
for (int i = 0; i < contact_count; i++) {
@@ -303,8 +308,8 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
}
- if (B->is_using_one_way_collision()) {
- Vector2 direction = B->get_one_way_collision_direction();
+ if (B->is_shape_set_as_one_way_collision(shape_B)) {
+ Vector2 direction = xform_B.get_axis(1).normalized();
bool valid = false;
if (A->get_linear_velocity().dot(direction) >= 0) {
for (int i = 0; i < contact_count; i++) {
@@ -390,7 +395,7 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
}
- if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC)) {
+ if ((A->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC)) {
c.active = false;
collided = false;
continue;
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 0163a18850..8f13f1130a 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -37,7 +37,8 @@ void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_tra
s.xform = p_transform;
s.xform_inv = s.xform.affine_inverse();
s.bpid = 0; //needs update
- s.trigger = false;
+ s.disabled = false;
+ s.one_way_collision = false;
shapes.push_back(s);
p_shape->add_owner(this);
_update_shapes();
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index f2059e8618..5e29132e8d 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -58,8 +58,12 @@ private:
Rect2 aabb_cache; //for rayqueries
Shape2DSW *shape;
Variant metadata;
- bool trigger;
- Shape() { trigger = false; }
+ bool disabled;
+ bool one_way_collision;
+ Shape() {
+ disabled = false;
+ one_way_collision = false;
+ }
};
Vector<Shape> shapes;
@@ -116,8 +120,11 @@ public:
_FORCE_INLINE_ Transform2D get_inv_transform() const { return inv_transform; }
_FORCE_INLINE_ Space2DSW *get_space() const { return space; }
- _FORCE_INLINE_ void set_shape_as_trigger(int p_idx, bool p_enable) { shapes[p_idx].trigger = p_enable; }
- _FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; }
+ _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_disabled) { shapes[p_idx].disabled = p_disabled; }
+ _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const { return shapes[p_idx].disabled; }
+
+ _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision) { shapes[p_idx].one_way_collision = p_one_way_collision; }
+ _FORCE_INLINE_ bool is_shape_set_as_one_way_collision(int p_idx) const { return shapes[p_idx].one_way_collision; }
void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; }
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; }
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 9a31fa49b0..1d88710f1a 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -352,6 +352,15 @@ void Physics2DServerSW::area_set_shape_transform(RID p_area, int p_shape_idx, co
area->set_shape_transform(p_shape_idx, p_transform);
}
+void Physics2DServerSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) {
+
+ Area2DSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ ERR_FAIL_INDEX(p_shape, area->get_shape_count());
+ area->set_shape_as_disabled(p_shape, p_disabled);
+}
+
int Physics2DServerSW::area_get_shape_count(RID p_area) const {
Area2DSW *area = area_owner.get(p_area);
@@ -640,24 +649,23 @@ void Physics2DServerSW::body_clear_shapes(RID p_body) {
body->remove_shape(0);
}
-void Physics2DServerSW::body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) {
+void Physics2DServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
- body->set_shape_as_trigger(p_shape_idx, p_enable);
+ body->set_shape_as_disabled(p_shape_idx, p_disabled);
}
+void Physics2DServerSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable) {
-bool Physics2DServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const {
-
- const Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, false);
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
- ERR_FAIL_INDEX_V(p_shape_idx, body->get_shape_count(), false);
+ ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
- return body->is_shape_set_as_trigger(p_shape_idx);
+ body->set_shape_as_one_way_collision(p_shape_idx, p_enable);
}
void Physics2DServerSW::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) {
@@ -887,34 +895,6 @@ int Physics2DServerSW::body_get_max_contacts_reported(RID p_body) const {
return body->get_max_contacts_reported();
}
-void Physics2DServerSW::body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction) {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
- body->set_one_way_collision_direction(p_direction);
-}
-
-Vector2 Physics2DServerSW::body_get_one_way_collision_direction(RID p_body) const {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, Vector2());
- return body->get_one_way_collision_direction();
-}
-
-void Physics2DServerSW::body_set_one_way_collision_max_depth(RID p_body, real_t p_max_depth) {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
- body->set_one_way_collision_max_depth(p_max_depth);
-}
-
-real_t Physics2DServerSW::body_get_one_way_collision_max_depth(RID p_body) const {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, 0);
- return body->get_one_way_collision_max_depth();
-}
-
void Physics2DServerSW::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
Body2DSW *body = body_owner.get(p_body);
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index be67e3157d..9cbdfc598f 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -123,6 +123,8 @@ public:
virtual RID area_get_shape(RID p_area, int p_shape_idx) const;
virtual Transform2D area_get_shape_transform(RID p_area, int p_shape_idx) const;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled);
+
virtual void area_remove_shape(RID p_area, int p_shape_idx);
virtual void area_clear_shapes(RID p_area);
@@ -167,8 +169,8 @@ public:
virtual void body_remove_shape(RID p_body, int p_shape_idx);
virtual void body_clear_shapes(RID p_body);
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable);
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled);
+ virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled);
virtual void body_attach_object_instance_ID(RID p_body, uint32_t p_ID);
virtual uint32_t body_get_object_instance_ID(RID p_body) const;
@@ -212,12 +214,6 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts);
virtual int body_get_max_contacts_reported(RID p_body) const;
- virtual void body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction);
- virtual Vector2 body_get_one_way_collision_direction(RID p_body) const;
-
- virtual void body_set_one_way_collision_max_depth(RID p_body, real_t p_max_depth);
- virtual real_t body_get_one_way_collision_max_depth(RID p_body) const;
-
virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant());
virtual bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count);
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index 1026d84fd9..9fcfebef6b 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -145,6 +145,7 @@ public:
FUNC3(area_add_shape, RID, RID, const Transform2D &);
FUNC3(area_set_shape, RID, int, RID);
FUNC3(area_set_shape_transform, RID, int, const Transform2D &);
+ FUNC3(area_set_shape_disabled, RID, int, bool);
FUNC1RC(int, area_get_shape_count, RID);
FUNC2RC(RID, area_get_shape, RID, int);
@@ -191,8 +192,8 @@ public:
FUNC2RC(Variant, body_get_shape_metadata, RID, int);
FUNC2RC(RID, body_get_shape, RID, int);
- FUNC3(body_set_shape_as_trigger, RID, int, bool);
- FUNC2RC(bool, body_is_shape_set_as_trigger, RID, int);
+ FUNC3(body_set_shape_disabled, RID, int, bool);
+ FUNC3(body_set_shape_as_one_way_collision, RID, int, bool);
FUNC2(body_remove_shape, RID, int);
FUNC1(body_clear_shapes, RID);
@@ -232,12 +233,6 @@ public:
FUNC2(body_set_max_contacts_reported, RID, int);
FUNC1RC(int, body_get_max_contacts_reported, RID);
- FUNC2(body_set_one_way_collision_direction, RID, const Vector2 &);
- FUNC1RC(Vector2, body_get_one_way_collision_direction, RID);
-
- FUNC2(body_set_one_way_collision_max_depth, RID, real_t);
- FUNC1RC(real_t, body_get_one_way_collision_max_depth, RID);
-
FUNC2(body_set_contacts_reported_depth_treshold, RID, real_t);
FUNC1RC(real_t, body_get_contacts_reported_depth_treshold, RID);
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index fd94fc01cd..0b31ff144b 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -265,14 +265,6 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
//test initial overlap
if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, p_margin)) {
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- //if one way collision direction ignore initial overlap
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
- continue;
- }
- }
-
return false;
}
@@ -297,27 +289,6 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
}
}
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
-
- Vector2 cd[2];
- Physics2DServerSW::CollCbkData cbk;
- cbk.max = 1;
- cbk.amount = 0;
- cbk.ptr = cd;
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
-
- Vector2 sep = mnormal; //important optimization for this to work fast enough
- bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * (hi + space->contact_max_allowed_penetration), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, p_margin);
- if (!collided || cbk.amount == 0) {
- continue;
- }
- }
- }
-
if (low < best_safe) {
best_safe = low;
best_unsafe = hi;
@@ -369,15 +340,9 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
if (p_exclude.has(col_obj->get_self()))
continue;
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
- } else {
- cbk.valid_dir = Vector2();
- cbk.valid_depth = 0;
- }
+ cbk.valid_dir = Vector2();
+ cbk.valid_depth = 0;
if (CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
collided = p_result_max == 0 || cbk.amount > 0;
@@ -407,13 +372,10 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
_RestCallbackData2D *rd = (_RestCallbackData2D *)p_userdata;
if (rd->valid_dir != Vector2()) {
-
- if (rd->valid_dir != Vector2()) {
- if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth)
- return;
- if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25)
- return;
- }
+ if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth)
+ return;
+ if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25)
+ return;
}
Vector2 contact_rel = p_point_B - p_point_A;
@@ -455,16 +417,8 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
if (p_exclude.has(col_obj->get_self()))
continue;
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- rcd.valid_dir = body->get_one_way_collision_direction();
- rcd.valid_depth = body->get_one_way_collision_max_depth();
- } else {
- rcd.valid_dir = Vector2();
- rcd.valid_depth = 0;
- }
-
+ rcd.valid_dir = Vector2();
+ rcd.valid_depth = 0;
rcd.object = col_obj;
rcd.shape = shape_idx;
bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
@@ -517,7 +471,7 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
keep = false;
else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self()))
keep = false;
- else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_trigger(intersection_query_subindex_results[i]))
+ else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i]))
keep = false;
if (!keep) {
@@ -589,7 +543,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_trigger(j))
+ if (p_body->is_shape_set_as_disabled(j))
continue;
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
@@ -599,18 +553,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
-
- Vector2 cdir = body->get_one_way_collision_direction();
- /*
- if (cdir!=Vector2() && p_motion.dot(cdir)<0)
- continue;
- */
+ if (col_obj->is_shape_set_as_one_way_collision(j)) {
- cbk.valid_dir = cdir;
- cbk.valid_depth = body->get_one_way_collision_max_depth();
+ cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ cbk.valid_depth = p_margin; //only valid depth is the collision margin
} else {
cbk.valid_dir = Vector2();
cbk.valid_depth = 0;
@@ -678,7 +624,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_trigger(j))
+ if (p_body->is_shape_set_as_disabled(j))
continue;
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
@@ -703,12 +649,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
//test initial overlap
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- //if one way collision direction ignore initial overlap
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
- continue;
- }
+ if (col_obj->is_shape_set_as_one_way_collision(j)) {
+ continue;
}
stuck = true;
@@ -720,7 +662,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
real_t hi = 1;
Vector2 mnormal = p_motion.normalized();
- for (int i = 0; i < 8; i++) { //steps should be customizable..
+ for (int k = 0; k < 8; k++) { //steps should be customizable..
real_t ofs = (low + hi) * 0.5;
@@ -739,15 +681,16 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
+ if (col_obj->is_shape_set_as_one_way_collision(j)) {
Vector2 cd[2];
Physics2DServerSW::CollCbkData cbk;
cbk.max = 1;
cbk.amount = 0;
cbk.ptr = cd;
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
+ cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ ;
+ cbk.valid_depth = 10e20;
Vector2 sep = mnormal; //important optimization for this to work fast enough
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, 0);
@@ -816,11 +759,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
+ if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- rcd.valid_dir = body->get_one_way_collision_direction();
- rcd.valid_depth = body->get_one_way_collision_max_depth();
+ rcd.valid_dir = body_shape_xform.get_axis(1).normalized();
+ rcd.valid_depth = 10e20;
} else {
rcd.valid_dir = Vector2();
rcd.valid_depth = 0;
@@ -839,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.cpp b/servers/physics_2d_server.cpp
index 8ffa82214c..55ea2b41e7 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -496,6 +496,7 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform"), &Physics2DServer::area_add_shape, DEFVAL(Transform2D()));
ClassDB::bind_method(D_METHOD("area_set_shape", "area", "shape_idx", "shape"), &Physics2DServer::area_set_shape);
ClassDB::bind_method(D_METHOD("area_set_shape_transform", "area", "shape_idx", "transform"), &Physics2DServer::area_set_shape_transform);
+ ClassDB::bind_method(D_METHOD("area_set_shape_disabled", "area", "shape_idx", "disable"), &Physics2DServer::area_set_shape_disabled);
ClassDB::bind_method(D_METHOD("area_get_shape_count", "area"), &Physics2DServer::area_get_shape_count);
ClassDB::bind_method(D_METHOD("area_get_shape", "area", "shape_idx"), &Physics2DServer::area_get_shape);
@@ -539,8 +540,8 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_remove_shape", "body", "shape_idx"), &Physics2DServer::body_remove_shape);
ClassDB::bind_method(D_METHOD("body_clear_shapes", "body"), &Physics2DServer::body_clear_shapes);
- ClassDB::bind_method(D_METHOD("body_set_shape_as_trigger", "body", "shape_idx", "enable"), &Physics2DServer::body_set_shape_as_trigger);
- ClassDB::bind_method(D_METHOD("body_is_shape_set_as_trigger", "body", "shape_idx"), &Physics2DServer::body_is_shape_set_as_trigger);
+ ClassDB::bind_method(D_METHOD("body_set_shape_disabled", "body", "shape_idx", "disable"), &Physics2DServer::body_set_shape_disabled);
+ ClassDB::bind_method(D_METHOD("body_set_shape_as_one_way_collision", "body", "shape_idx", "enable"), &Physics2DServer::body_set_shape_as_one_way_collision);
ClassDB::bind_method(D_METHOD("body_attach_object_instance_ID", "body", "id"), &Physics2DServer::body_attach_object_instance_ID);
ClassDB::bind_method(D_METHOD("body_get_object_instance_ID", "body"), &Physics2DServer::body_get_object_instance_ID);
@@ -571,12 +572,6 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_max_contacts_reported", "body", "amount"), &Physics2DServer::body_set_max_contacts_reported);
ClassDB::bind_method(D_METHOD("body_get_max_contacts_reported", "body"), &Physics2DServer::body_get_max_contacts_reported);
- ClassDB::bind_method(D_METHOD("body_set_one_way_collision_direction", "body", "normal"), &Physics2DServer::body_set_one_way_collision_direction);
- ClassDB::bind_method(D_METHOD("body_get_one_way_collision_direction", "body"), &Physics2DServer::body_get_one_way_collision_direction);
-
- ClassDB::bind_method(D_METHOD("body_set_one_way_collision_max_depth", "body", "depth"), &Physics2DServer::body_set_one_way_collision_max_depth);
- ClassDB::bind_method(D_METHOD("body_get_one_way_collision_max_depth", "body"), &Physics2DServer::body_get_one_way_collision_max_depth);
-
ClassDB::bind_method(D_METHOD("body_set_omit_force_integration", "body", "enable"), &Physics2DServer::body_set_omit_force_integration);
ClassDB::bind_method(D_METHOD("body_is_omitting_force_integration", "body"), &Physics2DServer::body_is_omitting_force_integration);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 80113dd7d6..f50faa42eb 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -332,6 +332,8 @@ public:
virtual void area_remove_shape(RID p_area, int p_shape_idx) = 0;
virtual void area_clear_shapes(RID p_area) = 0;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) = 0;
+
virtual void area_attach_object_instance_ID(RID p_area, ObjectID p_ID) = 0;
virtual ObjectID area_get_object_instance_ID(RID p_area) const = 0;
@@ -380,8 +382,8 @@ public:
virtual Transform2D body_get_shape_transform(RID p_body, int p_shape_idx) const = 0;
virtual Variant body_get_shape_metadata(RID p_body, int p_shape_idx) const = 0;
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) = 0;
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const = 0;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled) = 0;
+ virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled) = 0;
virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0;
virtual void body_clear_shapes(RID p_body) = 0;
@@ -451,12 +453,6 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) = 0;
virtual int body_get_max_contacts_reported(RID p_body) const = 0;
- virtual void body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction) = 0;
- virtual Vector2 body_get_one_way_collision_direction(RID p_body) const = 0;
-
- virtual void body_set_one_way_collision_max_depth(RID p_body, float p_max_depth) = 0;
- virtual float body_get_one_way_collision_max_depth(RID p_body) const = 0;
-
//missing remove
virtual void body_set_contacts_reported_depth_treshold(RID p_body, float p_treshold) = 0;
virtual float body_get_contacts_reported_depth_treshold(RID p_body) const = 0;
@@ -478,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 07d6542b62..5b60a46ade 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;
@@ -444,6 +448,7 @@ public:
virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0;
virtual void particles_set_amount(RID p_particles, int p_amount) = 0;
virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0;
+ virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0;
virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0;
virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0;
virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0;
@@ -453,6 +458,7 @@ public:
virtual void particles_set_process_material(RID p_particles, RID p_material) = 0;
virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
+ virtual void particles_restart(RID p_particles) = 0;
virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order) = 0;
@@ -612,6 +618,7 @@ public:
TYPE_POLYGON,
TYPE_MESH,
TYPE_MULTIMESH,
+ TYPE_PARTICLES,
TYPE_CIRCLE,
TYPE_TRANSFORM,
TYPE_CLIP_IGNORE,
@@ -707,6 +714,16 @@ public:
CommandMultiMesh() { type = TYPE_MULTIMESH; }
};
+ struct CommandParticles : public Command {
+
+ RID particles;
+ RID texture;
+ RID normal_map;
+ int h_frames;
+ int v_frames;
+ CommandParticles() { type = TYPE_PARTICLES; }
+ };
+
struct CommandCircle : public Command {
Point2 pos;
@@ -845,6 +862,15 @@ public:
r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
} break;
+ case Item::Command::TYPE_PARTICLES: {
+
+ const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c);
+ if (particles_cmd->particles.is_valid()) {
+ Rect3 aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles);
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+ }
+
+ } break;
case Item::Command::TYPE_CIRCLE: {
const Item::CommandCircle *circle = static_cast<const Item::CommandCircle *>(c);
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 81139ecc1c..42f1a98826 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -212,6 +212,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["NUMBER"] = ShaderLanguage::TYPE_UINT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["INDEX"] = ShaderLanguage::TYPE_INT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["EMISSION_TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["RANDOM_SEED"] = ShaderLanguage::TYPE_UINT;
shader_modes[VS::SHADER_PARTICLES].modes.insert("billboard");
shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_force");
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 2ef1fd417b..1227863b72 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -58,6 +58,12 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
if (!ci->visible)
return;
+ if (p_canvas_item->children_order_dirty) {
+
+ p_canvas_item->child_items.sort_custom<ItemIndexSort>();
+ p_canvas_item->children_order_dirty = false;
+ }
+
Rect2 rect = ci->get_rect();
Transform2D xform = p_transform * ci->xform;
Rect2 global_rect = xform.xform(rect);
@@ -171,6 +177,12 @@ void VisualServerCanvas::render_canvas(Canvas *p_canvas, const Transform2D &p_tr
VSG::canvas_render->canvas_begin();
+ if (p_canvas->children_order_dirty) {
+
+ p_canvas->child_items.sort();
+ p_canvas->children_order_dirty = false;
+ }
+
int l = p_canvas->child_items.size();
Canvas::ChildItem *ci = p_canvas->child_items.ptr();
@@ -637,6 +649,25 @@ void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID
canvas_item->commands.push_back(m);
}
+void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames) {
+
+ Item *canvas_item = canvas_item_owner.getornull(p_item);
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandParticles *part = memnew(Item::CommandParticles);
+ ERR_FAIL_COND(!part);
+ part->particles = p_particles;
+ part->texture = p_texture;
+ part->normal_map = p_normal;
+ part->h_frames = p_h_frames;
+ part->v_frames = p_v_frames;
+
+ //take the chance and request processing for them, at least once until they become visible again
+ VSG::storage->particles_request_process(p_particles);
+
+ canvas_item->commands.push_back(part);
+}
+
void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_skeleton) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
index 2c86b14c70..57c7515367 100644
--- a/servers/visual/visual_server_canvas.h
+++ b/servers/visual/visual_server_canvas.h
@@ -63,6 +63,14 @@ public:
}
};
+ struct ItemIndexSort {
+
+ _FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const {
+
+ return p_left->index < p_right->index;
+ }
+ };
+
struct ItemPtrSort {
_FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const {
@@ -173,6 +181,7 @@ public:
void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_skeleton = RID());
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_skeleton = RID());
+ void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames);
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index c48bee7fa4..e201f6a8c0 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -862,6 +862,7 @@ public:
BIND2(particles_set_emitting, RID, bool)
BIND2(particles_set_amount, RID, int)
BIND2(particles_set_lifetime, RID, float)
+ BIND2(particles_set_one_shot, RID, bool)
BIND2(particles_set_pre_process_time, RID, float)
BIND2(particles_set_explosiveness_ratio, RID, float)
BIND2(particles_set_randomness_ratio, RID, float)
@@ -871,13 +872,15 @@ public:
BIND2(particles_set_process_material, RID, RID)
BIND2(particles_set_fixed_fps, RID, int)
BIND2(particles_set_fractional_delta, RID, bool)
+ BIND1(particles_restart, RID)
BIND2(particles_set_draw_order, RID, VS::ParticlesDrawOrder)
BIND2(particles_set_draw_passes, RID, int)
BIND3(particles_set_draw_pass_mesh, RID, int, RID)
- BIND1R(Rect3, particles_get_current_aabb, RID);
+ BIND1R(Rect3, particles_get_current_aabb, RID)
+ BIND2(particles_set_emission_transform, RID, const Transform &)
#undef BINDBASE
//from now on, calls forwarded to this singleton
@@ -1049,6 +1052,7 @@ public:
BIND8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
BIND3(canvas_item_add_mesh, RID, const RID &, RID)
BIND3(canvas_item_add_multimesh, RID, RID, RID)
+ BIND6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
BIND2(canvas_item_add_clip_ignore, RID, bool)
BIND2(canvas_item_set_sort_children_by_y, RID, bool)
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);
}
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 94cbfc815e..9f49377fa8 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -306,6 +306,7 @@ public:
FUNC2(particles_set_emitting, RID, bool)
FUNC2(particles_set_amount, RID, int)
FUNC2(particles_set_lifetime, RID, float)
+ FUNC2(particles_set_one_shot, RID, bool)
FUNC2(particles_set_pre_process_time, RID, float)
FUNC2(particles_set_explosiveness_ratio, RID, float)
FUNC2(particles_set_randomness_ratio, RID, float)
@@ -315,11 +316,13 @@ public:
FUNC2(particles_set_process_material, RID, RID)
FUNC2(particles_set_fixed_fps, RID, int)
FUNC2(particles_set_fractional_delta, RID, bool)
+ FUNC1(particles_restart, RID)
FUNC2(particles_set_draw_order, RID, VS::ParticlesDrawOrder)
FUNC2(particles_set_draw_passes, RID, int)
FUNC3(particles_set_draw_pass_mesh, RID, int, RID)
+ FUNC2(particles_set_emission_transform, RID, const Transform &)
FUNC1R(Rect3, particles_get_current_aabb, RID)
@@ -476,6 +479,7 @@ public:
FUNC8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
FUNC3(canvas_item_add_mesh, RID, const RID &, RID)
FUNC3(canvas_item_add_multimesh, RID, RID, RID)
+ FUNC6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
FUNC2(canvas_item_add_clip_ignore, RID, bool)
FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 6c57275b3a..eb0848ff50 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "visual_server.h"
#include "global_config.h"
-#include "method_bind_ext.inc"
+#include "method_bind_ext.gen.inc"
VisualServer *VisualServer::singleton = NULL;
VisualServer *(*VisualServer::create_func)() = NULL;
@@ -137,7 +137,7 @@ void VisualServer::_free_internal_rids() {
if (test_material.is_valid())
free(test_material);
- for (int i = 0; i < 16; i++) {
+ for (int i = 0; i < 32; i++) {
if (material_2d[i].is_valid())
free(material_2d[i]);
}
@@ -284,7 +284,7 @@ RID VisualServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) {
return mesh;
}
-RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_alpha, bool p_opaque_prepass) {
+RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass) {
int version = 0;
if (p_shaded)
@@ -295,6 +295,8 @@ RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_
version |= 4;
if (p_opaque_prepass)
version |= 8;
+ if (p_double_sided)
+ version |= 16;
if (material_2d[version].is_valid())
return material_2d[version];
@@ -305,7 +307,7 @@ RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_
fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_DISCARD_ALPHA,p_cut_alpha);
material_set_flag(material_2d[version],MATERIAL_FLAG_UNSHADED,!p_shaded);
- material_set_flag(material_2d[version],MATERIAL_FLAG_DOUBLE_SIDED,true);
+ material_set_flag(material_2d[version], MATERIAL_FLAG_DOUBLE_SIDED, p_double_sided);
material_set_depth_draw_mode(material_2d[version],p_opaque_prepass?MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA:MATERIAL_DEPTH_DRAW_OPAQUE_ONLY);
fixed_material_set_texture(material_2d[version],FIXED_MATERIAL_PARAM_DIFFUSE,get_white_texture());
//material cut alpha?*/
diff --git a/servers/visual_server.h b/servers/visual_server.h
index a27b32f54f..4d2a983751 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -60,7 +60,7 @@ protected:
RID test_texture;
RID white_texture;
RID test_material;
- RID material_2d[16];
+ RID material_2d[32];
Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, Rect3 &r_aabb, Vector<Rect3> r_bone_aabb);
@@ -478,6 +478,7 @@ public:
virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0;
virtual void particles_set_amount(RID p_particles, int p_amount) = 0;
virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0;
+ virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0;
virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0;
virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0;
virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0;
@@ -487,6 +488,7 @@ public:
virtual void particles_set_process_material(RID p_particles, RID p_material) = 0;
virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
+ virtual void particles_restart(RID p_particles) = 0;
enum ParticlesDrawOrder {
PARTICLES_DRAW_ORDER_INDEX,
@@ -501,6 +503,8 @@ public:
virtual Rect3 particles_get_current_aabb(RID p_particles) = 0;
+ virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; //this is only used for 2D, in 3D it's automatic
+
/* CAMERA API */
virtual RID camera_create() = 0;
@@ -793,6 +797,7 @@ public:
virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_skeleton = RID()) = 0;
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_skeleton = RID()) = 0;
+ virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, int p_h_frames, int p_v_frames) = 0;
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore) = 0;
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) = 0;
@@ -909,7 +914,7 @@ public:
/* Materials for 2D on 3D */
- RID material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_alpha, bool p_opaque_prepass);
+ RID material_2d_get(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass);
/* TESTING */