@@ -422,10 +422,36 @@ namespace particle
422422 p_pos = part->pos ;
423423 }
424424
425- if (vm_vec_dot_to_point (&Eye_matrix.vec .fvec , &Eye_position, &p_pos) <= 0 .0f )
425+ bool part_has_length = part->length != 0 .0f ;
426+
427+ if (!part_has_length && vm_vec_dot_to_point (&Eye_matrix.vec .fvec , &Eye_position, &p_pos) <= 0 .0f )
426428 {
427429 return false ;
428430 }
431+
432+ const auto & source_effect = part->parent_effect .getParticleEffect ();
433+
434+ // For anything apart from the velocity curve, "Post-Curves Velocity" is well defined. This is needed to facilitate complex but common particle scaling and appearance curves.
435+ const auto & curve_input = std::forward_as_tuple (*part,
436+ vm_vec_mag_quick (&part->velocity ) * source_effect.m_lifetime_curves .get_output (ParticleEffect::ParticleLifetimeCurvesOutput::VELOCITY_MULT, std::forward_as_tuple (*part, vm_vec_mag_quick (&part->velocity ))));
437+
438+ vec3d p1 = vmd_x_vector;
439+
440+ if (part_has_length) {
441+ vm_vec_copy_normalize_safe (&p1, &part->velocity );
442+ if (part->attached_objnum >= 0 ) {
443+ vm_vec_unrotate (&p1, &p1, &Objects[part->attached_objnum ].orient );
444+ }
445+ p1 *= part->length * source_effect.m_lifetime_curves .get_output (ParticleEffect::ParticleLifetimeCurvesOutput::LENGTH_MULT, curve_input);
446+ p1 += p_pos;
447+
448+ float dot0 = vm_vec_dot_to_point (&Eye_matrix.vec .fvec , &Eye_position, &p_pos);
449+ float dot1 = vm_vec_dot_to_point (&Eye_matrix.vec .fvec , &Eye_position, &p1);
450+
451+ if (dot0 <= 0 .0f && dot1 <= 0 .0f ) {
452+ return false ;
453+ }
454+ }
429455
430456 // calculate the alpha to draw at
431457 auto alpha = get_current_alpha (&p_pos, part->radius );
@@ -441,17 +467,19 @@ namespace particle
441467
442468 if (flags)
443469 {
444- return false ;
470+ if (part_has_length) {
471+ vertex pos2;
472+ auto flags2 = g3_rotate_vertex (&pos2, &p1);
473+ if (flags & flags2) {
474+ return false ;
475+ }
476+ } else {
477+ return false ;
478+ }
445479 }
446480
447481 g3_transfer_vertex (&pos, &p_pos);
448482
449- const auto & source_effect = part->parent_effect .getParticleEffect ();
450-
451- // For anything apart from the velocity curve, "Post-Curves Velocity" is well defined. This is needed to facilitate complex but common particle scaling and appearance curves.
452- const auto & curve_input = std::forward_as_tuple (*part,
453- vm_vec_mag_quick (&part->velocity ) * source_effect.m_lifetime_curves .get_output (ParticleEffect::ParticleLifetimeCurvesOutput::ANIM_STATE, std::forward_as_tuple (*part, vm_vec_mag_quick (&part->velocity ))));
454-
455483 // figure out which frame we should be using
456484 int framenum;
457485 int cur_frame;
@@ -475,17 +503,8 @@ namespace particle
475503
476504 float radius = part->radius * source_effect.m_lifetime_curves .get_output (ParticleEffect::ParticleLifetimeCurvesOutput::RADIUS_MULT, curve_input);
477505
478- if (part-> length != 0 . 0f ) {
506+ if (part_has_length ) {
479507 vec3d p0 = p_pos;
480-
481- vec3d p1;
482- vm_vec_copy_normalize_safe (&p1, &part->velocity );
483- if (part->attached_objnum >= 0 ) {
484- vm_vec_unrotate (&p1, &p1, &Objects[part->attached_objnum ].orient );
485- }
486- p1 *= part->length * source_effect.m_lifetime_curves .get_output (ParticleEffect::ParticleLifetimeCurvesOutput::LENGTH_MULT, curve_input);
487- p1 += p_pos;
488-
489508 batching_add_laser (framenum + cur_frame, &p0, radius, &p1, radius);
490509 }
491510 else {
0 commit comments