1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
#include "offset_handlers.hpp"
#include "BLI_color.h"
namespace BParticles {
using BLI::rgba_f;
void CreateTrailHandler::execute(OffsetHandlerInterface &interface)
{
auto positions = interface.attributes().get<float3>("Position");
auto position_offsets = interface.attribute_offsets().get<float3>("Position");
auto colors = interface.attributes().get<rgba_f>("Color");
ParticleFunctionEvaluator inputs{m_inputs_fn, interface.mask(), interface.attributes()};
inputs.compute();
Vector<float3> new_positions;
Vector<rgba_f> new_colors;
Vector<float> new_birth_times;
for (uint pindex : interface.mask()) {
float rate = inputs.get_single<float>("Rate", 0, pindex);
if (rate <= 0.0f) {
continue;
}
FloatInterval time_span = interface.time_span(pindex);
rgba_f color = colors[pindex];
float factor_start, factor_step;
time_span.uniform_sample_range(rate, factor_start, factor_step);
float3 total_offset = position_offsets[pindex] * interface.time_factors()[pindex];
for (float factor = factor_start; factor < 1.0f; factor += factor_step) {
float time = time_span.value_at(factor);
new_positions.append(positions[pindex] + total_offset * factor);
new_birth_times.append(time);
new_colors.append(color);
}
}
for (StringRef system_name : m_systems_to_emit) {
auto new_particles = interface.particle_allocator().request(system_name, new_positions.size());
new_particles.set<float3>("Position", new_positions);
new_particles.set<float>("Birth Time", new_birth_times);
new_particles.set<rgba_f>("Color", new_colors);
m_on_birth_action.execute_for_new_particles(new_particles, interface);
}
}
void SizeOverTimeHandler::execute(OffsetHandlerInterface &interface)
{
auto birth_times = interface.attributes().get<float>("Birth Time");
auto sizes = interface.attributes().get<float>("Size");
ParticleFunctionEvaluator inputs{m_inputs_fn, interface.mask(), interface.attributes()};
inputs.compute();
for (uint pindex : interface.mask()) {
float final_size = inputs.get_single<float>("Final Size", 0, pindex);
float final_age = inputs.get_single<float>("Final Age", 1, pindex);
FloatInterval time_span = interface.time_span(pindex);
float age = time_span.start() - birth_times[pindex];
float time_until_end = final_age - age;
if (time_until_end <= 0.0f) {
continue;
}
float factor = std::min(time_span.size() / time_until_end, 1.0f);
float new_size = final_size * factor + sizes[pindex] * (1.0f - factor);
sizes[pindex] = new_size;
}
}
void AlwaysExecuteHandler::execute(OffsetHandlerInterface &interface)
{
m_action.execute_from_offset_handler(interface);
}
} // namespace BParticles
|