2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* particles.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2018-01-01 14:40:08 +01:00
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
2014-02-10 02:10:30 +01: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
2014-02-10 02:10:30 +01:00
# include "particles.h"
# include "scene/resources/surface_tool.h"
2017-03-05 16:44:50 +01:00
# include "servers/visual_server.h"
2014-02-10 02:10:30 +01:00
2017-11-17 03:09:00 +01:00
AABB Particles : : get_aabb ( ) const {
2017-04-07 04:36:37 +02:00
2017-11-17 03:09:00 +01:00
return AABB ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-01-07 22:25:37 +01:00
PoolVector < Face3 > Particles : : get_faces ( uint32_t p_usage_flags ) const {
2014-02-10 02:10:30 +01:00
2017-01-07 22:25:37 +01:00
return PoolVector < Face3 > ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void Particles : : set_emitting ( bool p_emitting ) {
2017-12-23 05:08:50 +01:00
VS : : get_singleton ( ) - > particles_set_emitting ( particles , p_emitting ) ;
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
void Particles : : set_amount ( int p_amount ) {
2017-05-15 22:49:34 +02:00
ERR_FAIL_COND ( p_amount < 1 ) ;
2017-04-07 04:36:37 +02:00
amount = p_amount ;
VS : : get_singleton ( ) - > particles_set_amount ( particles , amount ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void Particles : : set_lifetime ( float p_lifetime ) {
2016-03-09 00:00:52 +01:00
2017-05-15 22:49:34 +02:00
ERR_FAIL_COND ( p_lifetime < = 0 ) ;
2017-04-07 04:36:37 +02:00
lifetime = p_lifetime ;
VS : : get_singleton ( ) - > particles_set_lifetime ( particles , lifetime ) ;
2014-02-10 02:10:30 +01:00
}
2017-06-25 13:01:15 +02:00
void Particles : : set_one_shot ( bool p_one_shot ) {
one_shot = p_one_shot ;
VS : : get_singleton ( ) - > particles_set_one_shot ( particles , one_shot ) ;
2017-12-23 05:08:50 +01:00
if ( ! one_shot & & is_emitting ( ) )
2017-08-12 10:13:29 +02:00
VisualServer : : get_singleton ( ) - > particles_restart ( particles ) ;
2017-06-25 13:01:15 +02:00
}
2017-04-07 04:36:37 +02:00
void Particles : : set_pre_process_time ( float p_time ) {
2016-03-09 00:00:52 +01:00
2017-04-07 04:36:37 +02:00
pre_process_time = p_time ;
VS : : get_singleton ( ) - > particles_set_pre_process_time ( particles , pre_process_time ) ;
}
void Particles : : set_explosiveness_ratio ( float p_ratio ) {
explosiveness_ratio = p_ratio ;
VS : : get_singleton ( ) - > particles_set_explosiveness_ratio ( particles , explosiveness_ratio ) ;
}
void Particles : : set_randomness_ratio ( float p_ratio ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
randomness_ratio = p_ratio ;
VS : : get_singleton ( ) - > particles_set_randomness_ratio ( particles , randomness_ratio ) ;
}
2017-11-17 03:09:00 +01:00
void Particles : : set_visibility_aabb ( const AABB & p_aabb ) {
2017-04-07 04:36:37 +02:00
2017-04-09 03:38:11 +02:00
visibility_aabb = p_aabb ;
VS : : get_singleton ( ) - > particles_set_custom_aabb ( particles , visibility_aabb ) ;
update_gizmo ( ) ;
_change_notify ( " visibility_aabb " ) ;
2017-04-07 04:36:37 +02:00
}
void Particles : : set_use_local_coordinates ( bool p_enable ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
local_coords = p_enable ;
VS : : get_singleton ( ) - > particles_set_use_local_coordinates ( particles , local_coords ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void Particles : : set_process_material ( const Ref < Material > & p_material ) {
process_material = p_material ;
RID material_rid ;
if ( process_material . is_valid ( ) )
material_rid = process_material - > get_rid ( ) ;
VS : : get_singleton ( ) - > particles_set_process_material ( particles , material_rid ) ;
2017-04-09 03:38:11 +02:00
update_configuration_warning ( ) ;
}
void Particles : : set_speed_scale ( float p_scale ) {
speed_scale = p_scale ;
VS : : get_singleton ( ) - > particles_set_speed_scale ( particles , p_scale ) ;
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
bool Particles : : is_emitting ( ) const {
2017-12-23 05:08:50 +01:00
return VS : : get_singleton ( ) - > particles_get_emitting ( particles ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
int Particles : : get_amount ( ) const {
2016-03-09 00:00:52 +01:00
2017-04-07 04:36:37 +02:00
return amount ;
}
float Particles : : get_lifetime ( ) const {
return lifetime ;
}
2017-06-25 13:01:15 +02:00
bool Particles : : get_one_shot ( ) const {
return one_shot ;
}
2017-04-07 04:36:37 +02:00
float Particles : : get_pre_process_time ( ) const {
return pre_process_time ;
}
float Particles : : get_explosiveness_ratio ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return explosiveness_ratio ;
}
float Particles : : get_randomness_ratio ( ) const {
2016-03-09 00:00:52 +01:00
2017-04-07 04:36:37 +02:00
return randomness_ratio ;
2014-02-10 02:10:30 +01:00
}
2017-11-17 03:09:00 +01:00
AABB Particles : : get_visibility_aabb ( ) const {
2016-03-09 00:00:52 +01:00
2017-04-09 03:38:11 +02:00
return visibility_aabb ;
2017-04-07 04:36:37 +02:00
}
bool Particles : : get_use_local_coordinates ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return local_coords ;
}
Ref < Material > Particles : : get_process_material ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return process_material ;
2014-02-10 02:10:30 +01:00
}
2017-04-09 03:38:11 +02:00
float Particles : : get_speed_scale ( ) const {
return speed_scale ;
}
2017-04-07 04:36:37 +02:00
void Particles : : set_draw_order ( DrawOrder p_order ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
draw_order = p_order ;
VS : : get_singleton ( ) - > particles_set_draw_order ( particles , VS : : ParticlesDrawOrder ( p_order ) ) ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
Particles : : DrawOrder Particles : : get_draw_order ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return draw_order ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void Particles : : set_draw_passes ( int p_count ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
ERR_FAIL_COND ( p_count < 1 ) ;
draw_passes . resize ( p_count ) ;
VS : : get_singleton ( ) - > particles_set_draw_passes ( particles , p_count ) ;
_change_notify ( ) ;
}
int Particles : : get_draw_passes ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return draw_passes . size ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void Particles : : set_draw_pass_mesh ( int p_pass , const Ref < Mesh > & p_mesh ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
ERR_FAIL_INDEX ( p_pass , draw_passes . size ( ) ) ;
2018-07-25 03:11:03 +02:00
draw_passes . write [ p_pass ] = p_mesh ;
2017-04-07 04:36:37 +02:00
RID mesh_rid ;
if ( p_mesh . is_valid ( ) )
mesh_rid = p_mesh - > get_rid ( ) ;
VS : : get_singleton ( ) - > particles_set_draw_pass_mesh ( particles , p_pass , mesh_rid ) ;
2017-04-09 03:38:11 +02:00
update_configuration_warning ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
Ref < Mesh > Particles : : get_draw_pass_mesh ( int p_pass ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
ERR_FAIL_INDEX_V ( p_pass , draw_passes . size ( ) , Ref < Mesh > ( ) ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return draw_passes [ p_pass ] ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void Particles : : set_fixed_fps ( int p_count ) {
fixed_fps = p_count ;
VS : : get_singleton ( ) - > particles_set_fixed_fps ( particles , p_count ) ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
int Particles : : get_fixed_fps ( ) const {
return fixed_fps ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void Particles : : set_fractional_delta ( bool p_enable ) {
fractional_delta = p_enable ;
VS : : get_singleton ( ) - > particles_set_fractional_delta ( particles , p_enable ) ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
bool Particles : : get_fractional_delta ( ) const {
return fractional_delta ;
}
2017-04-09 03:38:11 +02:00
String Particles : : get_configuration_warning ( ) const {
String warnings ;
bool meshes_found = false ;
for ( int i = 0 ; i < draw_passes . size ( ) ; i + + ) {
if ( draw_passes [ i ] . is_valid ( ) ) {
meshes_found = true ;
break ;
}
}
if ( ! meshes_found ) {
warnings + = " - " + TTR ( " Nothing is visible because meshes have not been assigned to draw passes. " ) ;
}
if ( process_material . is_null ( ) ) {
if ( warnings ! = String ( ) )
warnings + = " \n " ;
warnings + = " - " + TTR ( " A material to process the particles is not assigned, so no behavior is imprinted. " ) ;
}
return warnings ;
}
2017-06-25 13:01:15 +02:00
void Particles : : restart ( ) {
VisualServer : : get_singleton ( ) - > particles_restart ( particles ) ;
}
2017-11-17 03:09:00 +01:00
AABB Particles : : capture_aabb ( ) const {
2017-04-09 03:38:11 +02:00
return VS : : get_singleton ( ) - > particles_get_current_aabb ( particles ) ;
}
2017-04-07 04:36:37 +02:00
void Particles : : _validate_property ( PropertyInfo & property ) const {
if ( property . name . begins_with ( " draw_pass_ " ) ) {
int index = property . name . get_slicec ( ' _ ' , 2 ) . to_int ( ) - 1 ;
if ( index > = draw_passes . size ( ) ) {
property . usage = 0 ;
return ;
}
}
2014-02-10 02:10:30 +01:00
}
2017-08-08 00:01:30 +02:00
void Particles : : _notification ( int p_what ) {
if ( p_what = = NOTIFICATION_PAUSED | | p_what = = NOTIFICATION_UNPAUSED ) {
if ( can_process ( ) ) {
VS : : get_singleton ( ) - > particles_set_speed_scale ( particles , speed_scale ) ;
} else {
VS : : get_singleton ( ) - > particles_set_speed_scale ( particles , 0 ) ;
}
}
}
2017-04-07 04:36:37 +02:00
void Particles : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_emitting " , " emitting " ) , & Particles : : set_emitting ) ;
ClassDB : : bind_method ( D_METHOD ( " set_amount " , " amount " ) , & Particles : : set_amount ) ;
ClassDB : : bind_method ( D_METHOD ( " set_lifetime " , " secs " ) , & Particles : : set_lifetime ) ;
2017-06-25 13:01:15 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_one_shot " , " enable " ) , & Particles : : set_one_shot ) ;
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_pre_process_time " , " secs " ) , & Particles : : set_pre_process_time ) ;
ClassDB : : bind_method ( D_METHOD ( " set_explosiveness_ratio " , " ratio " ) , & Particles : : set_explosiveness_ratio ) ;
ClassDB : : bind_method ( D_METHOD ( " set_randomness_ratio " , " ratio " ) , & Particles : : set_randomness_ratio ) ;
2017-04-09 03:38:11 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_visibility_aabb " , " aabb " ) , & Particles : : set_visibility_aabb ) ;
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_use_local_coordinates " , " enable " ) , & Particles : : set_use_local_coordinates ) ;
ClassDB : : bind_method ( D_METHOD ( " set_fixed_fps " , " fps " ) , & Particles : : set_fixed_fps ) ;
ClassDB : : bind_method ( D_METHOD ( " set_fractional_delta " , " enable " ) , & Particles : : set_fractional_delta ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_process_material " , " material " ) , & Particles : : set_process_material ) ;
2017-04-09 03:38:11 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_speed_scale " , " scale " ) , & Particles : : set_speed_scale ) ;
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_emitting " ) , & Particles : : is_emitting ) ;
ClassDB : : bind_method ( D_METHOD ( " get_amount " ) , & Particles : : get_amount ) ;
ClassDB : : bind_method ( D_METHOD ( " get_lifetime " ) , & Particles : : get_lifetime ) ;
2017-06-25 13:01:15 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_one_shot " ) , & Particles : : get_one_shot ) ;
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_pre_process_time " ) , & Particles : : get_pre_process_time ) ;
ClassDB : : bind_method ( D_METHOD ( " get_explosiveness_ratio " ) , & Particles : : get_explosiveness_ratio ) ;
ClassDB : : bind_method ( D_METHOD ( " get_randomness_ratio " ) , & Particles : : get_randomness_ratio ) ;
2017-04-09 03:38:11 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_visibility_aabb " ) , & Particles : : get_visibility_aabb ) ;
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_use_local_coordinates " ) , & Particles : : get_use_local_coordinates ) ;
ClassDB : : bind_method ( D_METHOD ( " get_fixed_fps " ) , & Particles : : get_fixed_fps ) ;
ClassDB : : bind_method ( D_METHOD ( " get_fractional_delta " ) , & Particles : : get_fractional_delta ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_process_material " ) , & Particles : : get_process_material ) ;
2017-04-09 03:38:11 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_speed_scale " ) , & Particles : : get_speed_scale ) ;
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_draw_order " , " order " ) , & Particles : : set_draw_order ) ;
ClassDB : : bind_method ( D_METHOD ( " get_draw_order " ) , & Particles : : get_draw_order ) ;
ClassDB : : bind_method ( D_METHOD ( " set_draw_passes " , " passes " ) , & Particles : : set_draw_passes ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_draw_pass_mesh " , " pass " , " mesh " ) , & Particles : : set_draw_pass_mesh ) ;
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_draw_passes " ) , & Particles : : get_draw_passes ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_draw_pass_mesh " , " pass " ) , & Particles : : get_draw_pass_mesh ) ;
2017-04-07 04:36:37 +02:00
2017-06-25 13:01:15 +02:00
ClassDB : : bind_method ( D_METHOD ( " restart " ) , & Particles : : restart ) ;
2017-04-09 03:38:11 +02:00
ClassDB : : bind_method ( D_METHOD ( " capture_aabb " ) , & Particles : : capture_aabb ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " emitting " ) , " set_emitting " , " is_emitting " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " amount " , PROPERTY_HINT_EXP_RANGE , " 1,1000000,1 " ) , " set_amount " , " get_amount " ) ;
2017-06-25 23:57:28 +02:00
ADD_GROUP ( " Time " , " " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " lifetime " , PROPERTY_HINT_EXP_RANGE , " 0.01,600.0,0.01 " ) , " set_lifetime " , " get_lifetime " ) ;
2017-06-25 13:01:15 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " one_shot " ) , " set_one_shot " , " get_one_shot " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " preprocess " , PROPERTY_HINT_EXP_RANGE , " 0.00,600.0,0.01 " ) , " set_pre_process_time " , " get_pre_process_time " ) ;
2017-04-09 03:38:11 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " speed_scale " , PROPERTY_HINT_RANGE , " 0.01,64,0.01 " ) , " set_speed_scale " , " get_speed_scale " ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " explosiveness " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_explosiveness_ratio " , " get_explosiveness_ratio " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " randomness " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_randomness_ratio " , " get_randomness_ratio " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " fixed_fps " , PROPERTY_HINT_RANGE , " 0,1000,1 " ) , " set_fixed_fps " , " get_fixed_fps " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " fract_delta " ) , " set_fractional_delta " , " get_fractional_delta " ) ;
2017-06-25 23:57:28 +02:00
ADD_GROUP ( " Drawing " , " " ) ;
2017-11-17 03:09:00 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : AABB , " visibility_aabb " ) , " set_visibility_aabb " , " get_visibility_aabb " ) ;
2017-06-25 23:57:28 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " local_coords " ) , " set_use_local_coordinates " , " get_use_local_coordinates " ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " draw_order " , PROPERTY_HINT_ENUM , " Index,Lifetime,View Depth " ) , " set_draw_order " , " get_draw_order " ) ;
2017-04-09 03:38:11 +02:00
ADD_GROUP ( " Process Material " , " " ) ;
2017-06-22 14:17:06 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " process_material " , PROPERTY_HINT_RESOURCE_TYPE , " ShaderMaterial,ParticlesMaterial " ) , " set_process_material " , " get_process_material " ) ;
2017-04-07 04:36:37 +02: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 ) ;
}
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( DRAW_ORDER_INDEX ) ;
BIND_ENUM_CONSTANT ( DRAW_ORDER_LIFETIME ) ;
BIND_ENUM_CONSTANT ( DRAW_ORDER_VIEW_DEPTH ) ;
2017-04-07 04:36:37 +02:00
BIND_CONSTANT ( MAX_DRAW_PASSES ) ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
Particles : : Particles ( ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
particles = VS : : get_singleton ( ) - > particles_create ( ) ;
set_base ( particles ) ;
set_emitting ( true ) ;
2017-06-25 13:01:15 +02:00
set_one_shot ( false ) ;
2017-04-09 03:38:11 +02:00
set_amount ( 8 ) ;
2017-04-07 04:36:37 +02:00
set_lifetime ( 1 ) ;
set_fixed_fps ( 0 ) ;
set_fractional_delta ( true ) ;
set_pre_process_time ( 0 ) ;
set_explosiveness_ratio ( 0 ) ;
set_randomness_ratio ( 0 ) ;
2017-11-17 03:09:00 +01:00
set_visibility_aabb ( AABB ( Vector3 ( - 4 , - 4 , - 4 ) , Vector3 ( 8 , 8 , 8 ) ) ) ;
2017-04-07 04:36:37 +02:00
set_use_local_coordinates ( true ) ;
set_draw_passes ( 1 ) ;
2017-04-09 03:38:11 +02:00
set_draw_order ( DRAW_ORDER_INDEX ) ;
set_speed_scale ( 1 ) ;
2014-02-10 02:10:30 +01:00
}
2016-03-09 00:00:52 +01:00
2017-04-07 04:36:37 +02:00
Particles : : ~ Particles ( ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
VS : : get_singleton ( ) - > free ( particles ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
//////////////////////////////////////
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
Mutex * ParticlesMaterial : : material_mutex = NULL ;
SelfList < ParticlesMaterial > : : List ParticlesMaterial : : dirty_materials ;
Map < ParticlesMaterial : : MaterialKey , ParticlesMaterial : : ShaderData > ParticlesMaterial : : shader_map ;
ParticlesMaterial : : ShaderNames * ParticlesMaterial : : shader_names = NULL ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : init_shaders ( ) {
# ifndef NO_THREADS
material_mutex = Mutex : : create ( ) ;
# endif
shader_names = memnew ( ShaderNames ) ;
shader_names - > spread = " spread " ;
shader_names - > flatness = " flatness " ;
shader_names - > initial_linear_velocity = " initial_linear_velocity " ;
shader_names - > initial_angle = " initial_angle " ;
shader_names - > angular_velocity = " angular_velocity " ;
shader_names - > orbit_velocity = " orbit_velocity " ;
shader_names - > linear_accel = " linear_accel " ;
shader_names - > radial_accel = " radial_accel " ;
shader_names - > tangent_accel = " tangent_accel " ;
shader_names - > damping = " damping " ;
shader_names - > scale = " scale " ;
shader_names - > hue_variation = " hue_variation " ;
shader_names - > anim_speed = " anim_speed " ;
shader_names - > anim_offset = " anim_offset " ;
2017-08-12 21:33:20 +02:00
shader_names - > initial_linear_velocity_random = " initial_linear_velocity_random " ;
2017-04-07 04:36:37 +02:00
shader_names - > initial_angle_random = " initial_angle_random " ;
shader_names - > angular_velocity_random = " angular_velocity_random " ;
shader_names - > orbit_velocity_random = " orbit_velocity_random " ;
shader_names - > linear_accel_random = " linear_accel_random " ;
shader_names - > radial_accel_random = " radial_accel_random " ;
shader_names - > tangent_accel_random = " tangent_accel_random " ;
shader_names - > damping_random = " damping_random " ;
shader_names - > scale_random = " scale_random " ;
shader_names - > hue_variation_random = " hue_variation_random " ;
shader_names - > anim_speed_random = " anim_speed_random " ;
shader_names - > anim_offset_random = " anim_offset_random " ;
shader_names - > angle_texture = " angle_texture " ;
shader_names - > angular_velocity_texture = " angular_velocity_texture " ;
shader_names - > orbit_velocity_texture = " orbit_velocity_texture " ;
shader_names - > linear_accel_texture = " linear_accel_texture " ;
shader_names - > radial_accel_texture = " radial_accel_texture " ;
shader_names - > tangent_accel_texture = " tangent_accel_texture " ;
shader_names - > damping_texture = " damping_texture " ;
shader_names - > scale_texture = " scale_texture " ;
shader_names - > hue_variation_texture = " hue_variation_texture " ;
shader_names - > anim_speed_texture = " anim_speed_texture " ;
shader_names - > anim_offset_texture = " anim_offset_texture " ;
shader_names - > color = " color_value " ;
shader_names - > color_ramp = " color_ramp " ;
shader_names - > emission_sphere_radius = " emission_sphere_radius " ;
shader_names - > emission_box_extents = " emission_box_extents " ;
shader_names - > emission_texture_point_count = " emission_texture_point_count " ;
shader_names - > emission_texture_points = " emission_texture_points " ;
shader_names - > emission_texture_normal = " emission_texture_normal " ;
2017-06-21 21:25:45 +02:00
shader_names - > emission_texture_color = " emission_texture_color " ;
2017-04-07 04:36:37 +02:00
shader_names - > trail_divisor = " trail_divisor " ;
shader_names - > trail_size_modifier = " trail_size_modifier " ;
shader_names - > trail_color_modifier = " trail_color_modifier " ;
2017-04-09 03:38:11 +02:00
shader_names - > gravity = " gravity " ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : finish_shaders ( ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
# ifndef NO_THREADS
memdelete ( material_mutex ) ;
# endif
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
memdelete ( shader_names ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : _update_shader ( ) {
dirty_materials . remove ( & element ) ;
MaterialKey mk = _compute_key ( ) ;
if ( mk . key = = current_key . key )
return ; //no update required in the end
if ( shader_map . has ( current_key ) ) {
shader_map [ current_key ] . users - - ;
if ( shader_map [ current_key ] . users = = 0 ) {
//deallocate shader, as it's no longer in use
VS : : get_singleton ( ) - > free ( shader_map [ current_key ] . shader ) ;
shader_map . erase ( current_key ) ;
}
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
current_key = mk ;
if ( shader_map . has ( mk ) ) {
VS : : get_singleton ( ) - > material_set_shader ( _get_material ( ) , shader_map [ mk ] . shader ) ;
shader_map [ mk ] . users + + ;
return ;
}
//must create a shader!
String code = " shader_type particles; \n " ;
code + = " uniform float spread; \n " ;
code + = " uniform float flatness; \n " ;
code + = " uniform float initial_linear_velocity; \n " ;
code + = " uniform float initial_angle; \n " ;
code + = " uniform float angular_velocity; \n " ;
code + = " uniform float orbit_velocity; \n " ;
code + = " uniform float linear_accel; \n " ;
code + = " uniform float radial_accel; \n " ;
code + = " uniform float tangent_accel; \n " ;
code + = " uniform float damping; \n " ;
code + = " uniform float scale; \n " ;
code + = " uniform float hue_variation; \n " ;
code + = " uniform float anim_speed; \n " ;
code + = " uniform float anim_offset; \n " ;
code + = " uniform float initial_linear_velocity_random; \n " ;
code + = " uniform float initial_angle_random; \n " ;
code + = " uniform float angular_velocity_random; \n " ;
code + = " uniform float orbit_velocity_random; \n " ;
code + = " uniform float linear_accel_random; \n " ;
code + = " uniform float radial_accel_random; \n " ;
code + = " uniform float tangent_accel_random; \n " ;
code + = " uniform float damping_random; \n " ;
code + = " uniform float scale_random; \n " ;
code + = " uniform float hue_variation_random; \n " ;
code + = " uniform float anim_speed_random; \n " ;
code + = " uniform float anim_offset_random; \n " ;
2017-06-21 21:25:45 +02:00
switch ( emission_shape ) {
case EMISSION_SHAPE_POINT : {
//do none
} break ;
case EMISSION_SHAPE_SPHERE : {
code + = " uniform float emission_sphere_radius; \n " ;
} break ;
case EMISSION_SHAPE_BOX : {
code + = " uniform vec3 emission_box_extents; \n " ;
} break ;
case EMISSION_SHAPE_DIRECTED_POINTS : {
code + = " uniform sampler2D emission_texture_normal : hint_black; \n " ;
} //fallthrough
case EMISSION_SHAPE_POINTS : {
code + = " uniform sampler2D emission_texture_points : hint_black; \n " ;
code + = " uniform int emission_texture_point_count; \n " ;
if ( emission_color_texture . is_valid ( ) ) {
code + = " uniform sampler2D emission_texture_color : hint_white; \n " ;
}
} break ;
}
2017-04-07 04:36:37 +02:00
code + = " uniform vec4 color_value : hint_color; \n " ;
code + = " uniform int trail_divisor; \n " ;
2017-04-09 03:38:11 +02:00
code + = " uniform vec3 gravity; \n " ;
2017-04-07 04:36:37 +02:00
if ( color_ramp . is_valid ( ) )
code + = " uniform sampler2D color_ramp; \n " ;
if ( tex_parameters [ PARAM_INITIAL_LINEAR_VELOCITY ] . is_valid ( ) )
code + = " uniform sampler2D linear_velocity_texture; \n " ;
if ( tex_parameters [ PARAM_ORBIT_VELOCITY ] . is_valid ( ) )
code + = " uniform sampler2D orbit_velocity_texture; \n " ;
if ( tex_parameters [ PARAM_ANGULAR_VELOCITY ] . is_valid ( ) )
code + = " uniform sampler2D angular_velocity_texture; \n " ;
if ( tex_parameters [ PARAM_LINEAR_ACCEL ] . is_valid ( ) )
code + = " uniform sampler2D linear_accel_texture; \n " ;
if ( tex_parameters [ PARAM_RADIAL_ACCEL ] . is_valid ( ) )
code + = " uniform sampler2D radial_accel_texture; \n " ;
if ( tex_parameters [ PARAM_TANGENTIAL_ACCEL ] . is_valid ( ) )
code + = " uniform sampler2D tangent_accel_texture; \n " ;
if ( tex_parameters [ PARAM_DAMPING ] . is_valid ( ) )
code + = " uniform sampler2D damping_texture; \n " ;
if ( tex_parameters [ PARAM_ANGLE ] . is_valid ( ) )
code + = " uniform sampler2D angle_texture; \n " ;
if ( tex_parameters [ PARAM_SCALE ] . is_valid ( ) )
code + = " uniform sampler2D scale_texture; \n " ;
if ( tex_parameters [ PARAM_HUE_VARIATION ] . is_valid ( ) )
code + = " uniform sampler2D hue_variation_texture; \n " ;
if ( tex_parameters [ PARAM_ANIM_SPEED ] . is_valid ( ) )
code + = " uniform sampler2D anim_speed_texture; \n " ;
if ( tex_parameters [ PARAM_ANIM_OFFSET ] . is_valid ( ) )
code + = " uniform sampler2D anim_offset_texture; \n " ;
if ( trail_size_modifier . is_valid ( ) ) {
code + = " uniform sampler2D trail_size_modifier; \n " ;
}
if ( trail_color_modifier . is_valid ( ) ) {
code + = " uniform sampler2D trail_color_modifier; \n " ;
}
//need a random function
code + = " \n \n " ;
code + = " float rand_from_seed(inout uint seed) { \n " ;
2017-10-12 13:12:50 +02:00
code + = " int k; \n " ;
code + = " int s = int(seed); \n " ;
code + = " if (s == 0) \n " ;
2017-04-07 04:36:37 +02:00
code + = " s = 305420679; \n " ;
2017-10-12 13:12:50 +02:00
code + = " k = s / 127773; \n " ;
code + = " s = 16807 * (s - k * 127773) - 2836 * k; \n " ;
code + = " if (s < 0) \n " ;
code + = " s += 2147483647; \n " ;
code + = " seed = uint(s); \n " ;
code + = " return float(seed % uint(65536))/65535.0; \n " ;
2017-04-07 04:36:37 +02:00
code + = " } \n " ;
2017-10-12 13:12:50 +02:00
code + = " \n " ;
2017-12-15 23:49:26 +01:00
code + = " float rand_from_seed_m1_p1(inout uint seed) { \n " ;
code + = " return rand_from_seed(seed)*2.0-1.0; \n " ;
code + = " } \n " ;
code + = " \n " ;
2017-04-07 04:36:37 +02:00
//improve seed quality
code + = " uint hash(uint x) { \n " ;
2017-10-12 13:12:50 +02:00
code + = " x = ((x >> uint(16)) ^ x) * uint(73244475); \n " ;
code + = " x = ((x >> uint(16)) ^ x) * uint(73244475); \n " ;
code + = " x = (x >> uint(16)) ^ x; \n " ;
code + = " return x; \n " ;
2017-04-07 04:36:37 +02:00
code + = " } \n " ;
code + = " \n " ;
2017-10-12 13:12:50 +02:00
code + = " void vertex() { \n " ;
code + = " uint base_number = NUMBER/uint(trail_divisor); \n " ;
code + = " uint alt_seed = hash(base_number+uint(1)+RANDOM_SEED); \n " ;
code + = " float angle_rand = rand_from_seed(alt_seed); \n " ;
code + = " float scale_rand = rand_from_seed(alt_seed); \n " ;
code + = " float hue_rot_rand = rand_from_seed(alt_seed); \n " ;
code + = " float anim_offset_rand = rand_from_seed(alt_seed); \n " ;
2017-12-15 23:49:26 +01:00
code + = " float pi = 3.14159; \n " ;
code + = " float degree_to_rad = pi / 180.0; \n " ;
2017-04-07 04:36:37 +02:00
code + = " \n " ;
2017-10-12 13:12:50 +02:00
2017-06-21 21:25:45 +02:00
if ( emission_shape > = EMISSION_SHAPE_POINTS ) {
2017-10-12 13:12:50 +02:00
code + = " int point = min(emission_texture_point_count-1,int(rand_from_seed(alt_seed) * float(emission_texture_point_count))); \n " ;
code + = " ivec2 emission_tex_size = textureSize( emission_texture_points, 0 ); \n " ;
code + = " ivec2 emission_tex_ofs = ivec2( point % emission_tex_size.x, point / emission_tex_size.x ); \n " ;
2017-06-21 21:25:45 +02:00
}
2017-10-12 13:12:50 +02:00
code + = " if (RESTART) { \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_INITIAL_LINEAR_VELOCITY ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(0.0,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_linear_velocity = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_ANGLE ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_angle = textureLod(angle_texture,vec2(0.0,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_angle = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_ANIM_OFFSET ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_anim_offset = textureLod(anim_offset_texture,vec2(0.0,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_anim_offset = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
2017-12-15 23:49:26 +01:00
code + = " float spread_rad = spread*degree_to_rad; \n " ;
2017-06-21 21:25:45 +02:00
if ( flags [ FLAG_DISABLE_Z ] ) {
2017-12-15 23:49:26 +01:00
code + = " float angle1_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad; \n " ;
code + = " vec3 rot = vec3( cos(angle1_rad), sin(angle1_rad),0.0 ); \n " ;
2017-11-06 17:39:10 +01:00
code + = " VELOCITY = rot*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random); \n " ;
2017-06-21 21:25:45 +02:00
} else {
//initiate velocity spread in 3D
2017-12-15 23:49:26 +01:00
code + = " float angle1_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad; \n " ;
code + = " float angle2_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad*(1.0-flatness); \n " ;
code + = " vec3 direction_xz = vec3( sin(angle1_rad), 0, cos(angle1_rad)); \n " ;
code + = " vec3 direction_yz = vec3( 0, sin(angle2_rad), cos(angle2_rad)); \n " ;
code + = " direction_yz.z = direction_yz.z / sqrt(direction_yz.z); //better uniform distribution \n " ;
code + = " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z); \n " ;
code + = " direction = normalize(direction); \n " ;
code + = " VELOCITY = direction*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random); \n " ;
2017-06-21 21:25:45 +02:00
}
2017-10-12 13:12:50 +02:00
code + = " float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random); \n " ;
2017-12-15 23:49:26 +01:00
code + = " CUSTOM.x = base_angle*degree_to_rad; \n " ; //angle
2017-10-12 13:12:50 +02:00
code + = " CUSTOM.y = 0.0; \n " ; //phase
code + = " CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random); \n " ; //animation offset (0-1)
2017-04-07 04:36:37 +02:00
switch ( emission_shape ) {
case EMISSION_SHAPE_POINT : {
//do none
} break ;
case EMISSION_SHAPE_SPHERE : {
2017-10-12 13:12:50 +02:00
code + = " TRANSFORM[3].xyz = normalize(vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0 ))*emission_sphere_radius; \n " ;
2017-04-07 04:36:37 +02:00
} break ;
case EMISSION_SHAPE_BOX : {
2017-10-12 13:12:50 +02:00
code + = " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0)*emission_box_extents; \n " ;
2017-04-07 04:36:37 +02:00
} break ;
case EMISSION_SHAPE_POINTS :
case EMISSION_SHAPE_DIRECTED_POINTS : {
2017-10-12 13:12:50 +02:00
code + = " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs,0).xyz; \n " ;
2017-06-21 21:25:45 +02:00
2017-04-07 04:36:37 +02:00
if ( emission_shape = = EMISSION_SHAPE_DIRECTED_POINTS ) {
2017-06-21 21:25:45 +02:00
if ( flags [ FLAG_DISABLE_Z ] ) {
2017-10-12 13:12:50 +02:00
code + = " mat2 rotm; " ;
code + = " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs,0).xy; \n " ;
code + = " rotm[1] = rotm[0].yx * vec2(1.0,-1.0); \n " ;
code + = " VELOCITY.xy = rotm * VELOCITY.xy; \n " ;
2017-06-21 21:25:45 +02:00
} else {
2017-10-12 13:12:50 +02:00
code + = " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs,0).xyz; \n " ;
code + = " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0); \n " ;
code + = " vec3 tangent = normalize(cross(v0, normal)); \n " ;
code + = " vec3 bitangent = normalize(cross(tangent, normal)); \n " ;
code + = " VELOCITY = mat3(tangent,bitangent,normal) * VELOCITY; \n " ;
2017-06-21 21:25:45 +02:00
}
2017-04-07 04:36:37 +02:00
}
} break ;
}
2017-10-12 13:12:50 +02:00
code + = " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY,0.0)).xyz; \n " ;
code + = " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM; \n " ;
2017-06-21 21:25:45 +02:00
if ( flags [ FLAG_DISABLE_Z ] ) {
2017-10-12 13:12:50 +02:00
code + = " VELOCITY.z = 0.0; \n " ;
code + = " TRANSFORM[3].z = 0.0; \n " ;
2017-06-21 21:25:45 +02:00
}
2017-04-07 04:36:37 +02:00
2017-10-12 13:12:50 +02:00
code + = " } else { \n " ;
2017-04-07 04:36:37 +02:00
2017-10-12 13:12:50 +02:00
code + = " CUSTOM.y += DELTA/LIFETIME; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_INITIAL_LINEAR_VELOCITY ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_linear_velocity = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
2017-12-07 17:17:03 +01:00
if ( flags [ FLAG_DISABLE_Z ] ) {
if ( tex_parameters [ PARAM_ORBIT_VELOCITY ] . is_valid ( ) )
code + = " float tex_orbit_velocity = textureLod(orbit_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
else
code + = " float tex_orbit_velocity = 0.0; \n " ;
}
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_ANGULAR_VELOCITY ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_angular_velocity = textureLod(angular_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_angular_velocity = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_LINEAR_ACCEL ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_linear_accel = textureLod(linear_accel_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_linear_accel = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_RADIAL_ACCEL ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_radial_accel = textureLod(radial_accel_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_radial_accel = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_TANGENTIAL_ACCEL ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_tangent_accel = textureLod(tangent_accel_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_tangent_accel = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_DAMPING ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_damping = textureLod(damping_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_damping = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_ANGLE ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_angle = textureLod(angle_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_angle = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_ANIM_SPEED ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_anim_speed = textureLod(anim_speed_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_anim_speed = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_ANIM_OFFSET ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_anim_offset = textureLod(anim_offset_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_anim_offset = 0.0; \n " ;
2017-04-07 04:36:37 +02:00
2017-10-12 13:12:50 +02:00
code + = " vec3 force = gravity; \n " ;
code + = " vec3 pos = TRANSFORM[3].xyz; \n " ;
2017-06-21 21:25:45 +02:00
if ( flags [ FLAG_DISABLE_Z ] ) {
2017-10-12 13:12:50 +02:00
code + = " pos.z = 0.0; \n " ;
2017-06-21 21:25:45 +02:00
}
2017-10-12 13:12:50 +02:00
code + = " //apply linear acceleration \n " ;
code + = " force += length(VELOCITY) > 0.0 ? normalize(VELOCITY) * (linear_accel+tex_linear_accel)*mix(1.0,rand_from_seed(alt_seed),linear_accel_random) : vec3(0.0); \n " ;
code + = " //apply radial acceleration \n " ;
2017-12-07 17:17:03 +01:00
code + = " vec3 org = EMISSION_TRANSFORM[3].xyz; \n " ;
2017-10-12 13:12:50 +02:00
code + = " vec3 diff = pos-org; \n " ;
code + = " force += length(diff) > 0.0 ? normalize(diff) * (radial_accel+tex_radial_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random) : vec3(0.0); \n " ;
code + = " //apply tangential acceleration; \n " ;
2017-06-21 21:25:45 +02:00
if ( flags [ FLAG_DISABLE_Z ] ) {
2017-11-10 23:19:08 +01:00
code + = " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0,1.0)),0.0) * ((tangent_accel+tex_tangent_accel)*mix(1.0,rand_from_seed(alt_seed),tangent_accel_random)) : vec3(0.0); \n " ;
2017-06-21 21:25:45 +02:00
} else {
2017-10-12 13:12:50 +02:00
code + = " vec3 crossDiff = cross(normalize(diff),normalize(gravity)); \n " ;
2017-11-10 23:19:08 +01:00
code + = " force += length(crossDiff) > 0.0 ? normalize(crossDiff) * ((tangent_accel+tex_tangent_accel)*mix(1.0,rand_from_seed(alt_seed),tangent_accel_random)) : vec3(0.0); \n " ;
2017-06-21 21:25:45 +02:00
}
2017-10-12 13:12:50 +02:00
code + = " //apply attractor forces \n " ;
code + = " VELOCITY += force * DELTA; \n " ;
2017-12-07 17:17:03 +01:00
code + = " //orbit velocity \n " ;
if ( flags [ FLAG_DISABLE_Z ] ) {
code + = " float orbit_amount = (orbit_velocity+tex_orbit_velocity)*mix(1.0,rand_from_seed(alt_seed),orbit_velocity_random); \n " ;
code + = " if (orbit_amount!=0.0) { \n " ;
2017-12-15 23:49:26 +01:00
code + = " float ang = orbit_amount * DELTA * pi * 2.0; \n " ;
2017-12-07 17:17:03 +01:00
code + = " mat2 rot = mat2(vec2(cos(ang),-sin(ang)),vec2(sin(ang),cos(ang))); \n " ;
code + = " TRANSFORM[3].xy-=diff.xy; \n " ;
code + = " TRANSFORM[3].xy+=rot * diff.xy; \n " ;
code + = " } \n " ;
}
2017-06-21 21:25:45 +02:00
if ( tex_parameters [ PARAM_INITIAL_LINEAR_VELOCITY ] . is_valid ( ) ) {
2017-10-12 13:12:50 +02:00
code + = " VELOCITY = normalize(VELOCITY)*tex_linear_velocity; \n " ;
2017-06-21 21:25:45 +02:00
}
2017-10-12 13:12:50 +02:00
code + = " if (damping + tex_damping > 0.0) { \n " ;
code + = " \n " ;
code + = " float v = length(VELOCITY); \n " ;
code + = " float damp = (damping+tex_damping)*mix(1.0,rand_from_seed(alt_seed),damping_random); \n " ;
code + = " v -= damp * DELTA; \n " ;
code + = " if (v < 0.0) { \n " ;
code + = " VELOCITY = vec3(0.0); \n " ;
code + = " } else { \n " ;
code + = " VELOCITY = normalize(VELOCITY) * v; \n " ;
code + = " } \n " ;
code + = " } \n " ;
code + = " float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random); \n " ;
code + = " base_angle += CUSTOM.y*LIFETIME*(angular_velocity+tex_angular_velocity)*mix(1.0,rand_from_seed(alt_seed)*2.0-1.0,angular_velocity_random); \n " ;
2017-12-15 23:49:26 +01:00
code + = " CUSTOM.x = base_angle*degree_to_rad; \n " ; //angle
2017-10-12 13:12:50 +02:00
code + = " CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random)+CUSTOM.y*(anim_speed+tex_anim_speed)*mix(1.0,rand_from_seed(alt_seed),anim_speed_random); \n " ; //angle
2017-06-21 21:25:45 +02:00
if ( flags [ FLAG_ANIM_LOOP ] ) {
2017-10-12 13:12:50 +02:00
code + = " CUSTOM.z = mod(CUSTOM.z,1.0); \n " ; //loop
2017-06-21 21:25:45 +02:00
} else {
2017-10-12 13:12:50 +02:00
code + = " CUSTOM.z = clamp(CUSTOM.z,0.0,1.0); \n " ; //0 to 1 only
2017-06-21 21:25:45 +02:00
}
2017-10-12 13:12:50 +02:00
code + = " } \n " ;
2017-04-07 04:36:37 +02:00
//apply color
//apply hue rotation
if ( tex_parameters [ PARAM_SCALE ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_scale = textureLod(scale_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_scale = 1.0; \n " ;
2017-04-07 04:36:37 +02:00
if ( tex_parameters [ PARAM_HUE_VARIATION ] . is_valid ( ) )
2017-10-12 13:12:50 +02:00
code + = " float tex_hue_variation = textureLod(hue_variation_texture,vec2(CUSTOM.y,0.0),0.0).r; \n " ;
2017-04-07 04:36:37 +02:00
else
2017-10-12 13:12:50 +02:00
code + = " float tex_hue_variation = 0.0; \n " ;
2017-12-15 23:49:26 +01:00
code + = " float hue_rot_angle = (hue_variation+tex_hue_variation)*pi*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random); \n " ;
2017-10-12 13:12:50 +02:00
code + = " float hue_rot_c = cos(hue_rot_angle); \n " ;
code + = " float hue_rot_s = sin(hue_rot_angle); \n " ;
code + = " mat4 hue_rot_mat = mat4( vec4(0.299, 0.587, 0.114, 0.0), \n " ;
code + = " vec4(0.299, 0.587, 0.114, 0.0), \n " ;
code + = " vec4(0.299, 0.587, 0.114, 0.0), \n " ;
code + = " vec4(0.000, 0.000, 0.000, 1.0)) + \n " ;
code + = " mat4( vec4(0.701, -0.587, -0.114, 0.0), \n " ;
code + = " vec4(-0.299, 0.413, -0.114, 0.0), \n " ;
code + = " vec4(-0.300, -0.588, 0.886, 0.0), \n " ;
code + = " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_c + \n " ;
code + = " mat4( vec4(0.168, 0.330, -0.497, 0.0), \n " ;
code + = " vec4(-0.328, 0.035, 0.292, 0.0), \n " ;
code + = " vec4(1.250, -1.050, -0.203, 0.0), \n " ;
code + = " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s; \n " ;
2017-04-07 04:36:37 +02:00
if ( color_ramp . is_valid ( ) ) {
2018-03-20 01:28:41 +01:00
code + = " COLOR = hue_rot_mat * textureLod(color_ramp,vec2(CUSTOM.y,0.0),0.0); \n " ;
2017-04-07 04:36:37 +02:00
} else {
2018-03-20 01:28:41 +01:00
code + = " COLOR = hue_rot_mat * color_value; \n " ;
2017-04-07 04:36:37 +02:00
}
2017-06-21 21:25:45 +02:00
if ( emission_color_texture . is_valid ( ) & & emission_shape > = EMISSION_SHAPE_POINTS ) {
2017-10-12 13:12:50 +02:00
code + = " COLOR*= texelFetch(emission_texture_color,emission_tex_ofs,0); \n " ;
2017-06-21 21:25:45 +02:00
}
2017-04-07 04:36:37 +02:00
if ( trail_color_modifier . is_valid ( ) ) {
2017-10-12 13:12:50 +02:00
code + = " if (trail_divisor > 1) { COLOR *= textureLod(trail_color_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0); } \n " ;
2017-04-07 04:36:37 +02:00
}
code + = " \n " ;
2017-06-21 21:25:45 +02:00
if ( flags [ FLAG_DISABLE_Z ] ) {
2017-11-18 23:39:20 +01:00
if ( flags [ FLAG_ALIGN_Y_TO_VELOCITY ] ) {
code + = " if (length(VELOCITY) > 0.0) { TRANSFORM[1].xyz = normalize(VELOCITY); } else { TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz); } \n " ;
code + = " TRANSFORM[0].xyz = normalize(cross(TRANSFORM[1].xyz,TRANSFORM[2].xyz)); \n " ;
code + = " TRANSFORM[2] = vec4(0.0,0.0,1.0,0.0); \n " ;
} else {
code + = " TRANSFORM[0] = vec4(cos(CUSTOM.x),-sin(CUSTOM.x),0.0,0.0); \n " ;
code + = " TRANSFORM[1] = vec4(sin(CUSTOM.x),cos(CUSTOM.x),0.0,0.0); \n " ;
code + = " TRANSFORM[2] = vec4(0.0,0.0,1.0,0.0); \n " ;
}
2017-06-21 21:25:45 +02:00
2017-04-07 04:36:37 +02:00
} else {
2017-06-21 21:25:45 +02:00
//orient particle Y towards velocity
if ( flags [ FLAG_ALIGN_Y_TO_VELOCITY ] ) {
2017-10-12 13:12:50 +02:00
code + = " if (length(VELOCITY) > 0.0) { TRANSFORM[1].xyz = normalize(VELOCITY); } else { TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz); } \n " ;
code + = " if (TRANSFORM[1].xyz == normalize(TRANSFORM[0].xyz)) { \n " ;
code + = " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz))); \n " ;
code + = " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz))); \n " ;
code + = " } else { \n " ;
code + = " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz))); \n " ;
code + = " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz))); \n " ;
code + = " } \n " ;
2017-06-21 21:25:45 +02:00
} else {
2017-10-12 13:12:50 +02:00
code + = " TRANSFORM[0].xyz = normalize(TRANSFORM[0].xyz); \n " ;
code + = " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz); \n " ;
code + = " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz); \n " ;
2017-06-21 21:25:45 +02:00
}
//turn particle by rotation in Y
if ( flags [ FLAG_ROTATE_Y ] ) {
2017-10-12 13:12:50 +02:00
code + = " TRANSFORM = TRANSFORM * mat4( vec4(cos(CUSTOM.x),0.0,-sin(CUSTOM.x),0.0), vec4(0.0,1.0,0.0,0.0),vec4(sin(CUSTOM.x),0.0,cos(CUSTOM.x),0.0),vec4(0.0,0.0,0.0,1.0)); \n " ;
2017-06-21 21:25:45 +02:00
}
2017-04-07 04:36:37 +02:00
}
//scale by scale
2017-10-12 13:12:50 +02:00
code + = " float base_scale = mix(scale*tex_scale,1.0,scale_random*scale_rand); \n " ;
2017-12-06 23:43:22 +01:00
code + = " if (base_scale==0.0) base_scale=0.000001; \n " ;
2017-04-07 04:36:37 +02:00
if ( trail_size_modifier . is_valid ( ) ) {
2017-10-12 13:12:50 +02:00
code + = " if (trail_divisor > 1) { base_scale *= textureLod(trail_size_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0).r; } \n " ;
2017-04-07 04:36:37 +02:00
}
2017-10-12 13:12:50 +02:00
code + = " TRANSFORM[0].xyz *= base_scale; \n " ;
code + = " TRANSFORM[1].xyz *= base_scale; \n " ;
code + = " TRANSFORM[2].xyz *= base_scale; \n " ;
2017-06-21 21:25:45 +02:00
if ( flags [ FLAG_DISABLE_Z ] ) {
2017-10-12 13:12:50 +02:00
code + = " VELOCITY.z = 0.0; \n " ;
code + = " TRANSFORM[3].z = 0.0; \n " ;
2017-06-21 21:25:45 +02:00
}
2017-04-07 04:36:37 +02:00
code + = " } \n " ;
code + = " \n " ;
ShaderData shader_data ;
shader_data . shader = VS : : get_singleton ( ) - > shader_create ( ) ;
shader_data . users = 1 ;
VS : : get_singleton ( ) - > shader_set_code ( shader_data . shader , code ) ;
shader_map [ mk ] = shader_data ;
VS : : get_singleton ( ) - > material_set_shader ( _get_material ( ) , shader_data . shader ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : flush_changes ( ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
if ( material_mutex )
material_mutex - > lock ( ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
while ( dirty_materials . first ( ) ) {
dirty_materials . first ( ) - > self ( ) - > _update_shader ( ) ;
}
if ( material_mutex )
material_mutex - > unlock ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : _queue_shader_change ( ) {
if ( material_mutex )
material_mutex - > lock ( ) ;
if ( ! element . in_list ( ) ) {
dirty_materials . add ( & element ) ;
}
if ( material_mutex )
material_mutex - > unlock ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
bool ParticlesMaterial : : _is_shader_dirty ( ) const {
bool dirty = false ;
if ( material_mutex )
material_mutex - > lock ( ) ;
dirty = element . in_list ( ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
if ( material_mutex )
material_mutex - > unlock ( ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return dirty ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_spread ( float p_spread ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
spread = p_spread ;
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > spread , p_spread ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
float ParticlesMaterial : : get_spread ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return spread ;
}
void ParticlesMaterial : : set_flatness ( float p_flatness ) {
flatness = p_flatness ;
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > flatness , p_flatness ) ;
}
float ParticlesMaterial : : get_flatness ( ) const {
return flatness ;
}
void ParticlesMaterial : : set_param ( Parameter p_param , float p_value ) {
ERR_FAIL_INDEX ( p_param , PARAM_MAX ) ;
parameters [ p_param ] = p_value ;
switch ( p_param ) {
case PARAM_INITIAL_LINEAR_VELOCITY : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > initial_linear_velocity , p_value ) ;
} break ;
case PARAM_ANGULAR_VELOCITY : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > angular_velocity , p_value ) ;
} break ;
case PARAM_ORBIT_VELOCITY : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > orbit_velocity , p_value ) ;
} break ;
case PARAM_LINEAR_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > linear_accel , p_value ) ;
} break ;
case PARAM_RADIAL_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > radial_accel , p_value ) ;
} break ;
case PARAM_TANGENTIAL_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > tangent_accel , p_value ) ;
} break ;
case PARAM_DAMPING : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > damping , p_value ) ;
} break ;
case PARAM_ANGLE : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > initial_angle , p_value ) ;
} break ;
case PARAM_SCALE : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > scale , p_value ) ;
} break ;
case PARAM_HUE_VARIATION : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > hue_variation , p_value ) ;
} break ;
case PARAM_ANIM_SPEED : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > anim_speed , p_value ) ;
} break ;
case PARAM_ANIM_OFFSET : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > anim_offset , p_value ) ;
} break ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
}
float ParticlesMaterial : : get_param ( Parameter p_param ) const {
ERR_FAIL_INDEX_V ( p_param , PARAM_MAX , 0 ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return parameters [ p_param ] ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_param_randomness ( Parameter p_param , float p_value ) {
ERR_FAIL_INDEX ( p_param , PARAM_MAX ) ;
randomness [ p_param ] = p_value ;
switch ( p_param ) {
case PARAM_INITIAL_LINEAR_VELOCITY : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > initial_linear_velocity_random , p_value ) ;
} break ;
case PARAM_ANGULAR_VELOCITY : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > angular_velocity_random , p_value ) ;
} break ;
case PARAM_ORBIT_VELOCITY : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > orbit_velocity_random , p_value ) ;
} break ;
case PARAM_LINEAR_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > linear_accel_random , p_value ) ;
} break ;
case PARAM_RADIAL_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > radial_accel_random , p_value ) ;
} break ;
case PARAM_TANGENTIAL_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > tangent_accel_random , p_value ) ;
} break ;
case PARAM_DAMPING : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > damping_random , p_value ) ;
} break ;
case PARAM_ANGLE : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > initial_angle_random , p_value ) ;
} break ;
case PARAM_SCALE : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > scale_random , p_value ) ;
} break ;
case PARAM_HUE_VARIATION : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > hue_variation_random , p_value ) ;
} break ;
case PARAM_ANIM_SPEED : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > anim_speed_random , p_value ) ;
} break ;
case PARAM_ANIM_OFFSET : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > anim_offset_random , p_value ) ;
} break ;
}
}
float ParticlesMaterial : : get_param_randomness ( Parameter p_param ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
ERR_FAIL_INDEX_V ( p_param , PARAM_MAX , 0 ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return randomness [ p_param ] ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
static void _adjust_curve_range ( const Ref < Texture > & p_texture , float p_min , float p_max ) {
2014-02-10 02:10:30 +01:00
2017-06-26 23:39:35 +02:00
Ref < CurveTexture > curve_tex = p_texture ;
if ( ! curve_tex . is_valid ( ) )
2017-04-07 04:36:37 +02:00
return ;
2014-02-10 02:10:30 +01:00
2017-06-26 23:39:35 +02:00
curve_tex - > ensure_default_setup ( p_min , p_max ) ;
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_param_texture ( Parameter p_param , const Ref < Texture > & p_texture ) {
ERR_FAIL_INDEX ( p_param , PARAM_MAX ) ;
tex_parameters [ p_param ] = p_texture ;
switch ( p_param ) {
case PARAM_INITIAL_LINEAR_VELOCITY : {
//do none for this one
} break ;
case PARAM_ANGULAR_VELOCITY : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > angular_velocity_texture , p_texture ) ;
_adjust_curve_range ( p_texture , - 360 , 360 ) ;
} break ;
case PARAM_ORBIT_VELOCITY : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > orbit_velocity_texture , p_texture ) ;
_adjust_curve_range ( p_texture , - 500 , 500 ) ;
} break ;
case PARAM_LINEAR_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > linear_accel_texture , p_texture ) ;
_adjust_curve_range ( p_texture , - 200 , 200 ) ;
} break ;
case PARAM_RADIAL_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > radial_accel_texture , p_texture ) ;
_adjust_curve_range ( p_texture , - 200 , 200 ) ;
} break ;
case PARAM_TANGENTIAL_ACCEL : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > tangent_accel_texture , p_texture ) ;
_adjust_curve_range ( p_texture , - 200 , 200 ) ;
} break ;
case PARAM_DAMPING : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > damping_texture , p_texture ) ;
_adjust_curve_range ( p_texture , 0 , 100 ) ;
} break ;
case PARAM_ANGLE : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > angle_texture , p_texture ) ;
_adjust_curve_range ( p_texture , - 360 , 360 ) ;
} break ;
case PARAM_SCALE : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > scale_texture , p_texture ) ;
2017-04-30 16:27:10 +02:00
Ref < CurveTexture > curve_tex = p_texture ;
if ( curve_tex . is_valid ( ) ) {
curve_tex - > ensure_default_setup ( ) ;
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
} break ;
case PARAM_HUE_VARIATION : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > hue_variation_texture , p_texture ) ;
_adjust_curve_range ( p_texture , - 1 , 1 ) ;
} break ;
case PARAM_ANIM_SPEED : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > anim_speed_texture , p_texture ) ;
_adjust_curve_range ( p_texture , 0 , 200 ) ;
} break ;
case PARAM_ANIM_OFFSET : {
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > anim_offset_texture , p_texture ) ;
} break ;
}
_queue_shader_change ( ) ;
}
Ref < Texture > ParticlesMaterial : : get_param_texture ( Parameter p_param ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
ERR_FAIL_INDEX_V ( p_param , PARAM_MAX , Ref < Texture > ( ) ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return tex_parameters [ p_param ] ;
2016-03-09 00:00:52 +01:00
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_color ( const Color & p_color ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > color , p_color ) ;
color = p_color ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
Color ParticlesMaterial : : get_color ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return color ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_color_ramp ( const Ref < Texture > & p_texture ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
color_ramp = p_texture ;
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > color_ramp , p_texture ) ;
_queue_shader_change ( ) ;
_change_notify ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
Ref < Texture > ParticlesMaterial : : get_color_ramp ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return color_ramp ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_flag ( Flags p_flag , bool p_enable ) {
ERR_FAIL_INDEX ( p_flag , FLAG_MAX ) ;
flags [ p_flag ] = p_enable ;
_queue_shader_change ( ) ;
2017-12-10 01:27:02 +01:00
if ( p_flag = = FLAG_DISABLE_Z ) {
2017-12-07 17:17:03 +01:00
_change_notify ( ) ;
}
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
bool ParticlesMaterial : : get_flag ( Flags p_flag ) const {
ERR_FAIL_INDEX_V ( p_flag , FLAG_MAX , false ) ;
return flags [ p_flag ] ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_emission_shape ( EmissionShape p_shape ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
emission_shape = p_shape ;
_change_notify ( ) ;
_queue_shader_change ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_emission_sphere_radius ( float p_radius ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
emission_sphere_radius = p_radius ;
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > emission_sphere_radius , p_radius ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_emission_box_extents ( Vector3 p_extents ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
emission_box_extents = p_extents ;
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > emission_box_extents , p_extents ) ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_emission_point_texture ( const Ref < Texture > & p_points ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
emission_point_texture = p_points ;
2018-02-24 09:58:17 +01:00
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > emission_texture_points , p_points ) ;
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_emission_normal_texture ( const Ref < Texture > & p_normals ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
emission_normal_texture = p_normals ;
2018-02-24 09:58:17 +01:00
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > emission_texture_normal , p_normals ) ;
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
2017-06-21 21:25:45 +02:00
void ParticlesMaterial : : set_emission_color_texture ( const Ref < Texture > & p_colors ) {
emission_color_texture = p_colors ;
2018-02-24 09:58:17 +01:00
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > emission_texture_color , p_colors ) ;
2017-06-21 21:25:45 +02:00
_queue_shader_change ( ) ;
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_emission_point_count ( int p_count ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
emission_point_count = p_count ;
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > emission_texture_point_count , p_count ) ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
ParticlesMaterial : : EmissionShape ParticlesMaterial : : get_emission_shape ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return emission_shape ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
float ParticlesMaterial : : get_emission_sphere_radius ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return emission_sphere_radius ;
}
Vector3 ParticlesMaterial : : get_emission_box_extents ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return emission_box_extents ;
}
Ref < Texture > ParticlesMaterial : : get_emission_point_texture ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return emission_point_texture ;
}
Ref < Texture > ParticlesMaterial : : get_emission_normal_texture ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return emission_normal_texture ;
}
2014-02-10 02:10:30 +01:00
2017-06-21 21:25:45 +02:00
Ref < Texture > ParticlesMaterial : : get_emission_color_texture ( ) const {
return emission_color_texture ;
}
2017-04-07 04:36:37 +02:00
int ParticlesMaterial : : get_emission_point_count ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return emission_point_count ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_trail_divisor ( int p_divisor ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
trail_divisor = p_divisor ;
2017-08-08 17:10:18 +02:00
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > trail_divisor , p_divisor ) ;
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
int ParticlesMaterial : : get_trail_divisor ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return trail_divisor ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_trail_size_modifier ( const Ref < CurveTexture > & p_trail_size_modifier ) {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
trail_size_modifier = p_trail_size_modifier ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
Ref < CurveTexture > curve = trail_size_modifier ;
if ( curve . is_valid ( ) ) {
2017-04-30 16:27:10 +02:00
curve - > ensure_default_setup ( ) ;
2014-02-10 02:10:30 +01:00
}
2018-02-24 09:58:17 +01:00
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > trail_size_modifier , curve ) ;
2017-04-07 04:36:37 +02:00
_queue_shader_change ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
Ref < CurveTexture > ParticlesMaterial : : get_trail_size_modifier ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return trail_size_modifier ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : set_trail_color_modifier ( const Ref < GradientTexture > & p_trail_color_modifier ) {
trail_color_modifier = p_trail_color_modifier ;
2018-02-24 09:58:17 +01:00
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > trail_color_modifier , p_trail_color_modifier ) ;
2017-04-07 04:36:37 +02:00
_queue_shader_change ( ) ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
Ref < GradientTexture > ParticlesMaterial : : get_trail_color_modifier ( ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
return trail_color_modifier ;
2014-02-10 02:10:30 +01:00
}
2017-04-09 03:38:11 +02:00
void ParticlesMaterial : : set_gravity ( const Vector3 & p_gravity ) {
gravity = p_gravity ;
Vector3 gset = gravity ;
if ( gset = = Vector3 ( ) ) {
gset = Vector3 ( 0 , - 0.000001 , 0 ) ; //as gravity is used as upvector in some calculations
}
VisualServer : : get_singleton ( ) - > material_set_param ( _get_material ( ) , shader_names - > gravity , gset ) ;
}
Vector3 ParticlesMaterial : : get_gravity ( ) const {
return gravity ;
}
2017-10-12 13:12:50 +02:00
RID ParticlesMaterial : : get_shader_rid ( ) const {
ERR_FAIL_COND_V ( ! shader_map . has ( current_key ) , RID ( ) ) ;
return shader_map [ current_key ] . shader ;
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : _validate_property ( PropertyInfo & property ) const {
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
if ( property . name = = " color " & & color_ramp . is_valid ( ) ) {
property . usage = 0 ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
if ( property . name = = " emission_sphere_radius " & & emission_shape ! = EMISSION_SHAPE_SPHERE ) {
property . usage = 0 ;
}
2016-03-09 00:00:52 +01:00
2017-04-07 04:36:37 +02:00
if ( property . name = = " emission_box_extents " & & emission_shape ! = EMISSION_SHAPE_BOX ) {
property . usage = 0 ;
2014-02-10 02:10:30 +01:00
}
2016-03-09 00:00:52 +01:00
2017-06-21 21:25:45 +02:00
if ( ( property . name = = " emission_point_texture " | | property . name = = " emission_color_texture " ) & & ( emission_shape < EMISSION_SHAPE_POINTS ) ) {
2017-04-07 04:36:37 +02:00
property . usage = 0 ;
}
if ( property . name = = " emission_normal_texture " & & emission_shape ! = EMISSION_SHAPE_DIRECTED_POINTS ) {
property . usage = 0 ;
}
if ( property . name = = " emission_point_count " & & ( emission_shape ! = EMISSION_SHAPE_POINTS & & emission_shape ! = EMISSION_SHAPE_DIRECTED_POINTS ) ) {
property . usage = 0 ;
}
2017-12-07 17:17:03 +01:00
if ( property . name . begins_with ( " orbit_ " ) & & ! flags [ FLAG_DISABLE_Z ] ) {
2017-12-10 01:27:02 +01:00
property . usage = 0 ;
2017-12-07 17:17:03 +01:00
}
2014-02-10 02:10:30 +01:00
}
2017-12-06 23:43:22 +01:00
Shader : : Mode ParticlesMaterial : : get_shader_mode ( ) const {
return Shader : : MODE_PARTICLES ;
}
2017-04-07 04:36:37 +02:00
void ParticlesMaterial : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_spread " , " degrees " ) , & ParticlesMaterial : : set_spread ) ;
ClassDB : : bind_method ( D_METHOD ( " get_spread " ) , & ParticlesMaterial : : get_spread ) ;
ClassDB : : bind_method ( D_METHOD ( " set_flatness " , " amount " ) , & ParticlesMaterial : : set_flatness ) ;
ClassDB : : bind_method ( D_METHOD ( " get_flatness " ) , & ParticlesMaterial : : get_flatness ) ;
ClassDB : : bind_method ( D_METHOD ( " set_param " , " param " , " value " ) , & ParticlesMaterial : : set_param ) ;
ClassDB : : bind_method ( D_METHOD ( " get_param " , " param " ) , & ParticlesMaterial : : get_param ) ;
ClassDB : : bind_method ( D_METHOD ( " set_param_randomness " , " param " , " randomness " ) , & ParticlesMaterial : : set_param_randomness ) ;
ClassDB : : bind_method ( D_METHOD ( " get_param_randomness " , " param " ) , & ParticlesMaterial : : get_param_randomness ) ;
ClassDB : : bind_method ( D_METHOD ( " set_param_texture " , " param " , " texture " ) , & ParticlesMaterial : : set_param_texture ) ;
ClassDB : : bind_method ( D_METHOD ( " get_param_texture " , " param " ) , & ParticlesMaterial : : get_param_texture ) ;
ClassDB : : bind_method ( D_METHOD ( " set_color " , " color " ) , & ParticlesMaterial : : set_color ) ;
ClassDB : : bind_method ( D_METHOD ( " get_color " ) , & ParticlesMaterial : : get_color ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_color_ramp " , " ramp " ) , & ParticlesMaterial : : set_color_ramp ) ;
ClassDB : : bind_method ( D_METHOD ( " get_color_ramp " ) , & ParticlesMaterial : : get_color_ramp ) ;
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_flag " , " flag " , " enable " ) , & ParticlesMaterial : : set_flag ) ;
ClassDB : : bind_method ( D_METHOD ( " get_flag " , " flag " ) , & ParticlesMaterial : : get_flag ) ;
ClassDB : : bind_method ( D_METHOD ( " set_emission_shape " , " shape " ) , & ParticlesMaterial : : set_emission_shape ) ;
ClassDB : : bind_method ( D_METHOD ( " get_emission_shape " ) , & ParticlesMaterial : : get_emission_shape ) ;
ClassDB : : bind_method ( D_METHOD ( " set_emission_sphere_radius " , " radius " ) , & ParticlesMaterial : : set_emission_sphere_radius ) ;
ClassDB : : bind_method ( D_METHOD ( " get_emission_sphere_radius " ) , & ParticlesMaterial : : get_emission_sphere_radius ) ;
ClassDB : : bind_method ( D_METHOD ( " set_emission_box_extents " , " extents " ) , & ParticlesMaterial : : set_emission_box_extents ) ;
ClassDB : : bind_method ( D_METHOD ( " get_emission_box_extents " ) , & ParticlesMaterial : : get_emission_box_extents ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_emission_point_texture " , " texture " ) , & ParticlesMaterial : : set_emission_point_texture ) ;
ClassDB : : bind_method ( D_METHOD ( " get_emission_point_texture " ) , & ParticlesMaterial : : get_emission_point_texture ) ;
2017-04-07 04:36:37 +02:00
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_emission_normal_texture " , " texture " ) , & ParticlesMaterial : : set_emission_normal_texture ) ;
ClassDB : : bind_method ( D_METHOD ( " get_emission_normal_texture " ) , & ParticlesMaterial : : get_emission_normal_texture ) ;
2017-04-07 04:36:37 +02:00
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_emission_color_texture " , " texture " ) , & ParticlesMaterial : : set_emission_color_texture ) ;
ClassDB : : bind_method ( D_METHOD ( " get_emission_color_texture " ) , & ParticlesMaterial : : get_emission_color_texture ) ;
2017-06-21 21:25:45 +02:00
2017-04-07 04:36:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_emission_point_count " , " point_count " ) , & ParticlesMaterial : : set_emission_point_count ) ;
ClassDB : : bind_method ( D_METHOD ( " get_emission_point_count " ) , & ParticlesMaterial : : get_emission_point_count ) ;
ClassDB : : bind_method ( D_METHOD ( " set_trail_divisor " , " divisor " ) , & ParticlesMaterial : : set_trail_divisor ) ;
ClassDB : : bind_method ( D_METHOD ( " get_trail_divisor " ) , & ParticlesMaterial : : get_trail_divisor ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_trail_size_modifier " , " texture " ) , & ParticlesMaterial : : set_trail_size_modifier ) ;
ClassDB : : bind_method ( D_METHOD ( " get_trail_size_modifier " ) , & ParticlesMaterial : : get_trail_size_modifier ) ;
2017-04-07 04:36:37 +02:00
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_trail_color_modifier " , " texture " ) , & ParticlesMaterial : : set_trail_color_modifier ) ;
ClassDB : : bind_method ( D_METHOD ( " get_trail_color_modifier " ) , & ParticlesMaterial : : get_trail_color_modifier ) ;
2017-04-07 04:36:37 +02:00
2017-04-09 03:38:11 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_gravity " ) , & ParticlesMaterial : : get_gravity ) ;
ClassDB : : bind_method ( D_METHOD ( " set_gravity " , " accel_vec " ) , & ParticlesMaterial : : set_gravity ) ;
2017-04-07 04:36:37 +02:00
ADD_GROUP ( " Trail " , " trail_ " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " trail_divisor " , PROPERTY_HINT_RANGE , " 1,1000000,1 " ) , " set_trail_divisor " , " get_trail_divisor " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " trail_size_modifier " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_trail_size_modifier " , " get_trail_size_modifier " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " trail_color_modifier " , PROPERTY_HINT_RESOURCE_TYPE , " GradientTexture " ) , " set_trail_color_modifier " , " get_trail_color_modifier " ) ;
ADD_GROUP ( " Emission Shape " , " emission_ " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " emission_shape " , PROPERTY_HINT_ENUM , " Point,Sphere,Box,Points,Directed Points " ) , " set_emission_shape " , " get_emission_shape " ) ;
2018-06-10 20:15:02 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " emission_sphere_radius " , PROPERTY_HINT_RANGE , " 0.01,128,0.01,or_greater " ) , " set_emission_sphere_radius " , " get_emission_sphere_radius " ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " emission_box_extents " ) , " set_emission_box_extents " , " get_emission_box_extents " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " emission_point_texture " , PROPERTY_HINT_RESOURCE_TYPE , " Texture " ) , " set_emission_point_texture " , " get_emission_point_texture " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " emission_normal_texture " , PROPERTY_HINT_RESOURCE_TYPE , " Texture " ) , " set_emission_normal_texture " , " get_emission_normal_texture " ) ;
2017-06-21 21:25:45 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " emission_color_texture " , PROPERTY_HINT_RESOURCE_TYPE , " Texture " ) , " set_emission_color_texture " , " get_emission_color_texture " ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " emission_point_count " , PROPERTY_HINT_RANGE , " 0,1000000,1 " ) , " set_emission_point_count " , " get_emission_point_count " ) ;
ADD_GROUP ( " Flags " , " flag_ " ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " flag_align_y " ) , " set_flag " , " get_flag " , FLAG_ALIGN_Y_TO_VELOCITY ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " flag_rotate_y " ) , " set_flag " , " get_flag " , FLAG_ROTATE_Y ) ;
2017-06-21 21:25:45 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " flag_disable_z " ) , " set_flag " , " get_flag " , FLAG_DISABLE_Z ) ;
2017-04-07 04:36:37 +02:00
ADD_GROUP ( " Spread " , " " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " spread " , PROPERTY_HINT_RANGE , " 0,180,0.01 " ) , " set_spread " , " get_spread " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " flatness " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_flatness " , " get_flatness " ) ;
2017-04-09 03:38:11 +02:00
ADD_GROUP ( " Gravity " , " " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " gravity " ) , " set_gravity " , " get_gravity " ) ;
2017-04-07 04:36:37 +02:00
ADD_GROUP ( " Initial Velocity " , " initial_ " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " initial_velocity " , PROPERTY_HINT_RANGE , " 0,1000,0.01,or_greater " ) , " set_param " , " get_param " , PARAM_INITIAL_LINEAR_VELOCITY ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " initial_velocity_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_INITIAL_LINEAR_VELOCITY ) ;
ADD_GROUP ( " Angular Velocity " , " angular_ " ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " angular_velocity " , PROPERTY_HINT_RANGE , " -360,360,0.01 " ) , " set_param " , " get_param " , PARAM_ANGULAR_VELOCITY ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " angular_velocity_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_ANGULAR_VELOCITY ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " angular_velocity_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_ANGULAR_VELOCITY ) ;
ADD_GROUP ( " Orbit Velocity " , " orbit_ " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " orbit_velocity " , PROPERTY_HINT_RANGE , " -1000,1000,0.01,or_lesser,or_greater " ) , " set_param " , " get_param " , PARAM_ORBIT_VELOCITY ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " orbit_velocity_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_ORBIT_VELOCITY ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " orbit_velocity_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_ORBIT_VELOCITY ) ;
ADD_GROUP ( " Linear Accel " , " linear_ " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " linear_accel " , PROPERTY_HINT_RANGE , " -100,100,0.01,or_lesser,or_greater " ) , " set_param " , " get_param " , PARAM_LINEAR_ACCEL ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " linear_accel_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_LINEAR_ACCEL ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " linear_accel_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_LINEAR_ACCEL ) ;
ADD_GROUP ( " Radial Accel " , " radial_ " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " radial_accel " , PROPERTY_HINT_RANGE , " -100,100,0.01,or_lesser,or_greater " ) , " set_param " , " get_param " , PARAM_RADIAL_ACCEL ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " radial_accel_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_RADIAL_ACCEL ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " radial_accel_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_RADIAL_ACCEL ) ;
ADD_GROUP ( " Tangential Accel " , " tangential_ " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " tangential_accel " , PROPERTY_HINT_RANGE , " -100,100,0.01,or_lesser,or_greater " ) , " set_param " , " get_param " , PARAM_TANGENTIAL_ACCEL ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " tangential_accel_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_TANGENTIAL_ACCEL ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " tangential_accel_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_TANGENTIAL_ACCEL ) ;
ADD_GROUP ( " Damping " , " " ) ;
2018-06-10 20:15:02 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " damping " , PROPERTY_HINT_RANGE , " 0,100,0.01,or_greater " ) , " set_param " , " get_param " , PARAM_DAMPING ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " damping_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_DAMPING ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " damping_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_DAMPING ) ;
ADD_GROUP ( " Angle " , " " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " angle " , PROPERTY_HINT_RANGE , " -720,720,0.1,or_lesser,or_greater " ) , " set_param " , " get_param " , PARAM_ANGLE ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " angle_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_ANGLE ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " angle_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_ANGLE ) ;
ADD_GROUP ( " Scale " , " " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " scale " , PROPERTY_HINT_RANGE , " 0,1000,0.01,or_greater " ) , " set_param " , " get_param " , PARAM_SCALE ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " scale_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_SCALE ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " scale_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_SCALE ) ;
ADD_GROUP ( " Color " , " " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : COLOR , " color " ) , " set_color " , " get_color " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " color_ramp " , PROPERTY_HINT_RESOURCE_TYPE , " GradientTexture " ) , " set_color_ramp " , " get_color_ramp " ) ;
ADD_GROUP ( " Hue Variation " , " hue_ " ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " hue_variation " , PROPERTY_HINT_RANGE , " -1,1,0.1 " ) , " set_param " , " get_param " , PARAM_HUE_VARIATION ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " hue_variation_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_HUE_VARIATION ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " hue_variation_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_HUE_VARIATION ) ;
ADD_GROUP ( " Animation " , " anim_ " ) ;
2018-05-16 14:13:41 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " anim_speed " , PROPERTY_HINT_RANGE , " 0,128,0.01,or_greater " ) , " set_param " , " get_param " , PARAM_ANIM_SPEED ) ;
2017-04-07 04:36:37 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " anim_speed_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_ANIM_SPEED ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " anim_speed_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_ANIM_SPEED ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " anim_offset " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param " , " get_param " , PARAM_ANIM_OFFSET ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " anim_offset_random " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_param_randomness " , " get_param_randomness " , PARAM_ANIM_OFFSET ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : OBJECT , " anim_offset_curve " , PROPERTY_HINT_RESOURCE_TYPE , " CurveTexture " ) , " set_param_texture " , " get_param_texture " , PARAM_ANIM_OFFSET ) ;
2017-06-21 21:25:45 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " anim_loop " ) , " set_flag " , " get_flag " , FLAG_ANIM_LOOP ) ;
2017-04-07 04:36:37 +02:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( PARAM_INITIAL_LINEAR_VELOCITY ) ;
BIND_ENUM_CONSTANT ( PARAM_ANGULAR_VELOCITY ) ;
BIND_ENUM_CONSTANT ( PARAM_ORBIT_VELOCITY ) ;
BIND_ENUM_CONSTANT ( PARAM_LINEAR_ACCEL ) ;
BIND_ENUM_CONSTANT ( PARAM_RADIAL_ACCEL ) ;
BIND_ENUM_CONSTANT ( PARAM_TANGENTIAL_ACCEL ) ;
BIND_ENUM_CONSTANT ( PARAM_DAMPING ) ;
BIND_ENUM_CONSTANT ( PARAM_ANGLE ) ;
BIND_ENUM_CONSTANT ( PARAM_SCALE ) ;
BIND_ENUM_CONSTANT ( PARAM_HUE_VARIATION ) ;
BIND_ENUM_CONSTANT ( PARAM_ANIM_SPEED ) ;
BIND_ENUM_CONSTANT ( PARAM_ANIM_OFFSET ) ;
BIND_ENUM_CONSTANT ( PARAM_MAX ) ;
BIND_ENUM_CONSTANT ( FLAG_ALIGN_Y_TO_VELOCITY ) ;
BIND_ENUM_CONSTANT ( FLAG_ROTATE_Y ) ;
BIND_ENUM_CONSTANT ( FLAG_MAX ) ;
BIND_ENUM_CONSTANT ( EMISSION_SHAPE_POINT ) ;
BIND_ENUM_CONSTANT ( EMISSION_SHAPE_SPHERE ) ;
BIND_ENUM_CONSTANT ( EMISSION_SHAPE_BOX ) ;
BIND_ENUM_CONSTANT ( EMISSION_SHAPE_POINTS ) ;
BIND_ENUM_CONSTANT ( EMISSION_SHAPE_DIRECTED_POINTS ) ;
2017-04-07 04:36:37 +02:00
}
2014-02-10 02:10:30 +01:00
2017-12-06 21:36:34 +01:00
ParticlesMaterial : : ParticlesMaterial ( ) :
element ( this ) {
2017-04-07 04:36:37 +02:00
set_spread ( 45 ) ;
set_flatness ( 0 ) ;
set_param ( PARAM_INITIAL_LINEAR_VELOCITY , 1 ) ;
set_param ( PARAM_ORBIT_VELOCITY , 0 ) ;
set_param ( PARAM_LINEAR_ACCEL , 0 ) ;
set_param ( PARAM_RADIAL_ACCEL , 0 ) ;
set_param ( PARAM_TANGENTIAL_ACCEL , 0 ) ;
set_param ( PARAM_DAMPING , 0 ) ;
set_param ( PARAM_ANGLE , 0 ) ;
set_param ( PARAM_SCALE , 1 ) ;
set_param ( PARAM_HUE_VARIATION , 0 ) ;
set_param ( PARAM_ANIM_SPEED , 0 ) ;
set_param ( PARAM_ANIM_OFFSET , 0 ) ;
set_emission_shape ( EMISSION_SHAPE_POINT ) ;
set_emission_sphere_radius ( 1 ) ;
set_emission_box_extents ( Vector3 ( 1 , 1 , 1 ) ) ;
set_trail_divisor ( 1 ) ;
2017-04-09 03:38:11 +02:00
set_gravity ( Vector3 ( 0 , - 9.8 , 0 ) ) ;
2017-04-07 04:36:37 +02:00
emission_point_count = 1 ;
for ( int i = 0 ; i < PARAM_MAX ; i + + ) {
set_param_randomness ( Parameter ( i ) , 0 ) ;
}
for ( int i = 0 ; i < FLAG_MAX ; i + + ) {
flags [ i ] = false ;
}
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
set_color ( Color ( 1 , 1 , 1 , 1 ) ) ;
current_key . key = 0 ;
current_key . invalid_key = 1 ;
_queue_shader_change ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-04-07 04:36:37 +02:00
ParticlesMaterial : : ~ ParticlesMaterial ( ) {
2018-01-11 20:03:47 +01:00
if ( material_mutex )
material_mutex - > lock ( ) ;
if ( shader_map . has ( current_key ) ) {
shader_map [ current_key ] . users - - ;
if ( shader_map [ current_key ] . users = = 0 ) {
//deallocate shader, as it's no longer in use
VS : : get_singleton ( ) - > free ( shader_map [ current_key ] . shader ) ;
shader_map . erase ( current_key ) ;
}
VS : : get_singleton ( ) - > material_set_shader ( _get_material ( ) , RID ( ) ) ;
}
if ( material_mutex )
material_mutex - > unlock ( ) ;
2017-04-07 04:36:37 +02:00
}