OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
particlefx.cpp
Go to the documentation of this file.
1#include "particlefx.h"
2
3#include "utils/parser.h"
4#include "gothic.h"
5#include "resources.h"
6#include "utils/string_frm.h"
7
8using namespace Tempest;
9
10ParticleFx::ParticleFx(const Material& mat, const zenkit::VirtualObject& vob) {
11 dbgName = vob.visual->name;
12
13 ppsValue = -1;
14 lspPartAvg = 1000;
16 visTexColorStart = Vec3(255,255,255);
17 visTexColorEnd = Vec3(255,255,255);
18 if(auto decal = dynamic_cast<const zenkit::VisualDecal*>(vob.visual.get())) {
19 visSizeStart = Vec2(2.f*decal->dimension.x,
20 2.f*decal->dimension.y);
21 }
23
24 visMaterial = mat;
25
27
29 dirAngleElev = 90;
31 visAlphaStart = 1;
32 visAlphaEnd = 1;
33 visYawAlign = vob.sprite_camera_facing_mode==zenkit::SpriteAlignment::YAW;
34 visZBias = vob.bias!=0;
35
36 useEmittersFOR = true;
37 }
38
39ParticleFx::ParticleFx(const zenkit::IParticleEffect& src, std::string_view name)
40 :dbgName(name) {
41 ppsValue = std::max(0.f,src.pps_value);
42 ppsScaleKeys = loadArr(src.pps_scale_keys_s);
43 ppsIsLooping = src.pps_is_looping!=0;
44 ppsIsSmooth = src.pps_is_smooth!=0;
45 ppsFPS = src.pps_fps>0 ? src.pps_fps : 1.f;
46 ppsCreateEm = Gothic::inst().loadParticleFx(src.pps_create_em_s);
47 ppsCreateEmDelay = uint64_t(src.pps_create_em_delay);
48
49 shpType = loadEmitType(src.shp_type_s);
50 shpFOR = loadFrameType(src.shp_for_s);
51 shpOffsetVec = Parser::loadVec3(src.shp_offset_vec_s);
52 shpDistribType = loadDistribType(src.shp_distrib_type_s);
53 shpDistribWalkSpeed = src.shp_distrib_walk_speed;
54 shpIsVolume = src.shp_is_volume!=0;
55 shpDim = Parser::loadVec3(src.shp_dim_s);
56 shpMesh_S = src.shp_mesh_s;
57 shpMesh = Resources::loadEmiterMesh(src.shp_mesh_s);
58 shpMeshRender = src.shp_mesh_render_b!=0;
59 shpScaleKeys = loadArr(src.shp_scale_keys_s);
60 shpScaleIsLooping = src.shp_scale_is_looping!=0;
61 shpScaleIsSmooth = src.shp_scale_is_smooth!=0;
62 shpScaleFPS = src.shp_scale_fps;
63
64 dirMode = loadDirType(src.dir_mode_s);
65 dirFOR = loadFrameType(src.dir_for_s);
66 dirModeTargetFOR = loadFrameType(src.dir_mode_target_for_s);
67 dirModeTargetPos = Parser::loadVec3(src.dir_mode_target_pos_s);
68 dirAngleHead = src.dir_angle_head;
69 dirAngleHeadVar = src.dir_angle_head_var;
70 dirAngleElev = src.dir_angle_elev;
71 dirAngleElevVar = src.dir_angle_elev_var;
72
73 velAvg = src.vel_avg;
74 velVar = src.vel_var;
75 lspPartAvg = src.lsp_part_avg;
76 lspPartVar = src.lsp_part_var;
77
78 flyGravity = Parser::loadVec3(src.fly_gravity_s);
79 flyCollDet = src.fly_colldet_b!=0;
80
81 visMaterial = Material(src);
82 visOrientation = loadOrientation(src.vis_orientation_s);
83 visTexIsQuadPoly = src.vis_tex_is_quadpoly;
84 visTexAniFPS = src.vis_tex_ani_fps;
85 visTexAniIsLooping = src.vis_tex_ani_is_looping;
86 visTexColorStart = Parser::loadVec3(src.vis_tex_color_start_s);
87 visTexColorEnd = Parser::loadVec3(src.vis_tex_color_end_s);
88 visSizeStart = Parser::loadVec2(src.vis_size_start_s);
89 visSizeEndScale = src.vis_size_end_scale;
90 visAlphaStart = src.vis_alpha_start/255.f;
91 visAlphaEnd = src.vis_alpha_end/255.f;
92
93 trlFadeSpeed = src.trl_fade_speed;
94 trlTexture = loadTexture(src.trl_texture_s);
95 trlWidth = src.trl_width;
96
97 mrkFadeSpeed = src.mrk_fades_peed;
98 mrkTexture = loadTexture(src.mrkt_exture_s);
99 mrkSize = src.mrk_size;
100
101 flockMode = src.flock_mode;
102 flockStrength = src.flock_strength;
103
104 useEmittersFOR = src.use_emitters_for!=0;
105
106 timeStartEnd_S = src.time_start_end_s;
107 m_bIsAmbientPFX = src.m_bis_ambient_pfx!=0;
108
109 prefferedTime = calcPrefferedTimeSingle();
110 }
111
113 :ParticleFx(proto) {
114 shpDim = key.pfx_shpDim.value_or(shpDim);
116
117 if(key.pfx_shpScaleFPS>0)
119
122 if(!key.pfx_shpDistribType_S.empty())
123 shpDistribType = loadDistribType(key.pfx_shpDistribType_S);
124
125 if(!key.pfx_dirMode_S.empty())
126 dirMode = loadDirType(key.pfx_dirMode_S);
127
128 if(!key.pfx_dirFOR_S.empty())
129 dirFOR = loadFrameType(key.pfx_dirFOR_S);
130
131 if(!key.pfx_dirModeTargetFOR_S.empty())
132 dirModeTargetFOR = loadFrameType(key.pfx_dirModeTargetFOR_S);
133
134 if(!key.pfx_dirModeTargetPos_S.empty())
136
137 if(key.pfx_velAvg>0)
138 velAvg = key.pfx_velAvg;
139
140 if(key.pfx_lspPartAvg>0)
142
143 if(key.pfx_visAlphaStart>0)
145 }
146
148 return ppsValue<0;
149 }
150
152 return trlTexture!=nullptr && trlWidth!=0.f && trlFadeSpeed>0;
153 }
154
155uint64_t ParticleFx::maxLifetime() const {
156 return uint64_t(lspPartAvg+lspPartVar);
157 }
158
160 auto v0 = prefferedTime;
162 auto time = std::max(v0,v1);
163
164 time = std::max<uint64_t>(1,time); // sleep spell has pfx burst effect with zero life span
165 return time;
166 }
167
168float ParticleFx::maxPps() const {
169 if(ppsValue<0)
170 return 1; // permanent particles
171
172 if(ppsScaleKeys.size()==0)
173 return ppsValue;
174
175 float v = 0;
176 for(auto i:ppsScaleKeys)
177 v = std::max(i,v);
178 return v*ppsValue;
179 }
180
181float ParticleFx::shpScale(uint64_t time) const {
182 return fetchScaleKey(time,shpScaleKeys,shpScaleFPS,
184 }
185
186float ParticleFx::ppsScale(uint64_t time) const {
187 float v = fetchScaleKey(time,ppsScaleKeys,ppsFPS,ppsIsSmooth!=0,ppsIsLooping!=0);
188 if(v<0)
189 return 0.f;
190 return v;
191 }
192
193uint64_t ParticleFx::calcPrefferedTimeSingle() const {
194 uint64_t ret = calcPrefferedTimeSingle(ppsScaleKeys,ppsFPS);
195 //ret = std::max<uint64_t>(1,ret);
196 return ret;
197 }
198
199uint64_t ParticleFx::calcPrefferedTimeSingle(const KeyList& k, float fps) {
200 if(k.size()==0 || fps<=0.f)
201 return 0;
202
203 float raw = float(k.size())*1000.f/fps;
204 if(raw>float(std::numeric_limits<uint32_t>::max()))
205 return 0;
206
207 auto sec = std::max<uint64_t>(1,uint64_t(std::ceil(raw)));
208 return sec;
209 }
210
211const Tempest::Texture2d* ParticleFx::loadTexture(std::string_view src) {
212 auto view = Resources::loadTexture(src);
213 if(view==nullptr)
214 view = &Resources::fallbackBlack();
215 return view;
216 }
217
218ParticleFx::KeyList ParticleFx::loadArr(std::string_view vsrc) {
219 string_frm src(vsrc);
220 std::vector<float> v;
221
222 const char* str = src.c_str();
223 while(true) {
224 char* next=nullptr;
225 float f = std::strtof(str,&next);
226 if(str==next) {
227 return v;
228 }
229 v.push_back(f);
230 str = next;
231 }
232 }
233
234ParticleFx::EmitterType ParticleFx::loadEmitType(std::string_view src) {
235 if(src=="POINT")
236 return EmitterType::Point;
237 if(src=="LINE")
238 return EmitterType::Line;
239 if(src=="BOX")
240 return EmitterType::Box;
241 if(src=="CIRCLE")
242 return EmitterType::Circle;
243 if(src=="SPHERE")
244 return EmitterType::Sphere;
245 if(src=="MESH")
246 return EmitterType::Mesh;
247 return EmitterType::Point;
248 }
249
250ParticleFx::Frame ParticleFx::loadFrameType(std::string_view src) {
251 if(src=="OBJECT")
252 return Frame::Object;
253 if(src=="object")
254 return Frame::Node; // look like "object"(low case) is not valid token - should be interpreted differently
255 if(src=="WORLD")
256 return Frame::World;
257 return Frame::World;
258 }
259
260ParticleFx::Distribution ParticleFx::loadDistribType(std::string_view src) {
261 if(src=="RAND" || src=="RANDOM")
262 return Distribution::Rand;
263 if(src=="DIR")
264 return Distribution::Dir;
265 if(src=="UNIFORM")
267 if(src=="WALK" || src=="WALKW")
268 return Distribution::Walk;
269 return Distribution::Rand;
270 }
271
272ParticleFx::Dir ParticleFx::loadDirType(std::string_view src) {
273 if(src=="RAND")
274 return Dir::Rand;
275 if(src=="DIR")
276 return Dir::Dir;
277 if(src=="TARGET")
278 return Dir::Target;
279 return Dir::Rand;
280 }
281
282ParticleFx::Orientation ParticleFx::loadOrientation(std::string_view src) {
283 if(src=="NONE")
284 return Orientation::None;
285 if(src=="VELO")
287 if(src=="VELO3D")
289 return Orientation::None;
290 }
291
292float ParticleFx::fetchScaleKey(uint64_t time, const KeyList& keys, float fps, bool smooth, bool loop) const {
293 if(keys.size()==0)
294 return 1.f;
295
296 uint64_t timeScaled = uint64_t(fps*float(time));
297 size_t at = size_t(timeScaled/1000);
298 float alpha = float(timeScaled%1000)/1000.f;
299
300 size_t frameA = 0, frameB = 0;
301 if(loop) {
302 frameA = (at )%keys.size();
303 frameB = (at+1)%keys.size();
304 } else {
305 frameA = std::min(at, keys.size()-1);
306 frameB = std::min(at+1,keys.size()-1);
307 }
308 float k0 = keys[frameA];
309 float k1 = keys[frameB];
310 if(smooth)
311 return k0+alpha*(k1-k0);
312 if(alpha<0.5)
313 return k0; else
314 return k1;
315 }
auto loadParticleFx(std::string_view name, bool relaxed=false) -> const ParticleFx *
Definition gothic.cpp:387
static Gothic & inst()
Definition gothic.cpp:249
bool visTexIsQuadPoly
Definition particlefx.h:100
float mrkFadeSpeed
Definition particlefx.h:117
Frame shpFOR
Definition particlefx.h:67
bool useEmittersFOR
Definition particlefx.h:123
float flockStrength
Definition particlefx.h:121
const Tempest::Texture2d * trlTexture
Definition particlefx.h:112
float maxPps() const
float dirAngleHead
Definition particlefx.h:85
bool visZBias
Definition particlefx.h:110
float lspPartAvg
Definition particlefx.h:92
std::string flockMode
Definition particlefx.h:120
const Tempest::Texture2d * mrkTexture
Definition particlefx.h:116
float dirAngleElevVar
Definition particlefx.h:88
uint64_t ppsCreateEmDelay
Definition particlefx.h:64
Tempest::Vec3 visTexColorStart
Definition particlefx.h:103
const ParticleFx * ppsCreateEm
Definition particlefx.h:63
bool shpScaleIsSmooth
Definition particlefx.h:78
Material visMaterial
Definition particlefx.h:98
float shpScaleFPS
Definition particlefx.h:79
uint64_t effectPrefferedTime() const
float mrkSize
Definition particlefx.h:118
std::string timeStartEnd_S
Definition particlefx.h:125
std::string dbgName
Definition particlefx.h:56
const PfxEmitterMesh * shpMesh
Definition particlefx.h:73
float visAlphaStart
Definition particlefx.h:107
uint64_t prefferedTime
Definition particlefx.h:128
float shpDistribWalkSpeed
Definition particlefx.h:70
EmitterType shpType
Definition particlefx.h:66
Frame dirFOR
Definition particlefx.h:82
bool shpMeshRender
Definition particlefx.h:75
Tempest::Vec3 visTexColorEnd
Definition particlefx.h:104
float ppsValue
Definition particlefx.h:58
KeyList shpScaleKeys
Definition particlefx.h:76
float dirAngleHeadVar
Definition particlefx.h:86
Frame dirModeTargetFOR
Definition particlefx.h:83
ParticleFx(const Material &mat, const zenkit::VirtualObject &vob)
std::string shpMesh_S
Definition particlefx.h:74
Tempest::Vec3 flyGravity
Definition particlefx.h:95
bool isDecal() const
float visSizeEndScale
Definition particlefx.h:106
bool shpIsVolume
Definition particlefx.h:71
uint64_t maxLifetime() const
Tempest::Vec3 shpDim
Definition particlefx.h:72
bool hasTrails() const
float ppsFPS
Definition particlefx.h:62
bool visTexAniIsLooping
Definition particlefx.h:102
Tempest::Vec2 visSizeStart
Definition particlefx.h:105
float trlWidth
Definition particlefx.h:114
bool ppsIsSmooth
Definition particlefx.h:61
float velVar
Definition particlefx.h:91
KeyList ppsScaleKeys
Definition particlefx.h:59
Tempest::Vec3 shpOffsetVec
Definition particlefx.h:68
float ppsScale(uint64_t time) const
Orientation visOrientation
Definition particlefx.h:99
bool visYawAlign
Definition particlefx.h:109
bool ppsIsLooping
Definition particlefx.h:60
bool m_bIsAmbientPFX
Definition particlefx.h:126
bool shpScaleIsLooping
Definition particlefx.h:77
float shpScale(uint64_t time) const
float velAvg
Definition particlefx.h:90
float trlFadeSpeed
Definition particlefx.h:113
float visAlphaEnd
Definition particlefx.h:108
float lspPartVar
Definition particlefx.h:93
float visTexAniFPS
Definition particlefx.h:101
bool flyCollDet
Definition particlefx.h:96
Distribution shpDistribType
Definition particlefx.h:69
Tempest::Vec3 dirModeTargetPos
Definition particlefx.h:84
std::vector< float > KeyList
Definition particlefx.h:54
float dirAngleElev
Definition particlefx.h:87
static const PfxEmitterMesh * loadEmiterMesh(std::string_view name)
static const Tempest::Texture2d * loadTexture(std::string_view name, bool forceMips=false)
static const Tempest::Texture2d & fallbackBlack()
float pfx_velAvg
Definition visualfx.h:84
OptVec3 pfx_shpOffsetVec
Definition visualfx.h:78
std::string pfx_shpDistribType_S
Definition visualfx.h:79
std::string pfx_dirModeTargetFOR_S
Definition visualfx.h:82
std::string pfx_dirFOR_S
Definition visualfx.h:81
float pfx_lspPartAvg
Definition visualfx.h:85
OptVec3 pfx_shpDim
Definition visualfx.h:74
bool pfx_shpIsVolumeChg
Definition visualfx.h:75
float pfx_shpScaleFPS
Definition visualfx.h:76
std::string pfx_dirModeTargetPos_S
Definition visualfx.h:83
float pfx_shpDistribWalkSpeed
Definition visualfx.h:77
float pfx_visAlphaStart
Definition visualfx.h:86
std::string pfx_dirMode_S
Definition visualfx.h:80
Tempest::Vec3 loadVec3(std::string_view src)
Definition parser.cpp:24
Tempest::Vec2 loadVec2(std::string_view src)
Definition parser.cpp:6