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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "particles.h"
#include "util.h"
#include "BLI_rand_cxx.h"
#include "FN_multi_function_common_contexts.h"
namespace FN {
MF_ParticleAttribute::MF_ParticleAttribute(const CPPType &type) : m_type(type)
{
MFSignatureBuilder signature = this->get_builder("Particle Attribute");
signature.use_element_context<ParticleAttributesContext>();
signature.single_input<std::string>("Attribute Name");
signature.single_output("Value", type);
}
void MF_ParticleAttribute::call(IndexMask mask, MFParams params, MFContext context) const
{
VirtualListRef<std::string> attribute_names = params.readonly_single_input<std::string>(
0, "Attribute Name");
GenericMutableArrayRef r_values = params.uninitialized_single_output(1, "Value");
auto context_data = context.try_find_per_element<ParticleAttributesContext>();
if (!context_data.has_value()) {
r_values.default_initialize(mask.indices());
return;
}
AttributesRef attributes = context_data->data->attributes;
MFElementContextIndices element_indices = context_data->indices;
group_indices_by_same_value(
mask, attribute_names, [&](StringRef attribute_name, IndexMask indices_with_same_name) {
Optional<GenericArrayRef> opt_array = attributes.try_get(attribute_name, m_type);
if (!opt_array.has_value()) {
r_values.default_initialize(indices_with_same_name);
return;
}
GenericArrayRef array = opt_array.value();
if (element_indices.is_direct_mapping()) {
m_type.copy_to_uninitialized_indices(
array.buffer(), r_values.buffer(), indices_with_same_name);
}
else {
for (uint i : indices_with_same_name) {
uint index = element_indices[i];
r_values.copy_in__initialized(i, array[index]);
}
}
});
}
MF_EmitterTimeInfo::MF_EmitterTimeInfo()
{
MFSignatureBuilder signature = this->get_builder("Emitter Time Info");
signature.use_global_context<EmitterTimeInfoContext>();
signature.single_output<float>("Duration");
signature.single_output<float>("Begin");
signature.single_output<float>("End");
signature.single_output<int>("Step");
}
void MF_EmitterTimeInfo::call(IndexMask mask, MFParams params, MFContext context) const
{
MutableArrayRef<float> r_durations = params.uninitialized_single_output<float>(0, "Duration");
MutableArrayRef<float> r_begins = params.uninitialized_single_output<float>(1, "Begin");
MutableArrayRef<float> r_ends = params.uninitialized_single_output<float>(2, "End");
MutableArrayRef<int> r_steps = params.uninitialized_single_output<int>(3, "Step");
auto *time_context = context.try_find_global<EmitterTimeInfoContext>();
if (time_context == nullptr) {
r_durations.fill_indices(mask, 0.0f);
r_begins.fill_indices(mask, 0.0f);
r_ends.fill_indices(mask, 0.0f);
r_steps.fill_indices(mask, 0);
}
else {
r_durations.fill_indices(mask, time_context->duration);
r_begins.fill_indices(mask, time_context->begin);
r_ends.fill_indices(mask, time_context->end);
r_steps.fill_indices(mask, time_context->step);
}
}
MF_EventFilterEndTime::MF_EventFilterEndTime()
{
MFSignatureBuilder signature = this->get_builder("Event Filter End Time");
signature.use_global_context<EventFilterEndTimeContext>();
signature.single_output<float>("End Time");
}
void MF_EventFilterEndTime::call(IndexMask mask, MFParams params, MFContext context) const
{
MutableArrayRef<float> r_end_times = params.uninitialized_single_output<float>(0, "End Time");
auto *time_context = context.try_find_global<EventFilterEndTimeContext>();
if (time_context == nullptr) {
r_end_times.fill_indices(mask, 0.0f);
}
else {
r_end_times.fill_indices(mask, time_context->end_time);
}
}
MF_EventFilterDuration::MF_EventFilterDuration()
{
MFSignatureBuilder signature = this->get_builder("Event Filter Duration");
signature.use_element_context<EventFilterDurationsContext>();
signature.single_output<float>("Duration");
}
void MF_EventFilterDuration::call(IndexMask mask, MFParams params, MFContext context) const
{
MutableArrayRef<float> r_durations = params.uninitialized_single_output<float>(0, "Duration");
auto duration_context = context.try_find_per_element<EventFilterDurationsContext>();
if (duration_context.has_value()) {
for (uint i : mask) {
uint index = duration_context->indices[i];
r_durations[i] = duration_context->data->durations[index];
}
}
else {
r_durations.fill_indices(mask, 0.0f);
}
}
} // namespace FN
|