| 473 | } |
| 474 | |
| 475 | void Renderer::PrepareParticles(RenderView& view) |
| 476 | { |
| 477 | for (int i = 0; i < ParticleNodeOffsetIDs::NodeMax; i++) |
| 478 | NodeOffsets[i].itemNumber = NO_VALUE; |
| 479 | |
| 480 | for (auto& particle : Particles) |
| 481 | { |
| 482 | if (!particle.on) |
| 483 | continue; |
| 484 | |
| 485 | if (particle.DisableInterpolation) |
| 486 | { |
| 487 | particle.DisableInterpolation = false; |
| 488 | particle.StoreInterpolationData(); |
| 489 | } |
| 490 | |
| 491 | if (particle.flags & SP_DEF) |
| 492 | { |
| 493 | auto pos = Vector3::Lerp( |
| 494 | Vector3(particle.PrevX, particle.PrevY, particle.PrevZ), |
| 495 | Vector3(particle.x, particle.y, particle.z), |
| 496 | GetInterpolationFactor()); |
| 497 | |
| 498 | if (particle.flags & SP_FX) |
| 499 | { |
| 500 | const auto& fx = EffectList[particle.fxObj]; |
| 501 | |
| 502 | auto& newEffect = _effects[particle.fxObj]; |
| 503 | |
| 504 | newEffect.Translation = Matrix::CreateTranslation(fx.pos.Position.ToVector3()); |
| 505 | newEffect.Rotation = fx.pos.Orientation.ToRotationMatrix(); |
| 506 | newEffect.Scale = Matrix::CreateScale(1.0f); |
| 507 | newEffect.World = newEffect.Rotation * newEffect.Translation; |
| 508 | newEffect.ObjectID = fx.objectNumber; |
| 509 | newEffect.RoomNumber = fx.roomNumber; |
| 510 | newEffect.Position = fx.pos.Position.ToVector3(); |
| 511 | |
| 512 | newEffect.InterpolatedPosition = Vector3::Lerp(newEffect.PrevPosition, newEffect.Position, GetInterpolationFactor()); |
| 513 | newEffect.InterpolatedTranslation = Matrix::Lerp(newEffect.PrevTranslation, newEffect.Translation, GetInterpolationFactor()); |
| 514 | newEffect.InterpolatedRotation = Matrix::Lerp(newEffect.InterpolatedRotation, newEffect.Rotation, GetInterpolationFactor()); |
| 515 | newEffect.InterpolatedWorld = Matrix::Lerp(newEffect.PrevWorld, newEffect.World, GetInterpolationFactor()); |
| 516 | newEffect.InterpolatedScale = Matrix::Lerp(newEffect.PrevScale, newEffect.Scale, GetInterpolationFactor()); |
| 517 | |
| 518 | pos += newEffect.InterpolatedPosition; |
| 519 | |
| 520 | if ((particle.sLife - particle.life) > Random::GenerateInt(8, 12)) |
| 521 | { |
| 522 | // Particle becomes autonome. |
| 523 | particle.flags &= ~SP_FX; |
| 524 | |
| 525 | particle.x = particle.PrevX = pos.x; |
| 526 | particle.y = particle.PrevY = pos.y; |
| 527 | particle.z = particle.PrevZ = pos.z; |
| 528 | } |
| 529 | } |
| 530 | else if (!(particle.flags & SP_ITEM)) |
| 531 | { |
| 532 | // NOTE: pos already set previously. |
nothing calls this directly
no test coverage detected