summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/audio/audio_rb_resampler.cpp2
-rw-r--r--servers/physics_2d/godot_body_2d.h10
-rw-r--r--servers/physics_2d/godot_body_pair_2d.cpp125
-rw-r--r--servers/physics_2d/godot_body_pair_2d.h3
-rw-r--r--servers/physics_2d/godot_physics_server_2d.cpp21
-rw-r--r--servers/physics_2d/godot_physics_server_2d.h3
-rw-r--r--servers/physics_2d/godot_space_2d.cpp14
-rw-r--r--servers/physics_2d/godot_space_2d.h5
-rw-r--r--servers/physics_2d/godot_step_2d.cpp4
-rw-r--r--servers/physics_2d/godot_step_2d.h2
-rw-r--r--servers/physics_3d/godot_body_pair_3d.cpp130
-rw-r--r--servers/physics_3d/godot_body_pair_3d.h1
-rw-r--r--servers/physics_3d/godot_physics_server_3d.cpp21
-rw-r--r--servers/physics_3d/godot_physics_server_3d.h3
-rw-r--r--servers/physics_3d/godot_space_3d.cpp14
-rw-r--r--servers/physics_3d/godot_space_3d.h5
-rw-r--r--servers/physics_3d/godot_step_3d.cpp4
-rw-r--r--servers/physics_3d/godot_step_3d.h2
-rw-r--r--servers/physics_server_2d.cpp6
-rw-r--r--servers/physics_server_2d.h9
-rw-r--r--servers/physics_server_2d_wrap_mt.h1
-rw-r--r--servers/physics_server_3d.cpp6
-rw-r--r--servers/physics_server_3d.h9
-rw-r--r--servers/physics_server_3d_wrap_mt.h1
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp1
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.cpp3
-rw-r--r--servers/rendering/rendering_device.cpp10
-rw-r--r--servers/rendering/shader_language.cpp131
-rw-r--r--servers/rendering/shader_language.h3
-rw-r--r--servers/rendering/shader_types.cpp32
-rw-r--r--servers/rendering/shader_warnings.cpp4
-rw-r--r--servers/rendering/shader_warnings.h2
-rw-r--r--servers/rendering_server.cpp62
-rw-r--r--servers/rendering_server.h57
35 files changed, 407 insertions, 305 deletions
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index d9c442facf..b37965a988 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -43,7 +43,7 @@ int AudioRBResampler::get_channel_count() const {
// Linear interpolation based sample rate conversion (low quality)
// Note that AudioStreamPlaybackResampled::mix has better algorithm,
-// but it wasn't obvious to integrate that with VideoPlayer
+// but it wasn't obvious to integrate that with VideoStreamPlayer
template <int C>
uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_increment) {
uint32_t read = offset & MIX_FRAC_MASK;
diff --git a/servers/physics_2d/godot_body_2d.h b/servers/physics_2d/godot_body_2d.h
index ba4c39737a..f00512fe92 100644
--- a/servers/physics_2d/godot_body_2d.h
+++ b/servers/physics_2d/godot_body_2d.h
@@ -234,9 +234,15 @@ public:
angular_velocity += _inv_inertia * p_torque;
}
- _FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) {
+ _FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2(), real_t p_max_delta_av = -1.0) {
biased_linear_velocity += p_impulse * _inv_mass;
- biased_angular_velocity += _inv_inertia * (p_position - center_of_mass).cross(p_impulse);
+ if (p_max_delta_av != 0.0) {
+ real_t delta_av = _inv_inertia * (p_position - center_of_mass).cross(p_impulse);
+ if (p_max_delta_av > 0 && delta_av > p_max_delta_av) {
+ delta_av = p_max_delta_av;
+ }
+ biased_angular_velocity += delta_av;
+ }
}
void set_active(bool p_active);
diff --git a/servers/physics_2d/godot_body_pair_2d.cpp b/servers/physics_2d/godot_body_pair_2d.cpp
index 67b0f21456..f8ec0b6512 100644
--- a/servers/physics_2d/godot_body_pair_2d.cpp
+++ b/servers/physics_2d/godot_body_pair_2d.cpp
@@ -34,6 +34,9 @@
#define ACCUMULATE_IMPULSES
+#define MIN_VELOCITY 0.001
+#define MAX_BIAS_ROTATION (Math_PI / 8)
+
void GodotBodyPair2D::_add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self) {
GodotBodyPair2D *self = (GodotBodyPair2D *)p_self;
@@ -41,8 +44,6 @@ void GodotBodyPair2D::_add_contact(const Vector2 &p_point_A, const Vector2 &p_po
}
void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B) {
- // check if we already have the contact
-
Vector2 local_A = A->get_inv_transform().basis_xform(p_point_A);
Vector2 local_B = B->get_inv_transform().basis_xform(p_point_B - offset_B);
@@ -51,46 +52,48 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
ERR_FAIL_COND(new_index >= (MAX_CONTACTS + 1));
Contact contact;
-
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_tangent_impulse = 0;
contact.local_A = local_A;
contact.local_B = local_B;
- contact.reused = true;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0; // will be computed in setup()
-
- // attempt to determine if the contact will be reused
+ contact.used = true;
+ // Attempt to determine if the contact will be reused.
real_t recycle_radius_2 = space->get_contact_recycle_radius() * space->get_contact_recycle_radius();
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (
- c.local_A.distance_squared_to(local_A) < (recycle_radius_2) &&
+ if (c.local_A.distance_squared_to(local_A) < (recycle_radius_2) &&
c.local_B.distance_squared_to(local_B) < (recycle_radius_2)) {
contact.acc_normal_impulse = c.acc_normal_impulse;
contact.acc_tangent_impulse = c.acc_tangent_impulse;
contact.acc_bias_impulse = c.acc_bias_impulse;
- new_index = i;
- break;
+ contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass;
+ c = contact;
+ return;
}
}
- // figure out if the contact amount must be reduced to fit the new contact
-
+ // Figure out if the contact amount must be reduced to fit the new contact.
if (new_index == MAX_CONTACTS) {
- // remove the contact with the minimum depth
-
- int least_deep = -1;
- real_t min_depth = 1e10;
+ // Remove the contact with the minimum depth.
const Transform2D &transform_A = A->get_transform();
const Transform2D &transform_B = B->get_transform();
- for (int i = 0; i <= contact_count; i++) {
- Contact &c = (i == contact_count) ? contact : contacts[i];
+ int least_deep = -1;
+ real_t min_depth;
+
+ // Start with depth for new contact.
+ {
+ Vector2 global_A = transform_A.basis_xform(contact.local_A);
+ Vector2 global_B = transform_B.basis_xform(contact.local_B) + offset_B;
+
+ Vector2 axis = global_A - global_B;
+ min_depth = axis.dot(contact.normal);
+ }
+
+ for (int i = 0; i < contact_count; i++) {
+ const Contact &c = contacts[i];
Vector2 global_A = transform_A.basis_xform(c.local_A);
Vector2 global_B = transform_B.basis_xform(c.local_B) + offset_B;
@@ -103,10 +106,8 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
}
}
- ERR_FAIL_COND(least_deep == -1);
-
- if (least_deep < contact_count) { //replace the last deep contact by the new one
-
+ if (least_deep > -1) {
+ // Replace the least deep contact by the new one.
contacts[least_deep] = contact;
}
@@ -114,15 +115,11 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
}
contacts[new_index] = contact;
-
- if (new_index == contact_count) {
- contact_count++;
- }
+ contact_count++;
}
void GodotBodyPair2D::_validate_contacts() {
- //make sure to erase contacts that are no longer valid
-
+ // Make sure to erase contacts that are no longer valid.
real_t max_separation = space->get_contact_max_separation();
real_t max_separation2 = max_separation * max_separation;
@@ -133,11 +130,11 @@ void GodotBodyPair2D::_validate_contacts() {
Contact &c = contacts[i];
bool erase = false;
- if (!c.reused) {
- //was left behind in previous frame
+ if (!c.used) {
+ // Was left behind in previous frame.
erase = true;
} else {
- c.reused = false;
+ c.used = false;
Vector2 global_A = transform_A.basis_xform(c.local_A);
Vector2 global_B = transform_B.basis_xform(c.local_B) + offset_B;
@@ -150,10 +147,10 @@ void GodotBodyPair2D::_validate_contacts() {
}
if (erase) {
- // contact no longer needed, remove
+ // Contact no longer needed, remove.
if ((i + 1) < contact_count) {
- // swap with the last one
+ // Swap with the last one.
SWAP(contacts[i], contacts[contact_count - 1]);
}
@@ -302,9 +299,6 @@ bool GodotBodyPair2D::setup(real_t p_step) {
bool valid = false;
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (!c.reused) {
- continue;
- }
if (c.normal.dot(direction) > -CMP_EPSILON) { //greater (normal inverted)
continue;
}
@@ -323,9 +317,6 @@ bool GodotBodyPair2D::setup(real_t p_step) {
bool valid = false;
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (!c.reused) {
- continue;
- }
if (c.normal.dot(direction) < CMP_EPSILON) { //less (normal ok)
continue;
}
@@ -350,7 +341,7 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = 0.3;
+ real_t bias = space->get_contact_bias();
GodotShape2D *shape_A_ptr = A->get_shape(shape_A);
GodotShape2D *shape_B_ptr = B->get_shape(shape_B);
@@ -389,7 +380,7 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
Vector2 axis = global_A - global_B;
real_t depth = axis.dot(c.normal);
- if (depth <= 0.0 || !c.reused) {
+ if (depth <= 0.0) {
continue;
}
@@ -400,8 +391,8 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
}
#endif
- c.rA = global_A;
- c.rB = global_B - offset_B;
+ c.rA = global_A - A->get_center_of_mass();
+ c.rB = global_B - B->get_center_of_mass() - offset_B;
if (A->can_report_contacts()) {
Vector2 crB(-B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x);
@@ -434,7 +425,6 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
c.bias = -bias * inv_dt * MIN(0.0f, -depth + max_penetration);
c.depth = depth;
- //c.acc_bias_impulse=0;
#ifdef ACCUMULATE_IMPULSES
{
@@ -442,10 +432,10 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
Vector2 P = c.acc_normal_impulse * c.normal + c.acc_tangent_impulse * tangent;
if (collide_A) {
- A->apply_impulse(-P, c.rA);
+ A->apply_impulse(-P, c.rA + A->get_center_of_mass());
}
if (collide_B) {
- B->apply_impulse(P, c.rB);
+ B->apply_impulse(P, c.rB + B->get_center_of_mass());
}
}
#endif
@@ -470,6 +460,11 @@ void GodotBodyPair2D::solve(real_t p_step) {
return;
}
+ const real_t max_bias_av = MAX_BIAS_ROTATION / p_step;
+
+ real_t inv_mass_A = collide_A ? A->get_inv_mass() : 0.0;
+ real_t inv_mass_B = collide_B ? B->get_inv_mass() : 0.0;
+
for (int i = 0; i < contact_count; ++i) {
Contact &c = contacts[i];
@@ -489,6 +484,7 @@ void GodotBodyPair2D::solve(real_t p_step) {
real_t vn = dv.dot(c.normal);
real_t vbn = dbv.dot(c.normal);
+
Vector2 tangent = c.normal.orthogonal();
real_t vt = dv.dot(tangent);
@@ -499,10 +495,31 @@ void GodotBodyPair2D::solve(real_t p_step) {
Vector2 jb = c.normal * (c.acc_bias_impulse - jbnOld);
if (collide_A) {
- A->apply_bias_impulse(-jb, c.rA);
+ A->apply_bias_impulse(-jb, c.rA + A->get_center_of_mass(), max_bias_av);
}
if (collide_B) {
- B->apply_bias_impulse(jb, c.rB);
+ B->apply_bias_impulse(jb, c.rB + B->get_center_of_mass(), max_bias_av);
+ }
+
+ crbA = Vector2(-A->get_biased_angular_velocity() * c.rA.y, A->get_biased_angular_velocity() * c.rA.x);
+ crbB = Vector2(-B->get_biased_angular_velocity() * c.rB.y, B->get_biased_angular_velocity() * c.rB.x);
+ dbv = B->get_biased_linear_velocity() + crbB - A->get_biased_linear_velocity() - crbA;
+
+ vbn = dbv.dot(c.normal);
+
+ if (Math::abs(-vbn + c.bias) > MIN_VELOCITY) {
+ real_t jbn_com = (-vbn + c.bias) / (inv_mass_A + inv_mass_B);
+ real_t jbnOld_com = c.acc_bias_impulse_center_of_mass;
+ c.acc_bias_impulse_center_of_mass = MAX(jbnOld_com + jbn_com, 0.0f);
+
+ Vector2 jb_com = c.normal * (c.acc_bias_impulse_center_of_mass - jbnOld_com);
+
+ if (collide_A) {
+ A->apply_bias_impulse(-jb_com, A->get_center_of_mass(), 0.0f);
+ }
+ if (collide_B) {
+ B->apply_bias_impulse(jb_com, B->get_center_of_mass(), 0.0f);
+ }
}
real_t jn = -(c.bounce + vn) * c.mass_normal;
@@ -519,10 +536,10 @@ void GodotBodyPair2D::solve(real_t p_step) {
Vector2 j = c.normal * (c.acc_normal_impulse - jnOld) + tangent * (c.acc_tangent_impulse - jtOld);
if (collide_A) {
- A->apply_impulse(-j, c.rA);
+ A->apply_impulse(-j, c.rA + A->get_center_of_mass());
}
if (collide_B) {
- B->apply_impulse(j, c.rB);
+ B->apply_impulse(j, c.rB + B->get_center_of_mass());
}
}
}
diff --git a/servers/physics_2d/godot_body_pair_2d.h b/servers/physics_2d/godot_body_pair_2d.h
index 0938ab542b..aa1b5b7886 100644
--- a/servers/physics_2d/godot_body_pair_2d.h
+++ b/servers/physics_2d/godot_body_pair_2d.h
@@ -62,13 +62,14 @@ class GodotBodyPair2D : public GodotConstraint2D {
real_t acc_normal_impulse = 0.0; // accumulated normal impulse (Pn)
real_t acc_tangent_impulse = 0.0; // accumulated tangent impulse (Pt)
real_t acc_bias_impulse = 0.0; // accumulated normal impulse for position bias (Pnb)
+ real_t acc_bias_impulse_center_of_mass = 0.0; // accumulated normal impulse for position bias applied to com
real_t mass_normal, mass_tangent = 0.0;
real_t bias = 0.0;
real_t depth = 0.0;
bool active = false;
+ bool used = false;
Vector2 rA, rB;
- bool reused = false;
real_t bounce = 0.0;
};
diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp
index 8ac27077fc..c88fd39657 100644
--- a/servers/physics_2d/godot_physics_server_2d.cpp
+++ b/servers/physics_2d/godot_physics_server_2d.cpp
@@ -1214,21 +1214,16 @@ void GodotPhysicsServer2D::free(RID p_rid) {
} else {
ERR_FAIL_MSG("Invalid ID.");
}
-};
+}
void GodotPhysicsServer2D::set_active(bool p_active) {
active = p_active;
-};
-
-void GodotPhysicsServer2D::set_collision_iterations(int p_iterations) {
- iterations = p_iterations;
-};
+}
void GodotPhysicsServer2D::init() {
doing_sync = false;
- iterations = 8; // 8?
stepper = memnew(GodotStep2D);
-};
+}
void GodotPhysicsServer2D::step(real_t p_step) {
if (!active) {
@@ -1241,16 +1236,16 @@ void GodotPhysicsServer2D::step(real_t p_step) {
active_objects = 0;
collision_pairs = 0;
for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- stepper->step((GodotSpace2D *)E->get(), p_step, iterations);
+ stepper->step((GodotSpace2D *)E->get(), p_step);
island_count += E->get()->get_island_count();
active_objects += E->get()->get_active_objects();
collision_pairs += E->get()->get_collision_pairs();
}
-};
+}
void GodotPhysicsServer2D::sync() {
doing_sync = true;
-};
+}
void GodotPhysicsServer2D::flush_queries() {
if (!active) {
@@ -1308,7 +1303,7 @@ void GodotPhysicsServer2D::end_sync() {
void GodotPhysicsServer2D::finish() {
memdelete(stepper);
-};
+}
void GodotPhysicsServer2D::_update_shapes() {
while (pending_shape_update_list.first()) {
@@ -1340,4 +1335,4 @@ GodotPhysicsServer2D::GodotPhysicsServer2D(bool p_using_threads) {
GodotBroadPhase2D::create_func = GodotBroadPhase2DBVH::_create;
using_threads = p_using_threads;
-};
+}
diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h
index 1f544fee72..ad6d5e0940 100644
--- a/servers/physics_2d/godot_physics_server_2d.h
+++ b/servers/physics_2d/godot_physics_server_2d.h
@@ -45,7 +45,6 @@ class GodotPhysicsServer2D : public PhysicsServer2D {
friend class GodotPhysicsDirectSpaceState2D;
friend class GodotPhysicsDirectBodyState2D;
bool active = true;
- int iterations = 0;
bool doing_sync = false;
int island_count = 0;
@@ -283,8 +282,6 @@ public:
virtual void end_sync() override;
virtual void finish() override;
- virtual void set_collision_iterations(int p_iterations) override;
-
virtual bool is_flushing_queries() const override { return flushing_queries; }
int get_process_info(ProcessInfo p_info) override;
diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp
index 7a5eb26bb3..5e6f233667 100644
--- a/servers/physics_2d/godot_space_2d.cpp
+++ b/servers/physics_2d/godot_space_2d.cpp
@@ -1138,9 +1138,12 @@ void GodotSpace2D::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_v
case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
contact_max_separation = p_value;
break;
- case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
contact_max_allowed_penetration = p_value;
break;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ contact_bias = p_value;
+ break;
case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
body_linear_velocity_sleep_threshold = p_value;
break;
@@ -1153,6 +1156,9 @@ void GodotSpace2D::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_v
case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
constraint_bias = p_value;
break;
+ case PhysicsServer2D::SPACE_PARAM_SOLVER_ITERATIONS:
+ solver_iterations = p_value;
+ break;
}
}
@@ -1162,8 +1168,10 @@ real_t GodotSpace2D::get_param(PhysicsServer2D::SpaceParameter p_param) const {
return contact_recycle_radius;
case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
return contact_max_separation;
- case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
return contact_max_allowed_penetration;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ return contact_bias;
case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
return body_linear_velocity_sleep_threshold;
case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
@@ -1172,6 +1180,8 @@ real_t GodotSpace2D::get_param(PhysicsServer2D::SpaceParameter p_param) const {
return body_time_to_sleep;
case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
return constraint_bias;
+ case PhysicsServer2D::SPACE_PARAM_SOLVER_ITERATIONS:
+ return solver_iterations;
}
return 0;
}
diff --git a/servers/physics_2d/godot_space_2d.h b/servers/physics_2d/godot_space_2d.h
index b155a834b6..c0d06706d8 100644
--- a/servers/physics_2d/godot_space_2d.h
+++ b/servers/physics_2d/godot_space_2d.h
@@ -96,9 +96,12 @@ private:
GodotArea2D *area = nullptr;
+ int solver_iterations = 16;
+
real_t contact_recycle_radius = 1.0;
real_t contact_max_separation = 1.5;
real_t contact_max_allowed_penetration = 0.3;
+ real_t contact_bias = 0.8;
real_t constraint_bias = 0.2;
enum {
@@ -155,9 +158,11 @@ public:
void remove_object(GodotCollisionObject2D *p_object);
const Set<GodotCollisionObject2D *> &get_objects() const;
+ _FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; }
_FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; }
_FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; }
_FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; }
+ _FORCE_INLINE_ real_t get_contact_bias() const { return contact_bias; }
_FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; }
_FORCE_INLINE_ real_t get_body_linear_velocity_sleep_threshold() const { return body_linear_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_angular_velocity_sleep_threshold() const { return body_angular_velocity_sleep_threshold; }
diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp
index 00d11acdab..bc604e380a 100644
--- a/servers/physics_2d/godot_step_2d.cpp
+++ b/servers/physics_2d/godot_step_2d.cpp
@@ -124,14 +124,14 @@ void GodotStep2D::_check_suspend(LocalVector<GodotBody2D *> &p_body_island) cons
}
}
-void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta, int p_iterations) {
+void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta) {
p_space->lock(); // can't access space during this
p_space->setup(); //update inertias, etc
p_space->set_last_step(p_delta);
- iterations = p_iterations;
+ iterations = p_space->get_solver_iterations();
delta = p_delta;
const SelfList<GodotBody2D>::List *body_list = &p_space->get_active_body_list();
diff --git a/servers/physics_2d/godot_step_2d.h b/servers/physics_2d/godot_step_2d.h
index efec243632..4038417854 100644
--- a/servers/physics_2d/godot_step_2d.h
+++ b/servers/physics_2d/godot_step_2d.h
@@ -55,7 +55,7 @@ class GodotStep2D {
void _check_suspend(LocalVector<GodotBody2D *> &p_body_island) const;
public:
- void step(GodotSpace2D *p_space, real_t p_delta, int p_iterations);
+ void step(GodotSpace2D *p_space, real_t p_delta);
GodotStep2D();
~GodotStep2D();
};
diff --git a/servers/physics_3d/godot_body_pair_3d.cpp b/servers/physics_3d/godot_body_pair_3d.cpp
index 8a701466ed..5c25ba9537 100644
--- a/servers/physics_3d/godot_body_pair_3d.cpp
+++ b/servers/physics_3d/godot_body_pair_3d.cpp
@@ -44,11 +44,6 @@ void GodotBodyPair3D::_contact_added_callback(const Vector3 &p_point_A, int p_in
}
void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B) {
- // check if we already have the contact
-
- //Vector3 local_A = A->get_inv_transform().xform(p_point_A);
- //Vector3 local_B = B->get_inv_transform().xform(p_point_B);
-
Vector3 local_A = A->get_inv_transform().basis.xform(p_point_A);
Vector3 local_B = B->get_inv_transform().basis.xform(p_point_B - offset_B);
@@ -57,19 +52,14 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
ERR_FAIL_COND(new_index >= (MAX_CONTACTS + 1));
Contact contact;
-
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_bias_impulse_center_of_mass = 0;
- contact.acc_tangent_impulse = Vector3();
contact.index_A = p_index_A;
contact.index_B = p_index_B;
contact.local_A = local_A;
contact.local_B = local_B;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0; // will be computed in setup()
+ contact.used = true;
- // attempt to determine if the contact will be reused
+ // Attempt to determine if the contact will be reused.
real_t contact_recycle_radius = space->get_contact_recycle_radius();
for (int i = 0; i < contact_count; i++) {
@@ -80,23 +70,34 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
contact.acc_bias_impulse = c.acc_bias_impulse;
contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass;
contact.acc_tangent_impulse = c.acc_tangent_impulse;
- new_index = i;
- break;
+ c = contact;
+ return;
}
}
- // figure out if the contact amount must be reduced to fit the new contact
-
+ // Figure out if the contact amount must be reduced to fit the new contact.
if (new_index == MAX_CONTACTS) {
- // remove the contact with the minimum depth
+ // Remove the contact with the minimum depth.
+
+ const Basis &basis_A = A->get_transform().basis;
+ const Basis &basis_B = B->get_transform().basis;
int least_deep = -1;
- real_t min_depth = 1e10;
+ real_t min_depth;
+
+ // Start with depth for new contact.
+ {
+ Vector3 global_A = basis_A.xform(contact.local_A);
+ Vector3 global_B = basis_B.xform(contact.local_B) + offset_B;
+
+ Vector3 axis = global_A - global_B;
+ min_depth = axis.dot(contact.normal);
+ }
- for (int i = 0; i <= contact_count; i++) {
- Contact &c = (i == contact_count) ? contact : contacts[i];
- Vector3 global_A = A->get_transform().basis.xform(c.local_A);
- Vector3 global_B = B->get_transform().basis.xform(c.local_B) + offset_B;
+ for (int i = 0; i < contact_count; i++) {
+ const Contact &c = contacts[i];
+ Vector3 global_A = basis_A.xform(c.local_A);
+ Vector3 global_B = basis_B.xform(c.local_B) + offset_B;
Vector3 axis = global_A - global_B;
real_t depth = axis.dot(c.normal);
@@ -107,10 +108,8 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
}
}
- ERR_FAIL_COND(least_deep == -1);
-
- if (least_deep < contact_count) { //replace the last deep contact by the new one
-
+ if (least_deep > -1) {
+ // Replace the least deep contact by the new one.
contacts[least_deep] = contact;
}
@@ -118,29 +117,41 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
}
contacts[new_index] = contact;
-
- if (new_index == contact_count) {
- contact_count++;
- }
+ contact_count++;
}
void GodotBodyPair3D::validate_contacts() {
- //make sure to erase contacts that are no longer valid
+ // Make sure to erase contacts that are no longer valid.
+ real_t max_separation = space->get_contact_max_separation();
+ real_t max_separation2 = max_separation * max_separation;
+
+ const Basis &basis_A = A->get_transform().basis;
+ const Basis &basis_B = B->get_transform().basis;
- real_t contact_max_separation = space->get_contact_max_separation();
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- Vector3 global_A = A->get_transform().basis.xform(c.local_A);
- Vector3 global_B = B->get_transform().basis.xform(c.local_B) + offset_B;
- Vector3 axis = global_A - global_B;
- real_t depth = axis.dot(c.normal);
+ bool erase = false;
+ if (!c.used) {
+ // Was left behind in previous frame.
+ erase = true;
+ } else {
+ c.used = false;
+
+ Vector3 global_A = basis_A.xform(c.local_A);
+ Vector3 global_B = basis_B.xform(c.local_B) + offset_B;
+ Vector3 axis = global_A - global_B;
+ real_t depth = axis.dot(c.normal);
- if (depth < -contact_max_separation || (global_B + c.normal * depth - global_A).length() > contact_max_separation) {
- // contact no longer needed, remove
+ if (depth < -max_separation || (global_B + c.normal * depth - global_A).length_squared() > max_separation2) {
+ erase = true;
+ }
+ }
+ if (erase) {
+ // Contact no longer needed, remove.
if ((i + 1) < contact_count) {
- // swap with the last one
+ // Swap with the last one.
SWAP(contacts[i], contacts[contact_count - 1]);
}
@@ -260,7 +271,7 @@ bool GodotBodyPair3D::pre_solve(real_t p_step) {
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = (real_t)0.3;
+ real_t bias = 0.8;
GodotShape3D *shape_A_ptr = A->get_shape(shape_A);
GodotShape3D *shape_B_ptr = B->get_shape(shape_B);
@@ -353,8 +364,6 @@ bool GodotBodyPair3D::pre_solve(real_t p_step) {
if (collide_B) {
B->apply_impulse(j_vec, c.rB + B->get_center_of_mass());
}
- c.acc_bias_impulse = 0;
- c.acc_bias_impulse_center_of_mass = 0;
c.bounce = combine_bounce(A, B);
if (c.bounce) {
@@ -538,14 +547,10 @@ void GodotBodySoftBodyPair3D::contact_added_callback(const Vector3 &p_point_A, i
Contact contact;
contact.index_A = p_index_A;
contact.index_B = p_index_B;
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_bias_impulse_center_of_mass = 0;
- contact.acc_tangent_impulse = Vector3();
contact.local_A = local_A;
contact.local_B = local_B;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0;
+ contact.used = true;
// Attempt to determine if the contact will be reused.
real_t contact_recycle_radius = space->get_contact_recycle_radius();
@@ -571,20 +576,33 @@ void GodotBodySoftBodyPair3D::contact_added_callback(const Vector3 &p_point_A, i
void GodotBodySoftBodyPair3D::validate_contacts() {
// Make sure to erase contacts that are no longer valid.
- const Transform3D &transform_A = body->get_transform();
+ real_t max_separation = space->get_contact_max_separation();
+ real_t max_separation2 = max_separation * max_separation;
- real_t contact_max_separation = space->get_contact_max_separation();
+ const Transform3D &transform_A = body->get_transform();
uint32_t contact_count = contacts.size();
for (uint32_t contact_index = 0; contact_index < contact_count; ++contact_index) {
Contact &c = contacts[contact_index];
- Vector3 global_A = transform_A.xform(c.local_A);
- Vector3 global_B = soft_body->get_node_position(c.index_B) + c.local_B;
- Vector3 axis = global_A - global_B;
- real_t depth = axis.dot(c.normal);
+ bool erase = false;
+ if (!c.used) {
+ // Was left behind in previous frame.
+ erase = true;
+ } else {
+ c.used = false;
+
+ Vector3 global_A = transform_A.xform(c.local_A);
+ Vector3 global_B = soft_body->get_node_position(c.index_B) + c.local_B;
+ Vector3 axis = global_A - global_B;
+ real_t depth = axis.dot(c.normal);
+
+ if (depth < -max_separation || (global_B + c.normal * depth - global_A).length_squared() > max_separation2) {
+ erase = true;
+ }
+ }
- if (depth < -contact_max_separation || (global_B + c.normal * depth - global_A).length() > contact_max_separation) {
+ if (erase) {
// Contact no longer needed, remove.
if ((contact_index + 1) < contact_count) {
// Swap with the last one.
@@ -640,7 +658,7 @@ bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) {
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = (real_t)0.3;
+ real_t bias = space->get_contact_bias();
GodotShape3D *shape_A_ptr = body->get_shape(body_shape);
@@ -723,8 +741,6 @@ bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) {
if (soft_body_collides) {
soft_body->apply_node_impulse(c.index_B, j_vec);
}
- c.acc_bias_impulse = 0;
- c.acc_bias_impulse_center_of_mass = 0;
c.bounce = body->get_bounce();
diff --git a/servers/physics_3d/godot_body_pair_3d.h b/servers/physics_3d/godot_body_pair_3d.h
index c0a2424e05..7c2c31704b 100644
--- a/servers/physics_3d/godot_body_pair_3d.h
+++ b/servers/physics_3d/godot_body_pair_3d.h
@@ -54,6 +54,7 @@ protected:
real_t depth = 0.0;
bool active = false;
+ bool used = false;
Vector3 rA, rB; // Offset in world orientation with respect to center of mass
};
diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp
index 9acae62382..573a5d373f 100644
--- a/servers/physics_3d/godot_physics_server_3d.cpp
+++ b/servers/physics_3d/godot_physics_server_3d.cpp
@@ -1574,20 +1574,15 @@ void GodotPhysicsServer3D::free(RID p_rid) {
} else {
ERR_FAIL_MSG("Invalid ID.");
}
-};
+}
void GodotPhysicsServer3D::set_active(bool p_active) {
active = p_active;
-};
-
-void GodotPhysicsServer3D::set_collision_iterations(int p_iterations) {
- iterations = p_iterations;
-};
+}
void GodotPhysicsServer3D::init() {
- iterations = 8; // 8?
stepper = memnew(GodotStep3D);
-};
+}
void GodotPhysicsServer3D::step(real_t p_step) {
#ifndef _3D_DISABLED
@@ -1602,7 +1597,7 @@ void GodotPhysicsServer3D::step(real_t p_step) {
active_objects = 0;
collision_pairs = 0;
for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- stepper->step((GodotSpace3D *)E->get(), p_step, iterations);
+ stepper->step((GodotSpace3D *)E->get(), p_step);
island_count += E->get()->get_island_count();
active_objects += E->get()->get_active_objects();
collision_pairs += E->get()->get_collision_pairs();
@@ -1612,7 +1607,7 @@ void GodotPhysicsServer3D::step(real_t p_step) {
void GodotPhysicsServer3D::sync() {
doing_sync = true;
-};
+}
void GodotPhysicsServer3D::flush_queries() {
#ifndef _3D_DISABLED
@@ -1665,15 +1660,15 @@ void GodotPhysicsServer3D::flush_queries() {
EngineDebugger::profiler_add_frame_data("servers", values);
}
#endif
-};
+}
void GodotPhysicsServer3D::end_sync() {
doing_sync = false;
-};
+}
void GodotPhysicsServer3D::finish() {
memdelete(stepper);
-};
+}
int GodotPhysicsServer3D::get_process_info(ProcessInfo p_info) {
switch (p_info) {
diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h
index f5c8e0f60d..be9bbea76b 100644
--- a/servers/physics_3d/godot_physics_server_3d.h
+++ b/servers/physics_3d/godot_physics_server_3d.h
@@ -44,7 +44,6 @@ class GodotPhysicsServer3D : public PhysicsServer3D {
friend class GodotPhysicsDirectSpaceState3D;
bool active = true;
- int iterations = 0;
int island_count = 0;
int active_objects = 0;
@@ -364,8 +363,6 @@ public:
virtual void end_sync() override;
virtual void finish() override;
- virtual void set_collision_iterations(int p_iterations) override;
-
virtual bool is_flushing_queries() const override { return flushing_queries; }
int get_process_info(ProcessInfo p_info) override;
diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp
index f503273c88..b2a8b00bca 100644
--- a/servers/physics_3d/godot_space_3d.cpp
+++ b/servers/physics_3d/godot_space_3d.cpp
@@ -1173,9 +1173,12 @@ void GodotSpace3D::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_v
case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
contact_max_separation = p_value;
break;
- case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
contact_max_allowed_penetration = p_value;
break;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ contact_bias = p_value;
+ break;
case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
body_linear_velocity_sleep_threshold = p_value;
break;
@@ -1191,6 +1194,9 @@ void GodotSpace3D::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_v
case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
constraint_bias = p_value;
break;
+ case PhysicsServer3D::SPACE_PARAM_SOLVER_ITERATIONS:
+ solver_iterations = p_value;
+ break;
}
}
@@ -1200,8 +1206,10 @@ real_t GodotSpace3D::get_param(PhysicsServer3D::SpaceParameter p_param) const {
return contact_recycle_radius;
case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
return contact_max_separation;
- case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
return contact_max_allowed_penetration;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ return contact_bias;
case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
return body_linear_velocity_sleep_threshold;
case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
@@ -1212,6 +1220,8 @@ real_t GodotSpace3D::get_param(PhysicsServer3D::SpaceParameter p_param) const {
return body_angular_velocity_damp_ratio;
case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
return constraint_bias;
+ case PhysicsServer3D::SPACE_PARAM_SOLVER_ITERATIONS:
+ return solver_iterations;
}
return 0;
}
diff --git a/servers/physics_3d/godot_space_3d.h b/servers/physics_3d/godot_space_3d.h
index aa5e965751..b9aeee7583 100644
--- a/servers/physics_3d/godot_space_3d.h
+++ b/servers/physics_3d/godot_space_3d.h
@@ -93,9 +93,12 @@ private:
GodotArea3D *area = nullptr;
+ int solver_iterations = 16;
+
real_t contact_recycle_radius = 0.01;
real_t contact_max_separation = 0.05;
real_t contact_max_allowed_penetration = 0.01;
+ real_t contact_bias = 0.8;
real_t constraint_bias = 0.01;
enum {
@@ -159,9 +162,11 @@ public:
void remove_object(GodotCollisionObject3D *p_object);
const Set<GodotCollisionObject3D *> &get_objects() const;
+ _FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; }
_FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; }
_FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; }
_FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; }
+ _FORCE_INLINE_ real_t get_contact_bias() const { return contact_bias; }
_FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; }
_FORCE_INLINE_ real_t get_body_linear_velocity_sleep_threshold() const { return body_linear_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_angular_velocity_sleep_threshold() const { return body_angular_velocity_sleep_threshold; }
diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp
index 5453c4415c..6332532f6e 100644
--- a/servers/physics_3d/godot_step_3d.cpp
+++ b/servers/physics_3d/godot_step_3d.cpp
@@ -181,14 +181,14 @@ void GodotStep3D::_check_suspend(const LocalVector<GodotBody3D *> &p_body_island
}
}
-void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta, int p_iterations) {
+void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta) {
p_space->lock(); // can't access space during this
p_space->setup(); //update inertias, etc
p_space->set_last_step(p_delta);
- iterations = p_iterations;
+ iterations = p_space->get_solver_iterations();
delta = p_delta;
const SelfList<GodotBody3D>::List *body_list = &p_space->get_active_body_list();
diff --git a/servers/physics_3d/godot_step_3d.h b/servers/physics_3d/godot_step_3d.h
index 23ede4feff..10389713f6 100644
--- a/servers/physics_3d/godot_step_3d.h
+++ b/servers/physics_3d/godot_step_3d.h
@@ -56,7 +56,7 @@ class GodotStep3D {
void _check_suspend(const LocalVector<GodotBody3D *> &p_body_island) const;
public:
- void step(GodotSpace3D *p_space, real_t p_delta, int p_iterations);
+ void step(GodotSpace3D *p_space, real_t p_delta);
GodotStep3D();
~GodotStep3D();
};
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index 76f0b74c72..c660bd4d69 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -730,17 +730,17 @@ void PhysicsServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer2D::set_active);
- ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &PhysicsServer2D::set_collision_iterations);
-
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer2D::get_process_info);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_SEPARATION);
- BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_DEFAULT_BIAS);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_SOLVER_ITERATIONS);
BIND_ENUM_CONSTANT(SHAPE_WORLD_BOUNDARY);
BIND_ENUM_CONSTANT(SHAPE_SEPARATION_RAY);
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index 2bff8f5dcb..6625be6d14 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -242,11 +242,13 @@ public:
enum SpaceParameter {
SPACE_PARAM_CONTACT_RECYCLE_RADIUS,
SPACE_PARAM_CONTACT_MAX_SEPARATION,
- SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_DEFAULT_BIAS,
SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_TIME_TO_SLEEP,
SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS,
+ SPACE_PARAM_SOLVER_ITERATIONS,
};
virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) = 0;
@@ -566,8 +568,6 @@ public:
virtual bool is_flushing_queries() const = 0;
- virtual void set_collision_iterations(int p_iterations) = 0;
-
enum ProcessInfo {
INFO_ACTIVE_OBJECTS,
INFO_COLLISION_PAIRS,
@@ -758,10 +758,9 @@ class PhysicsServer2DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo &operator=(const ClassInfo &p_ci) {
+ void operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
- return *this;
}
};
diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h
index dda4eb6ffa..f65c8921ce 100644
--- a/servers/physics_server_2d_wrap_mt.h
+++ b/servers/physics_server_2d_wrap_mt.h
@@ -294,7 +294,6 @@ public:
FUNC1(free, RID);
FUNC1(set_active, bool);
- FUNC1(set_collision_iterations, int);
virtual void init() override;
virtual void step(real_t p_step) override;
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index 373f216e01..658f7daf9f 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -890,8 +890,6 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer3D::set_active);
- ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &PhysicsServer3D::set_collision_iterations);
-
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer3D::get_process_info);
BIND_ENUM_CONSTANT(SHAPE_WORLD_BOUNDARY);
@@ -963,12 +961,14 @@ void PhysicsServer3D::_bind_methods() {
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_SEPARATION);
- BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_DEFAULT_BIAS);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_SOLVER_ITERATIONS);
BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_X);
BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_Y);
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index 89a7eeee96..dfaefc5fbf 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -263,12 +263,14 @@ public:
enum SpaceParameter {
SPACE_PARAM_CONTACT_RECYCLE_RADIUS,
SPACE_PARAM_CONTACT_MAX_SEPARATION,
- SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_DEFAULT_BIAS,
SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_TIME_TO_SLEEP,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO,
SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS,
+ SPACE_PARAM_SOLVER_ITERATIONS,
};
virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) = 0;
@@ -768,8 +770,6 @@ public:
virtual bool is_flushing_queries() const = 0;
- virtual void set_collision_iterations(int p_iterations) = 0;
-
enum ProcessInfo {
INFO_ACTIVE_OBJECTS,
INFO_COLLISION_PAIRS,
@@ -965,10 +965,9 @@ class PhysicsServer3DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo &operator=(const ClassInfo &p_ci) {
+ void operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
- return *this;
}
};
diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h
index 507427ecec..e6dc2d8ed9 100644
--- a/servers/physics_server_3d_wrap_mt.h
+++ b/servers/physics_server_3d_wrap_mt.h
@@ -370,7 +370,6 @@ public:
FUNC1(free, RID);
FUNC1(set_active, bool);
- FUNC1(set_collision_iterations, int);
virtual void init() override;
virtual void step(real_t p_step) override;
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
index b31d1062f5..d1085245c0 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
@@ -1305,7 +1305,6 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
RD::get_singleton()->draw_list_draw(p_draw_list, false, total_probes, total_points);
if (gi->sdfgi_debug_probe_dir != Vector3()) {
- print_line("CLICK DEBUG ME?");
uint32_t cascade = 0;
Vector3 offset = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[cascade].position)) * cascades[cascade].cell_size * Vector3(1.0, 1.0 / y_mult, 1.0);
Vector3 probe_size = cascades[cascade].cell_size * (cascade_size / SDFGI::PROBE_DIVISOR) * Vector3(1.0, 1.0 / y_mult, 1.0);
@@ -1333,11 +1332,6 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
}
}
- if (gi->sdfgi_debug_probe_enabled) {
- print_line("found: " + gi->sdfgi_debug_probe_index);
- } else {
- print_line("no found");
- }
gi->sdfgi_debug_probe_dir = Vector3();
}
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 45f321fc90..f8d0aad4fa 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -9265,7 +9265,6 @@ void RendererStorageRD::_update_global_variables() {
ERR_CONTINUE(!material); //wtf
_material_queue_update(material, false, true);
- print_line("update material texture?");
}
global_variables.must_update_texture_materials = false;
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
index 77d3a2e766..b02b3d2723 100644
--- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
@@ -1318,6 +1318,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += ")";
} break;
+ case SL::OP_EMPTY: {
+ // Semicolon (or empty statement) - ignored.
+ } break;
default: {
if (p_use_scope) {
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index dcbc5f5c8e..5602bb197b 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -185,9 +185,13 @@ Ref<RDShaderSPIRV> RenderingDevice::_shader_compile_spirv_from_source(const Ref<
String error;
ShaderStage stage = ShaderStage(i);
- Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache);
- bytecode->set_stage_bytecode(stage, spirv);
- bytecode->set_stage_compile_error(stage, error);
+ String source = p_source->get_stage_source(stage);
+
+ if (!source.is_empty()) {
+ Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, source, p_source->get_language(), &error, p_allow_cache);
+ bytecode->set_stage_bytecode(stage, spirv);
+ bytecode->set_stage_compile_error(stage, error);
+ }
}
return bytecode;
}
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 50719ecfc3..f5e91d0423 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -88,7 +88,8 @@ String ShaderLanguage::get_operator_text(Operator p_op) {
"--",
"()",
"construct",
- "index" };
+ "index",
+ "empty" };
return op_names[p_op];
}
@@ -474,6 +475,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
case ':':
return _make_token(TK_COLON);
case '^':
+ if (GETCHAR(0) == '=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_BIT_XOR);
+ }
return _make_token(TK_OP_BIT_XOR);
case '~':
return _make_token(TK_OP_BIT_INVERT);
@@ -4293,7 +4298,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_size(BlockNode *p_block, cons
return n;
}
-Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
+Error ShaderLanguage::_parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info) {
if (r_array_size > 0) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
@@ -4305,7 +4310,7 @@ Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) {
_set_tkpos(pos);
- Node *n = _parse_array_size(nullptr, FunctionInfo(), array_size);
+ Node *n = _parse_array_size(nullptr, p_function_info, array_size);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5208,9 +5213,21 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expression.push_back(e);
continue;
} else {
- _set_error("Expected expression, found: " + get_token_text(tk));
- return nullptr;
- //nothing
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected expression, found: " + get_token_text(tk));
+ return nullptr;
+ } else {
+#if DEBUG_ENABLED
+ if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
+ _add_line_warning(ShaderWarning::FORMATTING_ERROR, "Empty statement. Remove ';' to fix this warning.");
+ }
+#endif // DEBUG_ENABLED
+ _set_tkpos(prepos);
+
+ OperatorNode *func = alloc_node<OperatorNode>();
+ func->op = OP_EMPTY;
+ expr = func;
+ }
}
ERR_FAIL_COND_V(!expr, nullptr);
@@ -6386,7 +6403,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ArrayDeclarationNode::Declaration adecl;
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
- _set_error("Expected identifier or '[' after type.");
+ _set_error("Expected identifier or '[' after datatype.");
return ERR_PARSE_ERROR;
}
@@ -7446,6 +7463,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
stages = &p_functions;
+ const FunctionInfo &constants = p_functions.has("constants") ? p_functions["constants"] : FunctionInfo();
while (tk.type != TK_EOF) {
switch (tk.type) {
@@ -7489,7 +7507,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_IDENTIFIER) {
st.name = tk.text;
- if (shader->structs.has(st.name)) {
+ if (shader->constants.has(st.name) || shader->structs.has(st.name)) {
_set_error("Redefinition of '" + String(st.name) + "'");
return ERR_PARSE_ERROR;
}
@@ -7561,7 +7579,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
int array_size = 0;
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size);
+ Error error = _parse_global_array_size(array_size, constants);
if (error != OK) {
return error;
}
@@ -7588,7 +7606,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(member->array_size);
+ Error error = _parse_global_array_size(member->array_size, constants);
if (error != OK) {
return error;
}
@@ -7715,7 +7733,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size);
+ Error error = _parse_global_array_size(array_size, constants);
if (error != OK) {
return error;
}
@@ -7730,7 +7748,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
prev_pos = _get_tkpos();
name = tk.text;
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
+ if (_find_identifier(nullptr, false, constants, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -7763,7 +7781,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(uniform2.array_size);
+ Error error = _parse_global_array_size(uniform2.array_size, constants);
if (error != OK) {
return error;
}
@@ -8017,7 +8035,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *expr = _parse_and_reduce_expression(nullptr, constants);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -8113,7 +8131,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
DataPrecision precision = PRECISION_DEFAULT;
DataType type;
StringName name;
- int return_array_size = 0;
+ int array_size = 0;
if (tk.type == TK_CONST) {
is_constant = true;
@@ -8152,13 +8170,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
prev_pos = _get_tkpos();
tk = _get_token();
+ bool unknown_size = false;
+
if (tk.type == TK_BRACKET_OPEN) {
+ if (is_constant && RenderingServer::get_singleton()->is_low_end()) {
+ _set_error("Global const arrays are only supported on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
bool error = false;
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- return_array_size = (int)tk.constant;
- if (return_array_size > 0) {
+ array_size = (int)tk.constant;
+ if (array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8167,11 +8191,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
error = true;
}
+ } else if (tk.type == TK_BRACKET_CLOSE) {
+ unknown_size = true;
} else {
error = true;
}
if (error) {
- _set_error("Expected integer constant > 0");
+ _set_error("Expected integer constant > 0 or ']'");
return ERR_PARSE_ERROR;
}
@@ -8183,16 +8209,15 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name);
if (name == StringName()) {
- _set_error("Expected function name after datatype");
- return ERR_PARSE_ERROR;
- }
-
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ if (is_constant) {
+ _set_error("Expected identifier or '[' after datatype.");
+ } else {
+ _set_error("Expected function name after datatype.");
+ }
return ERR_PARSE_ERROR;
}
- if (has_builtin(p_functions, name)) {
+ if (shader->structs.has(name) || _find_identifier(nullptr, false, constants, name) || has_builtin(p_functions, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -8205,7 +8230,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
//variable
-
+ bool first = true;
while (true) {
ShaderNode::Constant constant;
constant.name = name;
@@ -8213,16 +8238,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.type_str = struct_name;
constant.precision = precision;
constant.initializer = nullptr;
- constant.array_size = 0;
-
- bool unknown_size = false;
+ constant.array_size = (first ? array_size : 0);
+ first = false;
if (tk.type == TK_BRACKET_OPEN) {
if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error("Global const arrays are supported only on high-end platform!");
+ _set_error("Global const arrays are only supported on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
+ if (constant.array_size > 0 || unknown_size) {
+ _set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
-
tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) {
unknown_size = true;
@@ -8300,7 +8327,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
_set_tkpos(prev_pos);
- Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, constants);
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -8381,7 +8408,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, constants);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -8436,7 +8463,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
} else {
//variable created with assignment! must parse an expression
- Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *expr = _parse_and_reduce_expression(nullptr, constants);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -8452,7 +8479,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
- if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), 0)) {
+ if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), expr->get_array_size())) {
return ERR_PARSE_ERROR;
}
}
@@ -8483,7 +8510,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
name = tk.text;
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
+ if (_find_identifier(nullptr, false, constants, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -8517,6 +8544,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
}
+ if (p_functions.has("constants")) { // Adds global constants: 'PI', 'TAU', 'E'
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["constants"].built_ins) {
+ builtins.built_ins.insert(E.key, E.value);
+ }
+ }
+
ShaderNode::Function function;
function.callable = !p_functions.has(name);
@@ -8532,7 +8565,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
func_node->return_type = type;
func_node->return_struct_name = struct_name;
func_node->return_precision = precision;
- func_node->return_array_size = return_array_size;
+ func_node->return_array_size = array_size;
if (p_functions.has(name)) {
func_node->can_discard = p_functions[name].can_discard;
@@ -8586,7 +8619,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
StringName param_struct_name;
DataPrecision pprecision = PRECISION_DEFAULT;
bool use_precision = false;
- int array_size = 0;
+ int arg_array_size = 0;
if (is_token_precision(tk.type)) {
pprecision = get_token_precision(tk.type);
@@ -8637,9 +8670,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- array_size = (int)tk.constant;
+ arg_array_size = (int)tk.constant;
- if (array_size > 0) {
+ if (arg_array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8691,7 +8724,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- if (array_size > 0) {
+ if (arg_array_size > 0) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
@@ -8699,9 +8732,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- array_size = (int)tk.constant;
+ arg_array_size = (int)tk.constant;
- if (array_size > 0) {
+ if (arg_array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8721,7 +8754,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- arg.array_size = array_size;
+ arg.array_size = arg_array_size;
func_node->arguments.push_back(arg);
if (tk.type == TK_COMMA) {
@@ -9067,6 +9100,16 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
}
+ if (p_functions.has("constants")) {
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["constants"].built_ins) {
+ ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
+ if (E.value.constant) {
+ kind = ScriptCodeCompletionOption::KIND_CONSTANT;
+ }
+ matches.insert(E.key, kind);
+ }
+ }
+
if (skip_function != StringName() && p_functions.has(skip_function)) {
for (const KeyValue<StringName, BuiltInInfo> &E : p_functions[skip_function].built_ins) {
ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index c82f71d10d..3de89a89a5 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -287,6 +287,7 @@ public:
OP_CONSTRUCT,
OP_STRUCT,
OP_INDEX,
+ OP_EMPTY,
OP_MAX
};
@@ -989,7 +990,7 @@ private:
bool _check_node_constness(const Node *p_node) const;
Node *_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size);
- Error _parse_global_array_size(int &r_array_size);
+ Error _parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info);
Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, ArrayDeclarationNode *p_node, ArrayDeclarationNode::Declaration *p_decl, int &r_array_size, bool &r_is_unknown_size);
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index eb5c9e66e8..359196e096 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -59,9 +59,9 @@ ShaderTypes::ShaderTypes() {
/*************** SPATIAL ***********************/
shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
@@ -241,9 +241,9 @@ ShaderTypes::ShaderTypes() {
/************ CANVAS ITEM **************************/
shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
@@ -334,9 +334,9 @@ ShaderTypes::ShaderTypes() {
/************ PARTICLES **************************/
shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3;
@@ -367,7 +367,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["NUMBER"] = constt(ShaderLanguage::TYPE_UINT);
- shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_INT);
+ shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_UINT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["FLAG_EMIT_POSITION"] = constt(ShaderLanguage::TYPE_UINT);
@@ -400,9 +400,9 @@ ShaderTypes::ShaderTypes() {
/************ SKY **************************/
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["RADIANCE"] = constt(ShaderLanguage::TYPE_SAMPLERCUBE);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["AT_HALF_RES_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
@@ -446,9 +446,9 @@ ShaderTypes::ShaderTypes() {
/************ FOG **************************/
shader_modes[RS::SHADER_FOG].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["WORLD_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["OBJECT_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp
index 0b8476478c..bffae484a8 100644
--- a/servers/rendering/shader_warnings.cpp
+++ b/servers/rendering/shader_warnings.cpp
@@ -61,6 +61,8 @@ String ShaderWarning::get_message() const {
return vformat("The varying '%s' is declared but never used.", subject);
case UNUSED_LOCAL_VARIABLE:
return vformat("The local variable '%s' is declared but never used.", subject);
+ case FORMATTING_ERROR:
+ return subject;
default:
break;
}
@@ -82,6 +84,7 @@ String ShaderWarning::get_name_from_code(Code p_code) {
"UNUSED_UNIFORM",
"UNUSED_VARYING",
"UNUSED_LOCAL_VARIABLE",
+ "FORMATTING_ERROR",
};
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
@@ -110,6 +113,7 @@ static void init_code_to_flags_map() {
code_to_flags_map->insert(ShaderWarning::UNUSED_UNIFORM, ShaderWarning::UNUSED_UNIFORM_FLAG);
code_to_flags_map->insert(ShaderWarning::UNUSED_VARYING, ShaderWarning::UNUSED_VARYING_FLAG);
code_to_flags_map->insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG);
+ code_to_flags_map->insert(ShaderWarning::FORMATTING_ERROR, ShaderWarning::FORMATTING_ERROR_FLAG);
}
ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, bool> &p_map) {
diff --git a/servers/rendering/shader_warnings.h b/servers/rendering/shader_warnings.h
index db872d8fb1..18915fffd8 100644
--- a/servers/rendering/shader_warnings.h
+++ b/servers/rendering/shader_warnings.h
@@ -47,6 +47,7 @@ public:
UNUSED_UNIFORM,
UNUSED_VARYING,
UNUSED_LOCAL_VARIABLE,
+ FORMATTING_ERROR,
WARNING_MAX,
};
@@ -59,6 +60,7 @@ public:
UNUSED_UNIFORM_FLAG = 16U,
UNUSED_VARYING_FLAG = 32U,
UNUSED_LOCAL_VARIABLE_FLAG = 64U,
+ FORMATTING_ERROR_FLAG = 128U,
};
private:
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index b9ebe8c8d4..23d3bf030f 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -199,11 +199,11 @@ RID RenderingServer::_make_test_cube() {
normal_points[j][i % 3] = (i >= 3 ? -1 : 1);
}
- //tri 1
+ // Tri 1
ADD_VTX(0);
ADD_VTX(1);
ADD_VTX(2);
- //tri 2
+ // Tri 2
ADD_VTX(2);
ADD_VTX(3);
ADD_VTX(0);
@@ -317,9 +317,6 @@ RID RenderingServer::get_white_texture() {
return white_texture;
}
-#define SMALL_VEC2 Vector2(0.00001, 0.00001)
-#define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001)
-
Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) {
uint8_t *vw = r_vertex_array.ptrw();
uint8_t *aw = r_attrib_array.ptrw();
@@ -333,7 +330,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
int max_bone = 0;
for (int ai = 0; ai < RS::ARRAY_MAX; ai++) {
- if (!(p_format & (1 << ai))) { // no array
+ if (!(p_format & (1 << ai))) { // No array
continue;
}
@@ -345,7 +342,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector2 *src = array.ptr();
- // setting vertices means regenerating the AABB
+ // Setting vertices means regenerating the AABB.
Rect2 aabb;
{
@@ -355,7 +352,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
memcpy(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(float) * 2);
if (i == 0) {
- aabb = Rect2(src[i], SMALL_VEC2); //must have a bit of size
+ aabb = Rect2(src[i], SMALL_VEC2); // Must have a bit of size.
} else {
aabb.expand_to(src[i]);
}
@@ -370,7 +367,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector3 *src = array.ptr();
- // setting vertices means regenerating the AABB
+ // Setting vertices means regenerating the AABB.
AABB aabb;
{
@@ -505,7 +502,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case ARRAY_CUSTOM_RGBA8_UNORM:
case ARRAY_CUSTOM_RGBA8_SNORM:
case ARRAY_CUSTOM_RG_HALF: {
- //size 4
+ // Size 4
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER);
Vector<uint8_t> array = p_arrays[ai];
@@ -520,7 +517,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case ARRAY_CUSTOM_RGBA_HALF: {
- //size 8
+ // Size 8
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER);
Vector<uint8_t> array = p_arrays[ai];
@@ -537,7 +534,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case ARRAY_CUSTOM_RG_FLOAT:
case ARRAY_CUSTOM_RGB_FLOAT:
case ARRAY_CUSTOM_RGBA_FLOAT: {
- //RF
+ // RF
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER);
Vector<float> array = p_arrays[ai];
@@ -646,7 +643,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
}
if (p_format & RS::ARRAY_FORMAT_BONES) {
- //create AABBs for each detected bone
+ // Create AABBs for each detected bone.
int total_bones = max_bone + 1;
bool first = r_bone_aabb.size() == 0;
@@ -657,7 +654,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
if (first) {
for (int i = 0; i < total_bones; i++) {
- r_bone_aabb.write[i].size = Vector3(-1, -1, -1); //negative means unused
+ r_bone_aabb.write[i].size = Vector3(-1, -1, -1); // Negative means unused.
}
}
@@ -686,7 +683,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
ERR_FAIL_INDEX_V(idx, total_bones, ERR_INVALID_DATA);
if (bptr[idx].size.x < 0) {
- //first
+ // First
bptr[idx] = AABB(v, SMALL_VEC3);
any_valid = true;
} else {
@@ -749,7 +746,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i
uint32_t *size_accum;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
- r_offsets[i] = 0; //reset
+ r_offsets[i] = 0; // Reset
if (i == RS::ARRAY_VERTEX) {
size_accum = &r_vertex_element_size;
@@ -759,7 +756,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i
size_accum = &r_skin_element_size;
}
- if (!(p_format & (1 << i))) { // no array
+ if (!(p_format & (1 << i))) { // No array
continue;
}
@@ -873,7 +870,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
uint32_t format = 0;
- // validation
+ // Validation
int index_array_len = 0;
int array_len = 0;
@@ -921,10 +918,10 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
}
- ERR_FAIL_COND_V((format & RS::ARRAY_FORMAT_VERTEX) == 0, ERR_INVALID_PARAMETER); // mandatory
+ ERR_FAIL_COND_V((format & RS::ARRAY_FORMAT_VERTEX) == 0, ERR_INVALID_PARAMETER); // Mandatory
if (p_blend_shapes.size()) {
- //validate format for morphs
+ // Validate format for morphs.
for (int i = 0; i < p_blend_shapes.size(); i++) {
uint32_t bsformat = 0;
Array arr = p_blend_shapes[i];
@@ -939,7 +936,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
for (uint32_t i = 0; i < RS::ARRAY_CUSTOM_COUNT; ++i) {
- // include custom array format type.
+ // Include custom array format type.
if (format & (1 << (ARRAY_CUSTOM0 + i))) {
format |= (RS::ARRAY_FORMAT_CUSTOM_MASK << (RS::ARRAY_FORMAT_CUSTOM_BASE + i * RS::ARRAY_FORMAT_CUSTOM_BITS)) & p_compress_format;
}
@@ -954,7 +951,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
mesh_surface_make_offsets_from_format(format, array_len, index_array_len, offsets, vertex_element_size, attrib_element_size, skin_element_size);
uint32_t mask = (1 << ARRAY_MAX) - 1;
- format |= (~mask) & p_compress_format; //make the full format
+ format |= (~mask) & p_compress_format; // Make the full format.
int vertex_array_size = vertex_element_size * array_len;
int attrib_array_size = attrib_element_size * array_len;
@@ -1010,13 +1007,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
Vector<int> indices = p_lods[E];
ERR_CONTINUE(indices.size() == 0);
uint32_t index_count = indices.size();
- ERR_CONTINUE(index_count >= (uint32_t)index_array_len); //should be smaller..
+ ERR_CONTINUE(index_count >= (uint32_t)index_array_len); // Should be smaller..
const int *r = indices.ptr();
Vector<uint8_t> data;
if (array_len <= 65536) {
- //16 bits indices
+ // 16 bits indices
data.resize(indices.size() * 2);
uint8_t *w = data.ptrw();
uint16_t *index_ptr = (uint16_t *)w;
@@ -1024,7 +1021,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
index_ptr[i] = r[i];
}
} else {
- //32 bits indices
+ // 32 bits indices
data.resize(indices.size() * 4);
uint8_t *w = data.ptrw();
uint32_t *index_ptr = (uint32_t *)w;
@@ -1204,7 +1201,7 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
case ARRAY_CUSTOM_RGBA8_SNORM:
case ARRAY_CUSTOM_RG_HALF:
case ARRAY_CUSTOM_RGBA_HALF: {
- //size 4
+ // Size 4
int s = type == ARRAY_CUSTOM_RGBA_HALF ? 8 : 4;
Vector<uint8_t> arr;
arr.resize(p_vertex_len * s);
@@ -1472,12 +1469,12 @@ ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_dataty
case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE:
return ShaderLanguage::TYPE_SAMPLERCUBE;
default:
- return ShaderLanguage::TYPE_MAX; //invalid or not found
+ return ShaderLanguage::TYPE_MAX; // Invalid or not found.
}
}
RenderingDevice *RenderingServer::get_rendering_device() const {
- // return the rendering device we're using globally
+ // Return the rendering device we're using globally.
return RenderingDevice::get_singleton();
}
@@ -2221,8 +2218,8 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_SCALING_3D_MODE_MAX);
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_DISABLED);
- BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE); //then goes to disabled); must be manually updated
- BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE); // default
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE); // Then goes to disabled); must be manually updated.
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE); // Default
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ALWAYS);
@@ -2553,7 +2550,8 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_set_modulate", "item", "color"), &RenderingServer::canvas_item_set_modulate);
ClassDB::bind_method(D_METHOD("canvas_item_set_self_modulate", "item", "color"), &RenderingServer::canvas_item_set_self_modulate);
ClassDB::bind_method(D_METHOD("canvas_item_set_draw_behind_parent", "item", "enabled"), &RenderingServer::canvas_item_set_draw_behind_parent);
- //primitives
+
+ /* Primitives */
ClassDB::bind_method(D_METHOD("canvas_item_add_line", "item", "from", "to", "color", "width"), &RenderingServer::canvas_item_add_line, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("canvas_item_add_polyline", "item", "points", "colors", "width", "antialiased"), &RenderingServer::canvas_item_add_polyline, DEFVAL(1.0), DEFVAL(false));
@@ -2704,7 +2702,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAX);
/* Free */
- ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingServer::free); // shouldn't conflict with Object::free()
+ ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingServer::free); // Shouldn't conflict with Object::free().
/* Misc */
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 85f92bc003..230132651f 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -55,6 +55,9 @@ class RenderingServer : public Object {
RendererThreadPool *thread_pool = nullptr;
+ const Vector2 SMALL_VEC2 = Vector2(CMP_EPSILON, CMP_EPSILON);
+ const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON);
+
protected:
RID _make_test_cube();
void _free_internal_rids();
@@ -108,7 +111,7 @@ public:
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to) = 0;
- //these two APIs can be used together or in combination with the others.
+ // These two APIs can be used together or in combination with the others.
virtual RID texture_2d_placeholder_create() = 0;
virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_layered_type) = 0;
virtual RID texture_3d_placeholder_create() = 0;
@@ -210,18 +213,18 @@ public:
enum ArrayType {
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
- ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored
- ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal
+ ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
+ ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
ARRAY_COLOR = 3, // RGBA8
ARRAY_TEX_UV = 4, // RG32F
ARRAY_TEX_UV2 = 5, // RG32F
- ARRAY_CUSTOM0 = 6, // depends on ArrayCustomFormat
+ ARRAY_CUSTOM0 = 6, // Depends on ArrayCustomFormat.
ARRAY_CUSTOM1 = 7,
ARRAY_CUSTOM2 = 8,
ARRAY_CUSTOM3 = 9,
ARRAY_BONES = 10, // RGBA16UI (x2 if 8 weights)
ARRAY_WEIGHTS = 11, // RGBA16UNORM (x2 if 8 weights)
- ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF
+ ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF.
ARRAY_MAX = 13
};
@@ -243,7 +246,7 @@ public:
enum ArrayFormat {
/* ARRAY FORMAT FLAGS */
- ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // mandatory
+ ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // Mandatory
ARRAY_FORMAT_NORMAL = 1 << ARRAY_NORMAL,
ARRAY_FORMAT_TANGENT = 1 << ARRAY_TANGENT,
ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR,
@@ -287,9 +290,9 @@ public:
PrimitiveType primitive = PRIMITIVE_MAX;
uint32_t format = 0;
- Vector<uint8_t> vertex_data; // vertex, normal, tangent (change with skinning, blendshape)
- Vector<uint8_t> attribute_data; // color,uv, uv2, custom0-3
- Vector<uint8_t> skin_data; // bone index, bone weight
+ Vector<uint8_t> vertex_data; // Vertex, Normal, Tangent (change with skinning, blendshape).
+ Vector<uint8_t> attribute_data; // Color, UV, UV2, Custom0-3.
+ Vector<uint8_t> skin_data; // Bone index, Bone weight.
uint32_t vertex_count = 0;
Vector<uint8_t> index_data;
uint32_t index_count = 0;
@@ -452,7 +455,7 @@ public:
virtual void light_set_bake_mode(RID p_light, LightBakeMode p_bake_mode) = 0;
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0;
- // omni light
+ // Omni light
enum LightOmniShadowMode {
LIGHT_OMNI_SHADOW_DUAL_PARABOLOID,
LIGHT_OMNI_SHADOW_CUBE,
@@ -460,7 +463,7 @@ public:
virtual void light_omni_set_shadow_mode(RID p_light, LightOmniShadowMode p_mode) = 0;
- // directional light
+ // Directional light
enum LightDirectionalShadowMode {
LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL,
LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS,
@@ -671,7 +674,7 @@ public:
virtual AABB particles_get_current_aabb(RID p_particles) = 0;
- virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; //this is only used for 2D, in 3D it's automatic
+ virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; // This is only used for 2D, in 3D it's automatic.
/* PARTICLES COLLISION API */
@@ -689,16 +692,16 @@ public:
virtual void particles_collision_set_collision_type(RID p_particles_collision, ParticlesCollisionType p_type) = 0;
virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0;
- virtual void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) = 0; //for spheres
- virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; //for non-spheres
+ virtual void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) = 0; // For spheres.
+ virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; // For non-spheres.
virtual void particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) = 0;
virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) = 0;
virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) = 0;
- virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; //for SDF and vector field, heightfield is dynamic
+ virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; // For SDF and vector field, heightfield is dynamic.
- virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; //for SDF and vector field
+ virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; // For SDF and vector field.
- enum ParticlesCollisionHeightfieldResolution { //longest axis resolution
+ enum ParticlesCollisionHeightfieldResolution { // Longest axis resolution.
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_256,
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_512,
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024,
@@ -708,7 +711,7 @@ public:
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX,
};
- virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field
+ virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; // For SDF and vector field.
/* FOG VOLUME API */
@@ -750,7 +753,7 @@ public:
/* VIEWPORT API */
enum CanvasItemTextureFilter {
- CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, // Uses canvas item setting for draw command, uses global setting for canvas item.
CANVAS_ITEM_TEXTURE_FILTER_NEAREST,
CANVAS_ITEM_TEXTURE_FILTER_LINEAR,
CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS,
@@ -761,7 +764,7 @@ public:
};
enum CanvasItemTextureRepeat {
- CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, // Uses canvas item setting for draw command, uses global setting for canvas item.
CANVAS_ITEM_TEXTURE_REPEAT_DISABLED,
CANVAS_ITEM_TEXTURE_REPEAT_ENABLED,
CANVAS_ITEM_TEXTURE_REPEAT_MIRROR,
@@ -791,8 +794,8 @@ public:
enum ViewportUpdateMode {
VIEWPORT_UPDATE_DISABLED,
- VIEWPORT_UPDATE_ONCE, //then goes to disabled, must be manually updated
- VIEWPORT_UPDATE_WHEN_VISIBLE, // default
+ VIEWPORT_UPDATE_ONCE, // Then goes to disabled, must be manually updated.
+ VIEWPORT_UPDATE_WHEN_VISIBLE, // Default
VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE,
VIEWPORT_UPDATE_ALWAYS
};
@@ -1171,7 +1174,7 @@ public:
virtual void instance_set_ignore_culling(RID p_instance, bool p_enabled) = 0;
- // don't use these in a game!
+ // Don't use these in a game!
virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0;
virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0;
virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0;
@@ -1245,7 +1248,7 @@ public:
virtual void canvas_texture_set_channel(RID p_canvas_texture, CanvasTextureChannel p_channel, RID p_texture) = 0;
virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
- //takes effect only for new draw commands
+ // Takes effect only for new draw commands.
virtual void canvas_texture_set_texture_filter(RID p_canvas_texture, CanvasItemTextureFilter p_filter) = 0;
virtual void canvas_texture_set_texture_repeat(RID p_canvas_texture, CanvasItemTextureRepeat p_repeat) = 0;
@@ -1443,7 +1446,7 @@ public:
/* FREE */
- virtual void free(RID p_rid) = 0; ///< free RIDs associated with the rendering server
+ virtual void free(RID p_rid) = 0; // Free RIDs associated with the rendering server.
/* EVENT QUEUING */
@@ -1529,7 +1532,7 @@ public:
virtual ~RenderingServer();
private:
- //binder helpers
+ // Binder helpers
RID _texture_2d_layered_create(const TypedArray<Image> &p_layers, TextureLayeredType p_layered_type);
RID _texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data);
void _texture_3d_update(RID p_texture, const TypedArray<Image> &p_data);
@@ -1543,7 +1546,7 @@ private:
void _particles_set_trail_bind_poses(RID p_particles, const TypedArray<Transform3D> &p_bind_poses);
};
-// make variant understand the enums
+// Make variant understand the enums.
VARIANT_ENUM_CAST(RenderingServer::TextureLayeredType);
VARIANT_ENUM_CAST(RenderingServer::CubeMapLayer);
VARIANT_ENUM_CAST(RenderingServer::ShaderMode);