1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "BsParticleDistribution.h"
4
5namespace bs
6{
7 template <class T>
8 void addToVector(const T& val, Vector<float>& output)
9 {
10 output.push_back(val);
11 }
12
13 template <>
14 void addToVector(const Vector3& val, Vector<float>& output)
15 {
16 output.push_back(val.x);
17 output.push_back(val.y);
18 output.push_back(val.z);
19 }
20
21 template <>
22 void addToVector(const Vector2& val, Vector<float>& output)
23 {
24 output.push_back(val.x);
25 output.push_back(val.y);
26 }
27
28 template <>
29 void addToVector(const Color& val, Vector<float>& output)
30 {
31 output.push_back(val.r);
32 output.push_back(val.g);
33 output.push_back(val.b);
34 output.push_back(val.a);
35 }
36
37 LookupTable ColorDistribution::toLookupTable(UINT32 numSamples, bool ignoreRange) const
38 {
39 numSamples = std::max(1U, numSamples);
40
41 Vector<float> values;
42 float minT = 0.0f;
43 float maxT = 1.0f;
44
45 const bool useRange = (mType == PDT_RandomRange || mType == PDT_RandomCurveRange) && !ignoreRange;
46
47 switch (mType)
48 {
49 default:
50 case PDT_Constant:
51 case PDT_RandomRange:
52 {
53 addToVector(getMinConstant(), values);
54
55 if(useRange)
56 addToVector(getMaxConstant(), values);
57 }
58 break;
59 case PDT_Curve:
60 case PDT_RandomCurveRange:
61 {
62 const std::pair<float, float> minCurveRange = mMinGradient.getTimeRange();
63 minT = minCurveRange.first;
64 maxT = minCurveRange.second;
65
66 if(useRange)
67 {
68 const std::pair<float, float> maxCurveRange = mMaxGradient.getTimeRange();
69 minT = std::min(minT, maxCurveRange.first);
70 maxT = std::max(maxT, maxCurveRange.second);
71 }
72
73 float sampleInterval = 0.0f;
74 if(numSamples > 1)
75 sampleInterval = (maxT - minT) / (numSamples - 1);
76
77 float t = minT;
78 for(UINT32 i = 0; i < numSamples; i++)
79 {
80 addToVector(Color::fromRGBA(mMinGradient.evaluate(t)), values);
81
82 if(useRange)
83 addToVector(Color::fromRGBA(mMaxGradient.evaluate(t)), values);
84
85 t += sampleInterval;
86 }
87 }
88 }
89
90 return LookupTable(std::move(values), minT, maxT, sizeof(Color) / sizeof(float));
91 }
92
93 template <class T>
94 LookupTable TDistribution<T>::toLookupTable(UINT32 numSamples, bool ignoreRange) const
95 {
96 numSamples = std::max(1U, numSamples);
97
98 Vector<float> values;
99 float minT = 0.0f;
100 float maxT = 1.0f;
101
102 const bool useRange = (mType == PDT_RandomRange || mType == PDT_RandomCurveRange) && !ignoreRange;
103
104 switch (mType)
105 {
106 default:
107 case PDT_Constant:
108 case PDT_RandomRange:
109 addToVector(getMinConstant(), values);
110
111 if(useRange)
112 addToVector(getMaxConstant(), values);
113 break;
114 case PDT_Curve:
115 case PDT_RandomCurveRange:
116 {
117 const std::pair<float, float> minCurveRange = mMinCurve.getTimeRange();
118 minT = minCurveRange.first;
119 maxT = minCurveRange.second;
120
121 if(useRange)
122 {
123 const std::pair<float, float> maxCurveRange = mMaxCurve.getTimeRange();
124 minT = std::min(minT, maxCurveRange.first);
125 maxT = std::max(maxT, maxCurveRange.second);
126 }
127
128 float sampleInterval = 0.0f;
129 if(numSamples > 1)
130 sampleInterval = (maxT - minT) / (numSamples - 1);
131
132 float t = minT;
133 for(UINT32 i = 0; i < numSamples; i++)
134 {
135 T value = mMinCurve.evaluate(t);
136 addToVector(value, values);
137
138 if(useRange)
139 {
140 value = mMaxCurve.evaluate(t);
141 addToVector(value, values);
142 }
143
144 t += sampleInterval;
145 }
146 }
147 }
148
149 return LookupTable(std::move(values), minT, maxT, sizeof(T) / sizeof(float));
150 }
151
152 template struct BS_CORE_EXPORT TDistribution<float>;
153 template struct BS_CORE_EXPORT TDistribution<Vector3>;
154 template struct BS_CORE_EXPORT TDistribution<Vector2>;
155}