2014-02-09 22:10:30 -03:00
/*************************************************************************/
2020-03-26 18:49:16 -03:00
/* gpu_particles_3d.cpp */
2014-02-09 22:10:30 -03:00
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-09 22:10:30 -03:00
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-09 22:10:30 -03:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2020-03-26 18:49:16 -03:00
# include "gpu_particles_3d.h"
2019-02-09 20:49:58 +01:00
2022-08-18 11:09:22 +02:00
# include "scene/resources/particle_process_material.h"
2018-09-04 11:30:04 +02:00
2020-03-26 18:49:16 -03:00
AABB GPUParticles3D : : get_aabb ( ) const {
2017-11-16 21:09:00 -05:00
return AABB ( ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_emitting ( bool p_emitting ) {
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_emitting ( particles , p_emitting ) ;
2019-06-20 11:20:27 -07:00
if ( p_emitting & & one_shot ) {
set_process_internal ( true ) ;
} else if ( ! p_emitting ) {
set_process_internal ( false ) ;
}
2017-04-06 23:36:37 -03:00
}
2014-02-09 22:10:30 -03:00
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_amount ( int p_amount ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( p_amount < 1 , " Amount of particles cannot be smaller than 1. " ) ;
2017-04-06 23:36:37 -03:00
amount = p_amount ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_amount ( particles , amount ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2021-02-01 21:16:37 -05:00
void GPUParticles3D : : set_lifetime ( double p_lifetime ) {
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( p_lifetime < = 0 , " Particles lifetime must be greater than 0. " ) ;
2017-04-06 23:36:37 -03:00
lifetime = p_lifetime ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_lifetime ( particles , lifetime ) ;
2014-02-09 22:10:30 -03:00
}
2017-06-25 08:01:15 -03:00
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_one_shot ( bool p_one_shot ) {
2017-06-25 08:01:15 -03:00
one_shot = p_one_shot ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_one_shot ( particles , one_shot ) ;
2019-06-20 11:20:27 -07:00
if ( is_emitting ( ) ) {
set_process_internal ( true ) ;
2020-05-14 16:41:43 +02:00
if ( ! one_shot ) {
2020-03-27 15:21:27 -03:00
RenderingServer : : get_singleton ( ) - > particles_restart ( particles ) ;
2020-05-14 16:41:43 +02:00
}
2019-06-20 11:20:27 -07:00
}
2020-05-14 16:41:43 +02:00
if ( ! one_shot ) {
2019-06-20 11:20:27 -07:00
set_process_internal ( false ) ;
2020-05-14 16:41:43 +02:00
}
2017-06-25 08:01:15 -03:00
}
2021-02-01 21:16:37 -05:00
void GPUParticles3D : : set_pre_process_time ( double p_time ) {
2017-04-06 23:36:37 -03:00
pre_process_time = p_time ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_pre_process_time ( particles , pre_process_time ) ;
2017-04-06 23:36:37 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-12 09:07:47 -05:00
void GPUParticles3D : : set_explosiveness_ratio ( real_t p_ratio ) {
2017-04-06 23:36:37 -03:00
explosiveness_ratio = p_ratio ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_explosiveness_ratio ( particles , explosiveness_ratio ) ;
2017-04-06 23:36:37 -03:00
}
2020-05-14 14:29:06 +02:00
2021-08-12 09:07:47 -05:00
void GPUParticles3D : : set_randomness_ratio ( real_t p_ratio ) {
2017-04-06 23:36:37 -03:00
randomness_ratio = p_ratio ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_randomness_ratio ( particles , randomness_ratio ) ;
2017-04-06 23:36:37 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_visibility_aabb ( const AABB & p_aabb ) {
2017-04-08 22:38:11 -03:00
visibility_aabb = p_aabb ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_custom_aabb ( particles , visibility_aabb ) ;
2021-06-23 16:49:50 +02:00
update_gizmos ( ) ;
2017-04-06 23:36:37 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_use_local_coordinates ( bool p_enable ) {
2017-04-06 23:36:37 -03:00
local_coords = p_enable ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_use_local_coordinates ( particles , local_coords ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_process_material ( const Ref < Material > & p_material ) {
2017-04-06 23:36:37 -03:00
process_material = p_material ;
RID material_rid ;
2020-05-14 16:41:43 +02:00
if ( process_material . is_valid ( ) ) {
2017-04-06 23:36:37 -03:00
material_rid = process_material - > get_rid ( ) ;
2020-05-14 16:41:43 +02:00
}
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_process_material ( particles , material_rid ) ;
2017-04-08 22:38:11 -03:00
2020-10-29 05:01:28 -05:00
update_configuration_warnings ( ) ;
2017-04-08 22:38:11 -03:00
}
2021-02-01 21:16:37 -05:00
void GPUParticles3D : : set_speed_scale ( double p_scale ) {
2017-04-08 22:38:11 -03:00
speed_scale = p_scale ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_speed_scale ( particles , p_scale ) ;
2017-04-06 23:36:37 -03:00
}
2021-08-12 09:07:47 -05:00
void GPUParticles3D : : set_collision_base_size ( real_t p_size ) {
2020-10-07 21:29:49 -03:00
collision_base_size = p_size ;
RS : : get_singleton ( ) - > particles_set_collision_base_size ( particles , p_size ) ;
}
2020-03-26 18:49:16 -03:00
bool GPUParticles3D : : is_emitting ( ) const {
2020-03-27 15:21:27 -03:00
return RS : : get_singleton ( ) - > particles_get_emitting ( particles ) ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
int GPUParticles3D : : get_amount ( ) const {
2017-04-06 23:36:37 -03:00
return amount ;
}
2020-05-14 14:29:06 +02:00
2021-02-01 21:16:37 -05:00
double GPUParticles3D : : get_lifetime ( ) const {
2017-04-06 23:36:37 -03:00
return lifetime ;
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
bool GPUParticles3D : : get_one_shot ( ) const {
2017-06-25 08:01:15 -03:00
return one_shot ;
}
2021-02-01 21:16:37 -05:00
double GPUParticles3D : : get_pre_process_time ( ) const {
2017-04-06 23:36:37 -03:00
return pre_process_time ;
}
2020-05-14 14:29:06 +02:00
2021-08-12 09:07:47 -05:00
real_t GPUParticles3D : : get_explosiveness_ratio ( ) const {
2017-04-06 23:36:37 -03:00
return explosiveness_ratio ;
}
2020-05-14 14:29:06 +02:00
2021-08-12 09:07:47 -05:00
real_t GPUParticles3D : : get_randomness_ratio ( ) const {
2017-04-06 23:36:37 -03:00
return randomness_ratio ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
AABB GPUParticles3D : : get_visibility_aabb ( ) const {
2017-04-08 22:38:11 -03:00
return visibility_aabb ;
2017-04-06 23:36:37 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
bool GPUParticles3D : : get_use_local_coordinates ( ) const {
2017-04-06 23:36:37 -03:00
return local_coords ;
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
Ref < Material > GPUParticles3D : : get_process_material ( ) const {
2017-04-06 23:36:37 -03:00
return process_material ;
2014-02-09 22:10:30 -03:00
}
2021-02-01 21:16:37 -05:00
double GPUParticles3D : : get_speed_scale ( ) const {
2017-04-08 22:38:11 -03:00
return speed_scale ;
}
2021-08-12 09:07:47 -05:00
real_t GPUParticles3D : : get_collision_base_size ( ) const {
2020-10-07 21:29:49 -03:00
return collision_base_size ;
}
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_draw_order ( DrawOrder p_order ) {
2017-04-06 23:36:37 -03:00
draw_order = p_order ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_draw_order ( particles , RS : : ParticlesDrawOrder ( p_order ) ) ;
2017-04-06 23:36:37 -03:00
}
2014-02-09 22:10:30 -03:00
2021-05-20 11:25:06 -03:00
void GPUParticles3D : : set_trail_enabled ( bool p_enabled ) {
2021-04-27 12:43:49 -03:00
trail_enabled = p_enabled ;
RS : : get_singleton ( ) - > particles_set_trails ( particles , trail_enabled , trail_length ) ;
update_configuration_warnings ( ) ;
}
2021-08-12 09:07:47 -05:00
void GPUParticles3D : : set_trail_length ( double p_seconds ) {
2021-04-27 12:43:49 -03:00
ERR_FAIL_COND ( p_seconds < 0.001 ) ;
trail_length = p_seconds ;
RS : : get_singleton ( ) - > particles_set_trails ( particles , trail_enabled , trail_length ) ;
}
bool GPUParticles3D : : is_trail_enabled ( ) const {
return trail_enabled ;
}
2021-08-12 09:07:47 -05:00
double GPUParticles3D : : get_trail_length ( ) const {
2021-04-27 12:43:49 -03:00
return trail_length ;
}
2020-03-26 18:49:16 -03:00
GPUParticles3D : : DrawOrder GPUParticles3D : : get_draw_order ( ) const {
2017-04-06 23:36:37 -03:00
return draw_order ;
2014-02-09 22:10:30 -03:00
}
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_draw_passes ( int p_count ) {
2017-04-06 23:36:37 -03:00
ERR_FAIL_COND ( p_count < 1 ) ;
2021-04-27 12:43:49 -03:00
for ( int i = p_count ; i < draw_passes . size ( ) ; i + + ) {
set_draw_pass_mesh ( i , Ref < Mesh > ( ) ) ;
}
2017-04-06 23:36:37 -03:00
draw_passes . resize ( p_count ) ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_draw_passes ( particles , p_count ) ;
2021-02-10 17:18:45 -03:00
notify_property_list_changed ( ) ;
2017-04-06 23:36:37 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
int GPUParticles3D : : get_draw_passes ( ) const {
2017-04-06 23:36:37 -03:00
return draw_passes . size ( ) ;
2014-02-09 22:10:30 -03:00
}
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_draw_pass_mesh ( int p_pass , const Ref < Mesh > & p_mesh ) {
2017-04-06 23:36:37 -03:00
ERR_FAIL_INDEX ( p_pass , draw_passes . size ( ) ) ;
2021-04-27 12:43:49 -03:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) & & draw_passes . write [ p_pass ] . is_valid ( ) ) {
draw_passes . write [ p_pass ] - > disconnect ( " changed " , callable_mp ( ( Node * ) this , & Node : : update_configuration_warnings ) ) ;
}
2018-07-25 03:11:03 +02:00
draw_passes . write [ p_pass ] = p_mesh ;
2017-04-06 23:36:37 -03:00
2021-04-27 12:43:49 -03:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) & & draw_passes . write [ p_pass ] . is_valid ( ) ) {
2022-07-28 22:56:41 +02:00
draw_passes . write [ p_pass ] - > connect ( " changed " , callable_mp ( ( Node * ) this , & Node : : update_configuration_warnings ) , CONNECT_DEFERRED ) ;
2021-04-27 12:43:49 -03:00
}
2017-04-06 23:36:37 -03:00
RID mesh_rid ;
2020-05-14 16:41:43 +02:00
if ( p_mesh . is_valid ( ) ) {
2017-04-06 23:36:37 -03:00
mesh_rid = p_mesh - > get_rid ( ) ;
2020-05-14 16:41:43 +02:00
}
2017-04-06 23:36:37 -03:00
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_draw_pass_mesh ( particles , p_pass , mesh_rid ) ;
2017-04-08 22:38:11 -03:00
2021-04-27 12:43:49 -03:00
_skinning_changed ( ) ;
2020-10-29 05:01:28 -05:00
update_configuration_warnings ( ) ;
2014-02-09 22:10:30 -03:00
}
2020-03-26 18:49:16 -03:00
Ref < Mesh > GPUParticles3D : : get_draw_pass_mesh ( int p_pass ) const {
2017-04-06 23:36:37 -03:00
ERR_FAIL_INDEX_V ( p_pass , draw_passes . size ( ) , Ref < Mesh > ( ) ) ;
2014-02-09 22:10:30 -03:00
2017-04-06 23:36:37 -03:00
return draw_passes [ p_pass ] ;
2014-02-09 22:10:30 -03:00
}
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_fixed_fps ( int p_count ) {
2017-04-06 23:36:37 -03:00
fixed_fps = p_count ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_fixed_fps ( particles , p_count ) ;
2017-04-06 23:36:37 -03:00
}
2014-02-09 22:10:30 -03:00
2020-03-26 18:49:16 -03:00
int GPUParticles3D : : get_fixed_fps ( ) const {
2017-04-06 23:36:37 -03:00
return fixed_fps ;
2014-02-09 22:10:30 -03:00
}
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : set_fractional_delta ( bool p_enable ) {
2017-04-06 23:36:37 -03:00
fractional_delta = p_enable ;
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > particles_set_fractional_delta ( particles , p_enable ) ;
2017-04-06 23:36:37 -03:00
}
2014-02-09 22:10:30 -03:00
2020-03-26 18:49:16 -03:00
bool GPUParticles3D : : get_fractional_delta ( ) const {
2017-04-06 23:36:37 -03:00
return fractional_delta ;
}
2021-04-27 12:43:49 -03:00
void GPUParticles3D : : set_interpolate ( bool p_enable ) {
interpolate = p_enable ;
RS : : get_singleton ( ) - > particles_set_interpolate ( particles , p_enable ) ;
}
bool GPUParticles3D : : get_interpolate ( ) const {
return interpolate ;
}
2020-10-29 05:01:28 -05:00
TypedArray < String > GPUParticles3D : : get_configuration_warnings ( ) const {
2022-07-03 16:01:10 +02:00
TypedArray < String > warnings = GeometryInstance3D : : get_configuration_warnings ( ) ;
2020-10-29 05:01:28 -05:00
2020-03-27 15:21:27 -03:00
if ( RenderingServer : : get_singleton ( ) - > is_low_end ( ) ) {
2022-03-28 15:24:14 +02:00
warnings . push_back ( RTR ( " GPU-based particles are not supported by the OpenGL video driver. \n Use the CPUParticles3D node instead. You can use the \" Convert to CPUParticles3D \" option for this purpose. " ) ) ;
2019-02-09 20:49:58 +01:00
}
2017-04-08 22:38:11 -03:00
bool meshes_found = false ;
2018-11-13 18:19:16 +01:00
bool anim_material_found = false ;
2017-04-08 22:38:11 -03:00
for ( int i = 0 ; i < draw_passes . size ( ) ; i + + ) {
if ( draw_passes [ i ] . is_valid ( ) ) {
meshes_found = true ;
2018-11-13 18:19:16 +01:00
for ( int j = 0 ; j < draw_passes [ i ] - > get_surface_count ( ) ; j + + ) {
2020-04-02 01:20:12 +02:00
anim_material_found = Object : : cast_to < ShaderMaterial > ( draw_passes [ i ] - > surface_get_material ( j ) . ptr ( ) ) ! = nullptr ;
2021-04-27 12:43:49 -03:00
BaseMaterial3D * spat = Object : : cast_to < BaseMaterial3D > ( draw_passes [ i ] - > surface_get_material ( j ) . ptr ( ) ) ;
2019-09-15 01:01:52 -03:00
anim_material_found = anim_material_found | | ( spat & & spat - > get_billboard_mode ( ) = = StandardMaterial3D : : BILLBOARD_PARTICLES ) ;
2018-11-13 18:19:16 +01:00
}
2020-05-14 16:41:43 +02:00
if ( anim_material_found ) {
2020-05-10 12:56:01 +02:00
break ;
2020-05-14 16:41:43 +02:00
}
2017-04-08 22:38:11 -03:00
}
}
2020-04-02 01:20:12 +02:00
anim_material_found = anim_material_found | | Object : : cast_to < ShaderMaterial > ( get_material_override ( ) . ptr ( ) ) ! = nullptr ;
2021-04-27 12:43:49 -03:00
{
BaseMaterial3D * spat = Object : : cast_to < BaseMaterial3D > ( get_material_override ( ) . ptr ( ) ) ;
anim_material_found = anim_material_found | | ( spat & & spat - > get_billboard_mode ( ) = = BaseMaterial3D : : BILLBOARD_PARTICLES ) ;
}
2018-11-13 18:19:16 +01:00
2017-04-08 22:38:11 -03:00
if ( ! meshes_found ) {
2022-03-28 15:24:14 +02:00
warnings . push_back ( RTR ( " Nothing is visible because meshes have not been assigned to draw passes. " ) ) ;
2017-04-08 22:38:11 -03:00
}
if ( process_material . is_null ( ) ) {
2022-03-28 15:24:14 +02:00
warnings . push_back ( RTR ( " A material to process the particles is not assigned, so no behavior is imprinted. " ) ) ;
2018-11-13 18:19:16 +01:00
} else {
2022-08-18 11:09:22 +02:00
const ParticleProcessMaterial * process = Object : : cast_to < ParticleProcessMaterial > ( process_material . ptr ( ) ) ;
2018-11-13 18:19:16 +01:00
if ( ! anim_material_found & & process & &
2022-08-18 11:09:22 +02:00
( process - > get_param_max ( ParticleProcessMaterial : : PARAM_ANIM_SPEED ) ! = 0.0 | | process - > get_param_max ( ParticleProcessMaterial : : PARAM_ANIM_OFFSET ) ! = 0.0 | |
process - > get_param_texture ( ParticleProcessMaterial : : PARAM_ANIM_SPEED ) . is_valid ( ) | | process - > get_param_texture ( ParticleProcessMaterial : : PARAM_ANIM_OFFSET ) . is_valid ( ) ) ) {
2022-03-28 15:24:14 +02:00
warnings . push_back ( RTR ( " Particles animation requires the usage of a BaseMaterial3D whose Billboard Mode is set to \" Particle Billboard \" . " ) ) ;
2021-04-27 12:43:49 -03:00
}
}
if ( trail_enabled ) {
int dp_count = 0 ;
bool missing_trails = false ;
bool no_materials = false ;
for ( int i = 0 ; i < draw_passes . size ( ) ; i + + ) {
Ref < Mesh > draw_pass = draw_passes [ i ] ;
if ( draw_pass . is_valid ( ) & & draw_pass - > get_builtin_bind_pose_count ( ) > 0 ) {
dp_count + + ;
}
if ( draw_pass . is_valid ( ) ) {
int mats_found = 0 ;
for ( int j = 0 ; j < draw_passes [ i ] - > get_surface_count ( ) ; j + + ) {
BaseMaterial3D * spat = Object : : cast_to < BaseMaterial3D > ( draw_passes [ i ] - > surface_get_material ( j ) . ptr ( ) ) ;
if ( spat ) {
mats_found + + ;
}
if ( spat & & ! spat - > get_flag ( BaseMaterial3D : : FLAG_PARTICLE_TRAILS_MODE ) ) {
missing_trails = true ;
}
}
if ( mats_found ! = draw_passes [ i ] - > get_surface_count ( ) ) {
no_materials = true ;
}
}
}
BaseMaterial3D * spat = Object : : cast_to < BaseMaterial3D > ( get_material_override ( ) . ptr ( ) ) ;
if ( spat ) {
no_materials = false ;
}
if ( spat & & ! spat - > get_flag ( BaseMaterial3D : : FLAG_PARTICLE_TRAILS_MODE ) ) {
missing_trails = true ;
}
if ( dp_count & & skin . is_valid ( ) ) {
2022-03-28 15:24:14 +02:00
warnings . push_back ( RTR ( " Using Trail meshes with a skin causes Skin to override Trail poses. Suggest removing the Skin. " ) ) ;
2021-04-27 12:43:49 -03:00
} else if ( dp_count = = 0 & & skin . is_null ( ) ) {
2022-03-28 15:24:14 +02:00
warnings . push_back ( RTR ( " Trails active, but neither Trail meshes or a Skin were found. " ) ) ;
2021-04-27 12:43:49 -03:00
} else if ( dp_count > 1 ) {
2022-03-28 15:24:14 +02:00
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). " ) ) ;
2021-04-27 12:43:49 -03:00
}
if ( ( dp_count | | ! skin . is_null ( ) ) & & ( missing_trails | | no_materials ) ) {
2022-03-28 15:24:14 +02:00
warnings . push_back ( RTR ( " Trails enabled, but one or more mesh materials are either missing or not set for trails rendering. " ) ) ;
2018-11-13 18:19:16 +01:00
}
2017-04-08 22:38:11 -03:00
}
return warnings ;
}
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : restart ( ) {
2020-03-27 15:21:27 -03:00
RenderingServer : : get_singleton ( ) - > particles_restart ( particles ) ;
RenderingServer : : get_singleton ( ) - > particles_set_emitting ( particles , true ) ;
2017-06-25 08:01:15 -03:00
}
2020-03-26 18:49:16 -03:00
AABB GPUParticles3D : : capture_aabb ( ) const {
2020-03-27 15:21:27 -03:00
return RS : : get_singleton ( ) - > particles_get_current_aabb ( particles ) ;
2017-04-08 22:38:11 -03:00
}
2022-08-12 23:57:11 +03:00
void GPUParticles3D : : _validate_property ( PropertyInfo & p_property ) const {
if ( p_property . name . begins_with ( " draw_pass_ " ) ) {
int index = p_property . name . get_slicec ( ' _ ' , 2 ) . to_int ( ) - 1 ;
2017-04-06 23:36:37 -03:00
if ( index > = draw_passes . size ( ) ) {
2022-08-12 23:57:11 +03:00
p_property . usage = PROPERTY_USAGE_NONE ;
2017-04-06 23:36:37 -03:00
return ;
}
}
2014-02-09 22:10:30 -03:00
}
2020-10-17 01:08:21 -04:00
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 ) {
2020-09-06 09:18:10 -03:00
RS : : get_singleton ( ) - > particles_emit ( particles , p_transform , p_velocity , p_color , p_custom , p_emit_flags ) ;
}
void GPUParticles3D : : _attach_sub_emitter ( ) {
Node * n = get_node_or_null ( sub_emitter ) ;
if ( n ) {
GPUParticles3D * sen = Object : : cast_to < GPUParticles3D > ( n ) ;
if ( sen & & sen ! = this ) {
RS : : get_singleton ( ) - > particles_set_subemitter ( particles , sen - > particles ) ;
}
}
}
void GPUParticles3D : : set_sub_emitter ( const NodePath & p_path ) {
if ( is_inside_tree ( ) ) {
RS : : get_singleton ( ) - > particles_set_subemitter ( particles , RID ( ) ) ;
}
sub_emitter = p_path ;
if ( is_inside_tree ( ) & & sub_emitter ! = NodePath ( ) ) {
_attach_sub_emitter ( ) ;
}
}
NodePath GPUParticles3D : : get_sub_emitter ( ) const {
return sub_emitter ;
}
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : _notification ( int p_what ) {
2022-02-15 18:06:48 +01:00
switch ( p_what ) {
case NOTIFICATION_PAUSED :
case NOTIFICATION_UNPAUSED : {
if ( can_process ( ) ) {
RS : : get_singleton ( ) - > particles_set_speed_scale ( particles , speed_scale ) ;
} else {
RS : : get_singleton ( ) - > particles_set_speed_scale ( particles , 0 ) ;
}
} break ;
// Use internal process when emitting and one_shot is on so that when
// the shot ends the editor can properly update.
case NOTIFICATION_INTERNAL_PROCESS : {
if ( one_shot & & ! is_emitting ( ) ) {
notify_property_list_changed ( ) ;
set_process_internal ( false ) ;
}
} break ;
2019-11-09 09:51:17 +01:00
2022-02-15 18:06:48 +01:00
case NOTIFICATION_ENTER_TREE : {
if ( sub_emitter ! = NodePath ( ) ) {
_attach_sub_emitter ( ) ;
}
} break ;
2020-09-06 09:18:10 -03:00
2022-02-15 18:06:48 +01:00
case NOTIFICATION_EXIT_TREE : {
RS : : get_singleton ( ) - > particles_set_subemitter ( particles , RID ( ) ) ;
} break ;
2020-09-06 09:18:10 -03:00
2022-02-15 18:06:48 +01:00
case NOTIFICATION_VISIBILITY_CHANGED : {
// Make sure particles are updated before rendering occurs if they were active before.
if ( is_visible_in_tree ( ) & & ! RS : : get_singleton ( ) - > particles_is_inactive ( particles ) ) {
RS : : get_singleton ( ) - > particles_request_process ( particles ) ;
}
} break ;
2019-11-09 09:51:17 +01:00
}
2017-08-07 19:01:30 -03:00
}
2021-04-27 12:43:49 -03:00
void GPUParticles3D : : _skinning_changed ( ) {
2020-10-17 01:08:21 -04:00
Vector < Transform3D > xforms ;
2021-04-27 12:43:49 -03:00
if ( skin . is_valid ( ) ) {
xforms . resize ( skin - > get_bind_count ( ) ) ;
for ( int i = 0 ; i < skin - > get_bind_count ( ) ; i + + ) {
xforms . write [ i ] = skin - > get_bind_pose ( i ) ;
}
} else {
for ( int i = 0 ; i < draw_passes . size ( ) ; i + + ) {
Ref < Mesh > draw_pass = draw_passes [ i ] ;
if ( draw_pass . is_valid ( ) & & draw_pass - > get_builtin_bind_pose_count ( ) > 0 ) {
xforms . resize ( draw_pass - > get_builtin_bind_pose_count ( ) ) ;
for ( int j = 0 ; j < draw_pass - > get_builtin_bind_pose_count ( ) ; j + + ) {
2021-09-25 23:06:32 +09:00
xforms . write [ j ] = draw_pass - > get_builtin_bind_pose ( j ) ;
2021-04-27 12:43:49 -03:00
}
break ;
}
}
}
RS : : get_singleton ( ) - > particles_set_trail_bind_poses ( particles , xforms ) ;
update_configuration_warnings ( ) ;
}
void GPUParticles3D : : set_skin ( const Ref < Skin > & p_skin ) {
skin = p_skin ;
_skinning_changed ( ) ;
}
2021-08-12 18:05:59 -05:00
2021-04-27 12:43:49 -03:00
Ref < Skin > GPUParticles3D : : get_skin ( ) const {
return skin ;
}
void GPUParticles3D : : set_transform_align ( TransformAlign p_align ) {
ERR_FAIL_INDEX ( uint32_t ( p_align ) , 4 ) ;
transform_align = p_align ;
RS : : get_singleton ( ) - > particles_set_transform_align ( particles , RS : : ParticlesTransformAlign ( transform_align ) ) ;
}
GPUParticles3D : : TransformAlign GPUParticles3D : : get_transform_align ( ) const {
return transform_align ;
}
2020-03-26 18:49:16 -03:00
void GPUParticles3D : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_emitting " , " emitting " ) , & GPUParticles3D : : set_emitting ) ;
ClassDB : : bind_method ( D_METHOD ( " set_amount " , " amount " ) , & GPUParticles3D : : set_amount ) ;
ClassDB : : bind_method ( D_METHOD ( " set_lifetime " , " secs " ) , & GPUParticles3D : : set_lifetime ) ;
ClassDB : : bind_method ( D_METHOD ( " set_one_shot " , " enable " ) , & GPUParticles3D : : set_one_shot ) ;
ClassDB : : bind_method ( D_METHOD ( " set_pre_process_time " , " secs " ) , & GPUParticles3D : : set_pre_process_time ) ;
ClassDB : : bind_method ( D_METHOD ( " set_explosiveness_ratio " , " ratio " ) , & GPUParticles3D : : set_explosiveness_ratio ) ;
ClassDB : : bind_method ( D_METHOD ( " set_randomness_ratio " , " ratio " ) , & GPUParticles3D : : set_randomness_ratio ) ;
ClassDB : : bind_method ( D_METHOD ( " set_visibility_aabb " , " aabb " ) , & GPUParticles3D : : set_visibility_aabb ) ;
ClassDB : : bind_method ( D_METHOD ( " set_use_local_coordinates " , " enable " ) , & GPUParticles3D : : set_use_local_coordinates ) ;
ClassDB : : bind_method ( D_METHOD ( " set_fixed_fps " , " fps " ) , & GPUParticles3D : : set_fixed_fps ) ;
ClassDB : : bind_method ( D_METHOD ( " set_fractional_delta " , " enable " ) , & GPUParticles3D : : set_fractional_delta ) ;
2021-04-27 12:43:49 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_interpolate " , " enable " ) , & GPUParticles3D : : set_interpolate ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_process_material " , " material " ) , & GPUParticles3D : : set_process_material ) ;
ClassDB : : bind_method ( D_METHOD ( " set_speed_scale " , " scale " ) , & GPUParticles3D : : set_speed_scale ) ;
2020-10-07 21:29:49 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_collision_base_size " , " size " ) , & GPUParticles3D : : set_collision_base_size ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " is_emitting " ) , & GPUParticles3D : : is_emitting ) ;
ClassDB : : bind_method ( D_METHOD ( " get_amount " ) , & GPUParticles3D : : get_amount ) ;
ClassDB : : bind_method ( D_METHOD ( " get_lifetime " ) , & GPUParticles3D : : get_lifetime ) ;
ClassDB : : bind_method ( D_METHOD ( " get_one_shot " ) , & GPUParticles3D : : get_one_shot ) ;
ClassDB : : bind_method ( D_METHOD ( " get_pre_process_time " ) , & GPUParticles3D : : get_pre_process_time ) ;
ClassDB : : bind_method ( D_METHOD ( " get_explosiveness_ratio " ) , & GPUParticles3D : : get_explosiveness_ratio ) ;
ClassDB : : bind_method ( D_METHOD ( " get_randomness_ratio " ) , & GPUParticles3D : : get_randomness_ratio ) ;
ClassDB : : bind_method ( D_METHOD ( " get_visibility_aabb " ) , & GPUParticles3D : : get_visibility_aabb ) ;
ClassDB : : bind_method ( D_METHOD ( " get_use_local_coordinates " ) , & GPUParticles3D : : get_use_local_coordinates ) ;
ClassDB : : bind_method ( D_METHOD ( " get_fixed_fps " ) , & GPUParticles3D : : get_fixed_fps ) ;
ClassDB : : bind_method ( D_METHOD ( " get_fractional_delta " ) , & GPUParticles3D : : get_fractional_delta ) ;
2021-04-27 12:43:49 -03:00
ClassDB : : bind_method ( D_METHOD ( " get_interpolate " ) , & GPUParticles3D : : get_interpolate ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " get_process_material " ) , & GPUParticles3D : : get_process_material ) ;
ClassDB : : bind_method ( D_METHOD ( " get_speed_scale " ) , & GPUParticles3D : : get_speed_scale ) ;
2020-10-07 21:29:49 -03:00
ClassDB : : bind_method ( D_METHOD ( " get_collision_base_size " ) , & GPUParticles3D : : get_collision_base_size ) ;
2020-03-26 18:49:16 -03:00
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 ) ;
ClassDB : : bind_method ( D_METHOD ( " set_draw_passes " , " passes " ) , & GPUParticles3D : : set_draw_passes ) ;
ClassDB : : bind_method ( D_METHOD ( " set_draw_pass_mesh " , " pass " , " mesh " ) , & GPUParticles3D : : set_draw_pass_mesh ) ;
ClassDB : : bind_method ( D_METHOD ( " get_draw_passes " ) , & GPUParticles3D : : get_draw_passes ) ;
ClassDB : : bind_method ( D_METHOD ( " get_draw_pass_mesh " , " pass " ) , & GPUParticles3D : : get_draw_pass_mesh ) ;
2021-04-27 12:43:49 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_skin " , " skin " ) , & GPUParticles3D : : set_skin ) ;
ClassDB : : bind_method ( D_METHOD ( " get_skin " ) , & GPUParticles3D : : get_skin ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " restart " ) , & GPUParticles3D : : restart ) ;
ClassDB : : bind_method ( D_METHOD ( " capture_aabb " ) , & GPUParticles3D : : capture_aabb ) ;
2017-04-08 22:38:11 -03:00
2020-09-06 09:18:10 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_sub_emitter " , " path " ) , & GPUParticles3D : : set_sub_emitter ) ;
ClassDB : : bind_method ( D_METHOD ( " get_sub_emitter " ) , & GPUParticles3D : : get_sub_emitter ) ;
ClassDB : : bind_method ( D_METHOD ( " emit_particle " , " xform " , " velocity " , " color " , " custom " , " flags " ) , & GPUParticles3D : : emit_particle ) ;
2021-05-20 11:25:06 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_trail_enabled " , " enabled " ) , & GPUParticles3D : : set_trail_enabled ) ;
2021-04-27 12:43:49 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_trail_length " , " secs " ) , & GPUParticles3D : : set_trail_length ) ;
ClassDB : : bind_method ( D_METHOD ( " is_trail_enabled " ) , & GPUParticles3D : : is_trail_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " get_trail_length " ) , & GPUParticles3D : : get_trail_length ) ;
ClassDB : : bind_method ( D_METHOD ( " set_transform_align " , " align " ) , & GPUParticles3D : : set_transform_align ) ;
ClassDB : : bind_method ( D_METHOD ( " get_transform_align " ) , & GPUParticles3D : : get_transform_align ) ;
2017-04-06 23:36:37 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " emitting " ) , " set_emitting " , " is_emitting " ) ;
2021-10-20 16:37:19 +02:00
ADD_PROPERTY_DEFAULT ( " emitting " , true ) ; // Workaround for doctool in headless mode, as dummy rasterizer always returns false.
2021-06-29 16:42:12 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " amount " , PROPERTY_HINT_RANGE , " 1,1000000,1,exp " ) , " set_amount " , " get_amount " ) ;
2020-09-06 09:18:10 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : NODE_PATH , " sub_emitter " , PROPERTY_HINT_NODE_PATH_VALID_TYPES , " GPUParticles3D " ) , " set_sub_emitter " , " get_sub_emitter " ) ;
2017-06-25 18:57:28 -03:00
ADD_GROUP ( " Time " , " " ) ;
2021-12-02 18:09:19 -06:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " lifetime " , PROPERTY_HINT_RANGE , " 0.01,600.0,0.01,or_greater,exp,suffix:s " ) , " set_lifetime " , " get_lifetime " ) ;
2017-06-25 08:01:15 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " one_shot " ) , " set_one_shot " , " get_one_shot " ) ;
2021-12-02 18:09:19 -06:00
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 " ) ;
2020-02-24 15:20:53 -03:00
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 " ) ;
2021-12-02 18:09:19 -06:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " fixed_fps " , PROPERTY_HINT_RANGE , " 0,1000,1,suffix:FPS " ) , " set_fixed_fps " , " get_fixed_fps " ) ;
2021-04-27 12:43:49 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " interpolate " ) , " set_interpolate " , " get_interpolate " ) ;
2017-04-06 23:36:37 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " fract_delta " ) , " set_fractional_delta " , " get_fractional_delta " ) ;
2020-10-07 21:29:49 -03:00
ADD_GROUP ( " Collision " , " collision_ " ) ;
2021-12-02 18:09:19 -06:00
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 " ) ;
2017-06-25 18:57:28 -03:00
ADD_GROUP ( " Drawing " , " " ) ;
2022-05-20 00:24:41 -05:00
ADD_PROPERTY ( PropertyInfo ( Variant : : AABB , " visibility_aabb " , PROPERTY_HINT_NONE , " suffix:m " ) , " set_visibility_aabb " , " get_visibility_aabb " ) ;
2017-06-25 18:57:28 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " local_coords " ) , " set_use_local_coordinates " , " get_use_local_coordinates " ) ;
2021-05-20 11:25:06 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " draw_order " , PROPERTY_HINT_ENUM , " Index,Lifetime,Reverse Lifetime,View Depth " ) , " set_draw_order " , " get_draw_order " ) ;
2022-05-21 13:13:48 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " transform_align " , PROPERTY_HINT_ENUM , " Disabled,Z-Billboard,Y to Velocity,Z-Billboard + Y to Velocity " ) , " set_transform_align " , " get_transform_align " ) ;
2021-04-27 12:43:49 -03:00
ADD_GROUP ( " Trails " , " trail_ " ) ;
2021-05-20 11:25:06 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " trail_enabled " ) , " set_trail_enabled " , " is_trail_enabled " ) ;
2021-12-02 18:09:19 -06:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " trail_length_secs " , PROPERTY_HINT_RANGE , " 0.01,10,0.01,suffix:s " ) , " set_trail_length " , " get_trail_length " ) ;
2017-04-08 22:38:11 -03:00
ADD_GROUP ( " Process Material " , " " ) ;
2022-08-18 11:09:22 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " process_material " , PROPERTY_HINT_RESOURCE_TYPE , " ShaderMaterial,ParticleProcessMaterial " ) , " set_process_material " , " get_process_material " ) ;
2017-04-06 23:36:37 -03:00
ADD_GROUP ( " Draw Passes " , " draw_ " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " draw_passes " , PROPERTY_HINT_RANGE , " 0, " + itos ( MAX_DRAW_PASSES ) + " ,1 " ) , " set_draw_passes " , " get_draw_passes " ) ;
for ( int i = 0 ; i < MAX_DRAW_PASSES ; i + + ) {
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " draw_pass_ " + itos ( i + 1 ) , PROPERTY_HINT_RESOURCE_TYPE , " Mesh " ) , " set_draw_pass_mesh " , " get_draw_pass_mesh " , i ) ;
}
2021-04-27 12:43:49 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " draw_skin " , PROPERTY_HINT_RESOURCE_TYPE , " Skin " ) , " set_skin " , " get_skin " ) ;
2017-04-06 23:36:37 -03:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( DRAW_ORDER_INDEX ) ;
BIND_ENUM_CONSTANT ( DRAW_ORDER_LIFETIME ) ;
2021-05-20 11:25:06 -03:00
BIND_ENUM_CONSTANT ( DRAW_ORDER_REVERSE_LIFETIME ) ;
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( DRAW_ORDER_VIEW_DEPTH ) ;
2020-09-06 09:18:10 -03:00
BIND_ENUM_CONSTANT ( EMIT_FLAG_POSITION ) ;
BIND_ENUM_CONSTANT ( EMIT_FLAG_ROTATION_SCALE ) ;
BIND_ENUM_CONSTANT ( EMIT_FLAG_VELOCITY ) ;
BIND_ENUM_CONSTANT ( EMIT_FLAG_COLOR ) ;
BIND_ENUM_CONSTANT ( EMIT_FLAG_CUSTOM ) ;
2017-04-06 23:36:37 -03:00
BIND_CONSTANT ( MAX_DRAW_PASSES ) ;
2021-04-27 12:43:49 -03:00
2021-05-01 09:56:32 +01:00
BIND_ENUM_CONSTANT ( TRANSFORM_ALIGN_DISABLED ) ;
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 ) ;
2017-04-06 23:36:37 -03:00
}
2014-02-09 22:10:30 -03:00
2020-03-26 18:49:16 -03:00
GPUParticles3D : : GPUParticles3D ( ) {
2020-03-27 15:21:27 -03:00
particles = RS : : get_singleton ( ) - > particles_create ( ) ;
2021-05-10 13:12:44 -03:00
RS : : get_singleton ( ) - > particles_set_mode ( particles , RS : : PARTICLES_MODE_3D ) ;
2017-04-06 23:36:37 -03:00
set_base ( particles ) ;
2019-07-02 17:23:54 +03:00
one_shot = false ; // Needed so that set_emitting doesn't access uninitialized values
2017-04-06 23:36:37 -03:00
set_emitting ( true ) ;
2017-06-25 08:01:15 -03:00
set_one_shot ( false ) ;
2017-04-08 22:38:11 -03:00
set_amount ( 8 ) ;
2017-04-06 23:36:37 -03:00
set_lifetime ( 1 ) ;
2021-04-27 12:43:49 -03:00
set_fixed_fps ( 30 ) ;
2017-04-06 23:36:37 -03:00
set_fractional_delta ( true ) ;
2021-04-27 12:43:49 -03:00
set_interpolate ( true ) ;
2017-04-06 23:36:37 -03:00
set_pre_process_time ( 0 ) ;
set_explosiveness_ratio ( 0 ) ;
set_randomness_ratio ( 0 ) ;
2021-04-27 12:43:49 -03:00
set_trail_length ( 0.3 ) ;
2017-11-16 21:09:00 -05:00
set_visibility_aabb ( AABB ( Vector3 ( - 4 , - 4 , - 4 ) , Vector3 ( 8 , 8 , 8 ) ) ) ;
2022-06-09 17:38:07 +02:00
set_use_local_coordinates ( false ) ;
2017-04-06 23:36:37 -03:00
set_draw_passes ( 1 ) ;
2017-04-08 22:38:11 -03:00
set_draw_order ( DRAW_ORDER_INDEX ) ;
set_speed_scale ( 1 ) ;
2021-05-20 11:25:06 -03:00
set_collision_base_size ( collision_base_size ) ;
2021-04-27 12:43:49 -03:00
set_transform_align ( TRANSFORM_ALIGN_DISABLED ) ;
2014-02-09 22:10:30 -03:00
}
2016-03-09 00:00:52 +01:00
2020-03-26 18:49:16 -03:00
GPUParticles3D : : ~ GPUParticles3D ( ) {
2020-03-27 15:21:27 -03:00
RS : : get_singleton ( ) - > free ( particles ) ;
2014-02-09 22:10:30 -03:00
}