aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSmallJoker <mk939@ymail.com>2023-04-05 20:22:38 +0200
committerSmallJoker <SmallJoker@users.noreply.github.com>2023-04-08 17:23:17 +0200
commitf8e0778fc9e402674b091fcf529d0295acd4ddd0 (patch)
tree87bf806d481670e5a8edcef2c0e6ece6d5fd439d
parent9c9309cdbb053598aaf08506928a4824e78b4622 (diff)
downloadminetest-f8e0778fc9e402674b091fcf529d0295acd4ddd0.tar.xz
Particle spawner: Move definitions to source
Long functions were moved to the source file to keep the header short to speed up compiling. This has no functional change.
-rw-r--r--src/particles.cpp114
-rw-r--r--src/particles.h119
2 files changed, 136 insertions, 97 deletions
diff --git a/src/particles.cpp b/src/particles.cpp
index e495ecd03..74ccc2aae 100644
--- a/src/particles.cpp
+++ b/src/particles.cpp
@@ -19,8 +19,122 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "particles.h"
#include <type_traits>
+
using namespace ParticleParamTypes;
+template<typename T>
+void RangedParameter<T>::serialize(std::ostream &os) const
+{
+ min.serialize(os);
+ max.serialize(os);
+ writeF32(os, bias);
+}
+
+template<typename T>
+void RangedParameter<T>::deSerialize(std::istream &is)
+{
+ min.deSerialize(is);
+ max.deSerialize(is);
+ bias = readF32(is);
+}
+
+
+template<typename T>
+T RangedParameter<T>::pickWithin() const
+{
+ typename T::pickFactors values;
+ auto p = numericAbsolute(bias) + 1;
+ for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
+ if (bias < 0)
+ values[i] = 1.0f - pow(myrand_float(), p);
+ else
+ values[i] = pow(myrand_float(), p);
+ }
+ return T::pick(values, min, max);
+}
+
+
+template<typename T>
+T TweenedParameter<T>::blend(float fac) const
+{
+ // warp time coordinates in accordance w/ settings
+ if (fac > beginning) {
+ // remap for beginning offset
+ auto len = 1 - beginning;
+ fac -= beginning;
+ fac /= len;
+
+ // remap for repetitions
+ fac *= reps;
+ if (fac > 1) // poor man's modulo
+ fac -= (decltype(reps))fac;
+
+ // remap for style
+ switch (style) {
+ case TweenStyle::fwd: /* do nothing */ break;
+ case TweenStyle::rev: fac = 1.0f - fac; break;
+ case TweenStyle::pulse:
+ case TweenStyle::flicker: {
+ if (fac > 0.5f) {
+ fac = 1.f - (fac*2.f - 1.f);
+ } else {
+ fac = fac * 2;
+ }
+ if (style == TweenStyle::flicker) {
+ fac *= myrand_range(0.7f, 1.0f);
+ }
+ }
+ }
+ if (fac>1.f)
+ fac = 1.f;
+ else if (fac<0.f)
+ fac = 0.f;
+ } else {
+ fac = (style == TweenStyle::rev) ? 1.f : 0.f;
+ }
+
+ return start.interpolate(fac, end);
+}
+
+template<typename T>
+void TweenedParameter<T>::serialize(std::ostream &os) const
+{
+ writeU8(os, static_cast<u8>(style));
+ writeU16(os, reps);
+ writeF32(os, beginning);
+ start.serialize(os);
+ end.serialize(os);
+}
+
+template<typename T>
+void TweenedParameter<T>::deSerialize(std::istream &is)
+{
+ style = static_cast<TweenStyle>(readU8(is));
+ reps = readU16(is);
+ beginning = readF32(is);
+ start.deSerialize(is);
+ end.deSerialize(is);
+}
+
+namespace ParticleParamTypes {
+ // For function definitions
+ template struct RangedParameter<v3fParameter>;
+ template struct RangedParameter<f32Parameter>;
+
+ template struct TweenedParameter<v2fParameter>;
+ template struct TweenedParameter<v3fParameter>;
+ template struct TweenedParameter<f32Parameter>;
+ template struct TweenedParameter<v3fRange>;
+ template struct TweenedParameter<f32Range>;
+}
+
+// Linear interpolation
+template <typename T>
+static T numericalBlend(float fac, T min, T max)
+{
+ return min + ((max - min) * fac);
+}
+
#define PARAM_PVFN(n) ParticleParamTypes::n##ParameterValue
v2f PARAM_PVFN(pick) (float* f, const v2f a, const v2f b) {
return v2f(
diff --git a/src/particles.h b/src/particles.h
index 3061deb83..179d5ac5b 100644
--- a/src/particles.h
+++ b/src/particles.h
@@ -49,6 +49,7 @@ namespace ParticleParamTypes
type interpolateParameterValue(float fac, const type a, const type b); \
type pickParameterValue (float* facs, const type a, const type b);
+ // Function definition: see "particles.cpp"
DECL_PARAM_OVERLOADS(u8); DECL_PARAM_OVERLOADS(s8);
DECL_PARAM_OVERLOADS(u16); DECL_PARAM_OVERLOADS(s16);
DECL_PARAM_OVERLOADS(u32); DECL_PARAM_OVERLOADS(s32);
@@ -83,8 +84,7 @@ namespace ParticleParamTypes
k = (E)v;
}
- /* this is your brain on C++. */
-
+ // Describes a single value
template <typename T, size_t PN>
struct Parameter
{
@@ -119,9 +119,8 @@ namespace ParticleParamTypes
};
- template <typename T> T numericalBlend(float fac, T min, T max)
- { return min + ((max - min) * fac); }
-
+ // New struct required to differentiate between core::vectorNd-compatible
+ // structs for proper value dumping (debugging)
template <typename T, size_t N>
struct VectorParameter : public Parameter<T,N> {
using This = VectorParameter<T,N>;
@@ -146,15 +145,12 @@ namespace ParticleParamTypes
return oss.str();
}
- using u8Parameter = Parameter<u8, 1>; using s8Parameter = Parameter<s8, 1>;
- using u16Parameter = Parameter<u16, 1>; using s16Parameter = Parameter<s16, 1>;
- using u32Parameter = Parameter<u32, 1>; using s32Parameter = Parameter<s32, 1>;
-
using f32Parameter = Parameter<f32, 1>;
-
using v2fParameter = VectorParameter<v2f, 2>;
using v3fParameter = VectorParameter<v3f, 3>;
+ // Add more parameter types here if you need them ...
+ // Bound limits information based on "Parameter" types
template <typename T>
struct RangedParameter
{
@@ -168,31 +164,20 @@ namespace ParticleParamTypes
RangedParameter(T _min, T _max) : min(_min), max(_max) {}
template <typename M> RangedParameter(M b) : min(b), max(b) {}
- // these functions handle the old range serialization "format"; bias must
- // be manually encoded in a separate part of the stream. NEVER ADD FIELDS
- // TO THESE FUNCTIONS
- void legacySerialize(std::ostream& os) const
+ // Binary format must not be changed. Function is to be deprecated.
+ void legacySerialize(std::ostream &os) const
{
min.serialize(os);
max.serialize(os);
}
- void legacyDeSerialize(std::istream& is)
+ void legacyDeSerialize(std::istream &is)
{
min.deSerialize(is);
max.deSerialize(is);
}
- // these functions handle the format used by new fields. new fields go here
- void serialize(std::ostream &os) const
- {
- legacySerialize(os);
- writeF32(os, bias);
- }
- void deSerialize(std::istream &is)
- {
- legacyDeSerialize(is);
- bias = readF32(is);
- }
+ void serialize(std::ostream &os) const;
+ void deSerialize(std::istream &is);
This interpolate(float fac, const This against) const
{
@@ -203,19 +188,8 @@ namespace ParticleParamTypes
return r;
}
- T pickWithin() const
- {
- typename T::pickFactors values;
- auto p = numericAbsolute(bias) + 1;
- for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
- if (bias < 0)
- values[i] = 1.0f - pow(myrand_float(), p);
- else
- values[i] = pow(myrand_float(), p);
- }
- return T::pick(values, min, max);
- }
-
+ // Pick a random value (e.g. position) within bounds
+ T pickWithin() const;
};
template <typename T>
@@ -229,8 +203,10 @@ namespace ParticleParamTypes
return s.str();
}
+ // Animation styles (fwd is normal, linear interpolation)
enum class TweenStyle : u8 { fwd, rev, pulse, flicker };
+ // "Tweened" pretty much means "animated" in this context
template <typename T>
struct TweenedParameter
{
@@ -238,72 +214,21 @@ namespace ParticleParamTypes
using This = TweenedParameter<T>;
TweenStyle style = TweenStyle::fwd;
- u16 reps = 1;
- f32 beginning = 0.0f;
+ u16 reps = 1; // Blending repetitions (same pattern)
+ f32 beginning = 0.0f; // Blending start offset
T start, end;
TweenedParameter() = default;
TweenedParameter(T _start, T _end) : start(_start), end(_end) {}
+ // For initializer lists and assignment
template <typename M> TweenedParameter(M b) : start(b), end(b) {}
- T blend(float fac) const
- {
- // warp time coordinates in accordance w/ settings
- if (fac > beginning) {
- // remap for beginning offset
- auto len = 1 - beginning;
- fac -= beginning;
- fac /= len;
-
- // remap for repetitions
- fac *= reps;
- if (fac > 1) // poor man's modulo
- fac -= (decltype(reps))fac;
-
- // remap for style
- switch (style) {
- case TweenStyle::fwd: /* do nothing */ break;
- case TweenStyle::rev: fac = 1.0f - fac; break;
- case TweenStyle::pulse:
- case TweenStyle::flicker: {
- if (fac > 0.5f) {
- fac = 1.f - (fac*2.f - 1.f);
- } else {
- fac = fac * 2;
- }
- if (style == TweenStyle::flicker) {
- fac *= myrand_range(0.7f, 1.0f);
- }
- }
- }
- if (fac>1.f)
- fac = 1.f;
- else if (fac<0.f)
- fac = 0.f;
- } else {
- fac = (style == TweenStyle::rev) ? 1.f : 0.f;
- }
-
- return start.interpolate(fac, end);
- }
+ // Blend (or animate) the current value
+ T blend(float fac) const;
- void serialize(std::ostream &os) const
- {
- writeU8(os, static_cast<u8>(style));
- writeU16(os, reps);
- writeF32(os, beginning);
- start.serialize(os);
- end.serialize(os);
- }
- void deSerialize(std::istream &is)
- {
- style = static_cast<TweenStyle>(readU8(is));
- reps = readU16(is);
- beginning = readF32(is);
- start.deSerialize(is);
- end.deSerialize(is);
- }
+ void serialize(std::ostream &os) const;
+ void deSerialize(std::istream &is);
};
template <typename T>