|
15 | 15 | #include "debugconsole/console.h" |
16 | 16 | #include "globalincs/systemvars.h" |
17 | 17 | #include "graphics/2d.h" |
| 18 | +#include "lighting/lighting.h" |
18 | 19 | #include "math/curve.h" |
19 | 20 | #include "render/3d.h" |
20 | 21 | #include "render/batching.h" |
@@ -192,7 +193,7 @@ namespace particle |
192 | 193 | * @param part The particle to process for movement |
193 | 194 | * @return @c true if the particle has expired and should be removed, @c false otherwise |
194 | 195 | */ |
195 | | - static bool move_particle(float frametime, particle* part) { |
| 196 | + bool move_particle(float frametime, particle* part) { |
196 | 197 | if (part->age == 0.0f) |
197 | 198 | { |
198 | 199 | part->age = 0.00001f; |
@@ -232,11 +233,84 @@ namespace particle |
232 | 233 |
|
233 | 234 | const auto& source_effect = part->parent_effect.getParticleEffect(); |
234 | 235 |
|
235 | | - float vel_scalar = source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::VELOCITY_MULT, std::forward_as_tuple(*part, vm_vec_mag_quick(&part->velocity)) ); |
| 236 | + float part_velocity = vm_vec_mag_quick(&part->velocity); |
| 237 | + float vel_scalar = source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::VELOCITY_MULT, std::forward_as_tuple(*part, part_velocity) ); |
236 | 238 |
|
237 | 239 | // move as a regular particle |
| 240 | + vec3d prev_pos = part->pos; |
238 | 241 | part->pos += (part->velocity * vel_scalar) * frametime; |
239 | 242 |
|
| 243 | + const auto& curve_input = std::forward_as_tuple(*part, part_velocity * vel_scalar); |
| 244 | + |
| 245 | + if (source_effect.m_light_source) { |
| 246 | + const auto& light_source = *source_effect.m_light_source; |
| 247 | + |
| 248 | + vec3d p_pos; |
| 249 | + if (part->attached_objnum >= 0) |
| 250 | + { |
| 251 | + vm_vec_unrotate(&p_pos, &part->pos, &Objects[part->attached_objnum].orient); |
| 252 | + vm_vec_add2(&p_pos, &Objects[part->attached_objnum].pos); |
| 253 | + } |
| 254 | + else |
| 255 | + { |
| 256 | + p_pos = part->pos; |
| 257 | + } |
| 258 | + |
| 259 | + float light_radius = light_source.light_radius * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LIGHT_RADIUS_MULT, curve_input); |
| 260 | + float source_radius = light_source.source_radius * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LIGHT_SOURCE_RADIUS_MULT, curve_input); |
| 261 | + float intensity = light_source.intensity * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LIGHT_INTENSITY_MULT, curve_input); |
| 262 | + float r = light_source.r * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LIGHT_R_MULT, curve_input); |
| 263 | + float g = light_source.g * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LIGHT_G_MULT, curve_input); |
| 264 | + float b = light_source.b * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LIGHT_B_MULT, curve_input); |
| 265 | + |
| 266 | + switch (light_source.light_source_mode) { |
| 267 | + case ParticleEffect::LightInformation::LightSourceMode::POINT: |
| 268 | + light_add_point(&p_pos, light_radius, light_radius, intensity, r, g, b, source_radius); |
| 269 | + break; |
| 270 | + case ParticleEffect::LightInformation::LightSourceMode::TO_LAST_POS: { |
| 271 | + vec3d p_prev_pos; |
| 272 | + if (part->attached_objnum >= 0) |
| 273 | + { |
| 274 | + vm_vec_unrotate(&p_prev_pos, &prev_pos, &Objects[part->attached_objnum].last_orient); |
| 275 | + vm_vec_add2(&p_prev_pos, &Objects[part->attached_objnum].last_pos); |
| 276 | + } |
| 277 | + else |
| 278 | + { |
| 279 | + p_prev_pos = prev_pos; |
| 280 | + } |
| 281 | + light_add_tube(&p_prev_pos, &p_pos, light_radius, light_radius, intensity, r, g, b, source_radius); |
| 282 | + } |
| 283 | + break; |
| 284 | + case ParticleEffect::LightInformation::LightSourceMode::AS_PARTICLE: |
| 285 | + if (part->length != 0.0f) { |
| 286 | + vec3d p1; |
| 287 | + vm_vec_copy_normalize_safe(&p1, &part->velocity); |
| 288 | + if (part->attached_objnum >= 0) { |
| 289 | + vm_vec_unrotate(&p1, &p1, &Objects[part->attached_objnum].orient); |
| 290 | + } |
| 291 | + p1 *= part->length * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LENGTH_MULT, curve_input); |
| 292 | + p1 += p_pos; |
| 293 | + light_add_tube(&p_pos, &p1, light_radius, light_radius, intensity, r, g, b, source_radius); |
| 294 | + } |
| 295 | + else { |
| 296 | + light_add_point(&p_pos, light_radius, light_radius, intensity, r, g, b, source_radius); |
| 297 | + } |
| 298 | + break; |
| 299 | + case ParticleEffect::LightInformation::LightSourceMode::CONE: { |
| 300 | + float cone_angle = light_source.cone_angle * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LIGHT_CONE_ANGLE_MULT, curve_input); |
| 301 | + float cone_inner_angle = light_source.cone_inner_angle * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::LIGHT_CONE_INNER_ANGLE_MULT, curve_input); |
| 302 | + vec3d p1; |
| 303 | + vm_vec_copy_normalize_safe(&p1, &part->velocity); |
| 304 | + if (part->attached_objnum >= 0) { |
| 305 | + vm_vec_unrotate(&p1, &p1, &Objects[part->attached_objnum].orient); |
| 306 | + } |
| 307 | + |
| 308 | + light_add_cone(&p_pos, &p1, cone_angle, cone_inner_angle, false, light_radius, light_radius, intensity, r, g, b, source_radius); |
| 309 | + } |
| 310 | + break; |
| 311 | + } |
| 312 | + } |
| 313 | + |
240 | 314 | return false; |
241 | 315 | } |
242 | 316 |
|
@@ -370,7 +444,7 @@ namespace particle |
370 | 444 |
|
371 | 445 | Assert( (cur_frame < part->nframes) || (part->nframes == 0 && cur_frame == 0) ); |
372 | 446 |
|
373 | | - float radius = part->radius * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::VELOCITY_MULT, curve_input); |
| 447 | + float radius = part->radius * source_effect.m_lifetime_curves.get_output(ParticleEffect::ParticleLifetimeCurvesOutput::RADIUS_MULT, curve_input); |
374 | 448 |
|
375 | 449 | if (part->length != 0.0f) { |
376 | 450 | vec3d p0 = p_pos; |
|
0 commit comments