feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -29,6 +29,7 @@
/**************************************************************************/
#include "gpu_particles_3d.h"
#include "gpu_particles_3d.compat.inc"
#include "scene/3d/cpu_particles_3d.h"
#include "scene/resources/curve_texture.h"
@ -41,7 +42,9 @@ AABB GPUParticles3D::get_aabb() const {
void GPUParticles3D::set_emitting(bool p_emitting) {
// Do not return even if `p_emitting == emitting` because `emitting` is just an approximation.
if (p_emitting && p_emitting != emitting && !use_fixed_seed) {
set_seed(Math::rand());
}
if (p_emitting && one_shot) {
if (!active && !emitting) {
// Last cycle ended.
@ -96,6 +99,27 @@ void GPUParticles3D::set_one_shot(bool p_one_shot) {
}
}
void GPUParticles3D::set_use_fixed_seed(bool p_use_fixed_seed) {
if (p_use_fixed_seed == use_fixed_seed) {
return;
}
use_fixed_seed = p_use_fixed_seed;
notify_property_list_changed();
}
bool GPUParticles3D::get_use_fixed_seed() const {
return use_fixed_seed;
}
void GPUParticles3D::set_seed(uint32_t p_seed) {
seed = p_seed;
RS::get_singleton()->particles_set_seed(particles, p_seed);
}
uint32_t GPUParticles3D::get_seed() const {
return seed;
}
void GPUParticles3D::set_pre_process_time(double p_time) {
pre_process_time = p_time;
RS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time);
@ -123,10 +147,23 @@ void GPUParticles3D::set_use_local_coordinates(bool p_enable) {
}
void GPUParticles3D::set_process_material(const Ref<Material> &p_material) {
#ifdef TOOLS_ENABLED
if (process_material.is_valid()) {
if (Ref<ParticleProcessMaterial>(process_material).is_valid()) {
process_material->disconnect("emission_shape_changed", callable_mp((Node3D *)this, &GPUParticles3D::update_gizmos));
}
}
#endif
process_material = p_material;
RID material_rid;
if (process_material.is_valid()) {
material_rid = process_material->get_rid();
#ifdef TOOLS_ENABLED
if (Ref<ParticleProcessMaterial>(process_material).is_valid()) {
process_material->connect("emission_shape_changed", callable_mp((Node3D *)this, &GPUParticles3D::update_gizmos));
}
#endif
}
RS::get_singleton()->particles_set_process_material(particles, material_rid);
@ -381,22 +418,25 @@ PackedStringArray GPUParticles3D::get_configuration_warnings() const {
warnings.push_back(RTR("Only one Trail mesh is supported. If you want to use more than a single mesh, a Skin is needed (see documentation)."));
}
if ((dp_count || !skin.is_null()) && (missing_trails || no_materials)) {
if ((dp_count || skin.is_valid()) && (missing_trails || no_materials)) {
warnings.push_back(RTR("Trails enabled, but one or more mesh materials are either missing or not set for trails rendering."));
}
if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
warnings.push_back(RTR("Particle trails are only available when using the Forward+ or Mobile rendering backends."));
warnings.push_back(RTR("Particle trails are only available when using the Forward+ or Mobile renderers."));
}
}
if (sub_emitter != NodePath() && OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
warnings.push_back(RTR("Particle sub-emitters are only available when using the Forward+ or Mobile rendering backends."));
warnings.push_back(RTR("Particle sub-emitters are only available when using the Forward+ or Mobile renderers."));
}
return warnings;
}
void GPUParticles3D::restart() {
void GPUParticles3D::restart(bool p_keep_seed) {
if (!p_keep_seed && !use_fixed_seed) {
set_seed(Math::rand());
}
RenderingServer::get_singleton()->particles_restart(particles);
RenderingServer::get_singleton()->particles_set_emitting(particles, true);
@ -414,6 +454,10 @@ AABB GPUParticles3D::capture_aabb() const {
}
void GPUParticles3D::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "emitting") {
p_property.hint = one_shot ? PROPERTY_HINT_ONESHOT : PROPERTY_HINT_NONE;
}
if (p_property.name.begins_with("draw_pass_")) {
int index = p_property.name.get_slicec('_', 2).to_int() - 1;
if (index >= draw_passes.size()) {
@ -421,6 +465,13 @@ void GPUParticles3D::_validate_property(PropertyInfo &p_property) const {
return;
}
}
if (p_property.name == "seed" && !use_fixed_seed) {
p_property.usage = PROPERTY_USAGE_NONE;
}
}
void GPUParticles3D::request_particles_process(real_t p_requested_process_time) {
RS::get_singleton()->particles_request_process_time(particles, p_requested_process_time);
}
void GPUParticles3D::emit_particle(const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
@ -487,8 +538,21 @@ void GPUParticles3D::_notification(int p_what) {
}
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
// Update velocity in physics process, so that velocity calculations remain correct
// if the physics tick rate is lower than the rendered framerate (especially without physics interpolation).
const Vector3 velocity = (get_global_position() - previous_position) / get_physics_process_delta_time();
if (velocity != previous_velocity) {
RS::get_singleton()->particles_set_emitter_velocity(particles, velocity);
previous_velocity = velocity;
}
previous_position = get_global_position();
} break;
case NOTIFICATION_ENTER_TREE: {
set_process_internal(false);
set_physics_process_internal(false);
if (sub_emitter != NodePath()) {
_attach_sub_emitter();
}
@ -499,12 +563,15 @@ void GPUParticles3D::_notification(int p_what) {
}
previous_position = get_global_transform().origin;
set_process_internal(true);
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
RS::get_singleton()->particles_set_subemitter(particles, RID());
} break;
case NOTIFICATION_SUSPENDED:
case NOTIFICATION_UNSUSPENDED:
case NOTIFICATION_PAUSED:
case NOTIFICATION_UNPAUSED: {
if (is_inside_tree()) {
@ -615,6 +682,10 @@ void GPUParticles3D::convert_from_particles(Node *p_particles) {
proc_mat->set_emission_shape(ParticleProcessMaterial::EmissionShape(cpu_particles->get_emission_shape()));
proc_mat->set_emission_sphere_radius(cpu_particles->get_emission_sphere_radius());
proc_mat->set_emission_box_extents(cpu_particles->get_emission_box_extents());
proc_mat->set_emission_ring_height(cpu_particles->get_emission_ring_height());
proc_mat->set_emission_ring_radius(cpu_particles->get_emission_ring_radius());
proc_mat->set_emission_ring_inner_radius(cpu_particles->get_emission_ring_inner_radius());
proc_mat->set_emission_ring_cone_angle(cpu_particles->get_emission_ring_cone_angle());
if (cpu_particles->get_split_scale()) {
Ref<CurveXYZTexture> scale3D = memnew(CurveXYZTexture);
@ -699,6 +770,12 @@ void GPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_collision_base_size"), &GPUParticles3D::get_collision_base_size);
ClassDB::bind_method(D_METHOD("get_interp_to_end"), &GPUParticles3D::get_interp_to_end);
ClassDB::bind_method(D_METHOD("set_use_fixed_seed", "use_fixed_seed"), &GPUParticles3D::set_use_fixed_seed);
ClassDB::bind_method(D_METHOD("get_use_fixed_seed"), &GPUParticles3D::get_use_fixed_seed);
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &GPUParticles3D::set_seed);
ClassDB::bind_method(D_METHOD("get_seed"), &GPUParticles3D::get_seed);
ClassDB::bind_method(D_METHOD("set_draw_order", "order"), &GPUParticles3D::set_draw_order);
ClassDB::bind_method(D_METHOD("get_draw_order"), &GPUParticles3D::get_draw_order);
@ -712,7 +789,7 @@ void GPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_skin", "skin"), &GPUParticles3D::set_skin);
ClassDB::bind_method(D_METHOD("get_skin"), &GPUParticles3D::get_skin);
ClassDB::bind_method(D_METHOD("restart"), &GPUParticles3D::restart);
ClassDB::bind_method(D_METHOD("restart", "keep_seed"), &GPUParticles3D::restart, DEFVAL(false));
ClassDB::bind_method(D_METHOD("capture_aabb"), &GPUParticles3D::capture_aabb);
ClassDB::bind_method(D_METHOD("set_sub_emitter", "path"), &GPUParticles3D::set_sub_emitter);
@ -734,24 +811,29 @@ void GPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_amount_ratio", "ratio"), &GPUParticles3D::set_amount_ratio);
ClassDB::bind_method(D_METHOD("get_amount_ratio"), &GPUParticles3D::get_amount_ratio);
ClassDB::bind_method(D_METHOD("request_particles_process", "process_time"), &GPUParticles3D::request_particles_process);
ADD_SIGNAL(MethodInfo("finished"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting", PROPERTY_HINT_ONESHOT), "set_emitting", "is_emitting");
ADD_PROPERTY_DEFAULT("emitting", true); // Workaround for doctool in headless mode, as dummy rasterizer always returns false.
ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount");
ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount"); // FIXME: Evaluate support for `exp` in integer properties, or remove this.
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "amount_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001"), "set_amount_ratio", "get_amount_ratio");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "sub_emitter", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GPUParticles3D"), "set_sub_emitter", "get_sub_emitter");
ADD_GROUP("Time", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater,exp,suffix:s"), "set_lifetime", "get_lifetime");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interp_to_end", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_interp_to_end", "get_interp_to_end");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01,exp,suffix:s"), "set_pre_process_time", "get_pre_process_time");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_RANGE, "0.00,10.0,0.01,or_greater,exp,suffix:s"), "set_pre_process_time", "get_pre_process_time");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_fixed_seed"), "set_use_fixed_seed", "get_use_fixed_seed");
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed", PROPERTY_HINT_RANGE, "0," + itos(UINT32_MAX) + ",1"), "set_seed", "get_seed");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1,suffix:FPS"), "set_fixed_fps", "get_fixed_fps");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interpolate"), "set_interpolate", "get_interpolate");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta");
ADD_GROUP("Collision", "collision_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_base_size", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,suffix:m"), "set_collision_base_size", "get_collision_base_size");
ADD_GROUP("Drawing", "");
@ -788,6 +870,8 @@ void GPUParticles3D::_bind_methods() {
BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Z_BILLBOARD);
BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Y_TO_VELOCITY);
BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY);
ADD_PROPERTY_DEFAULT("seed", 0);
}
GPUParticles3D::GPUParticles3D() {
@ -797,6 +881,7 @@ GPUParticles3D::GPUParticles3D() {
one_shot = false; // Needed so that set_emitting doesn't access uninitialized values
set_emitting(true);
set_one_shot(false);
set_seed(Math::rand());
set_amount_ratio(1.0);
set_amount(8);
set_lifetime(1);
@ -814,6 +899,7 @@ GPUParticles3D::GPUParticles3D() {
set_speed_scale(1);
set_collision_base_size(collision_base_size);
set_transform_align(TRANSFORM_ALIGN_DISABLED);
set_use_fixed_seed(false);
}
GPUParticles3D::~GPUParticles3D() {