forked from Mirrorlandia_minetest/minetest
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.
This commit is contained in:
parent
9c9309cdbb
commit
f8e0778fc9
@ -19,8 +19,122 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "particles.h"
|
#include "particles.h"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
using namespace ParticleParamTypes;
|
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
|
#define PARAM_PVFN(n) ParticleParamTypes::n##ParameterValue
|
||||||
v2f PARAM_PVFN(pick) (float* f, const v2f a, const v2f b) {
|
v2f PARAM_PVFN(pick) (float* f, const v2f a, const v2f b) {
|
||||||
return v2f(
|
return v2f(
|
||||||
|
115
src/particles.h
115
src/particles.h
@ -49,6 +49,7 @@ namespace ParticleParamTypes
|
|||||||
type interpolateParameterValue(float fac, const type a, const type b); \
|
type interpolateParameterValue(float fac, const type a, const type b); \
|
||||||
type pickParameterValue (float* facs, 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(u8); DECL_PARAM_OVERLOADS(s8);
|
||||||
DECL_PARAM_OVERLOADS(u16); DECL_PARAM_OVERLOADS(s16);
|
DECL_PARAM_OVERLOADS(u16); DECL_PARAM_OVERLOADS(s16);
|
||||||
DECL_PARAM_OVERLOADS(u32); DECL_PARAM_OVERLOADS(s32);
|
DECL_PARAM_OVERLOADS(u32); DECL_PARAM_OVERLOADS(s32);
|
||||||
@ -83,8 +84,7 @@ namespace ParticleParamTypes
|
|||||||
k = (E)v;
|
k = (E)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is your brain on C++. */
|
// Describes a single value
|
||||||
|
|
||||||
template <typename T, size_t PN>
|
template <typename T, size_t PN>
|
||||||
struct Parameter
|
struct Parameter
|
||||||
{
|
{
|
||||||
@ -119,9 +119,8 @@ namespace ParticleParamTypes
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> T numericalBlend(float fac, T min, T max)
|
// New struct required to differentiate between core::vectorNd-compatible
|
||||||
{ return min + ((max - min) * fac); }
|
// structs for proper value dumping (debugging)
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
struct VectorParameter : public Parameter<T,N> {
|
struct VectorParameter : public Parameter<T,N> {
|
||||||
using This = VectorParameter<T,N>;
|
using This = VectorParameter<T,N>;
|
||||||
@ -146,15 +145,12 @@ namespace ParticleParamTypes
|
|||||||
return oss.str();
|
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 f32Parameter = Parameter<f32, 1>;
|
||||||
|
|
||||||
using v2fParameter = VectorParameter<v2f, 2>;
|
using v2fParameter = VectorParameter<v2f, 2>;
|
||||||
using v3fParameter = VectorParameter<v3f, 3>;
|
using v3fParameter = VectorParameter<v3f, 3>;
|
||||||
|
// Add more parameter types here if you need them ...
|
||||||
|
|
||||||
|
// Bound limits information based on "Parameter" types
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct RangedParameter
|
struct RangedParameter
|
||||||
{
|
{
|
||||||
@ -168,9 +164,7 @@ namespace ParticleParamTypes
|
|||||||
RangedParameter(T _min, T _max) : min(_min), max(_max) {}
|
RangedParameter(T _min, T _max) : min(_min), max(_max) {}
|
||||||
template <typename M> RangedParameter(M b) : min(b), max(b) {}
|
template <typename M> RangedParameter(M b) : min(b), max(b) {}
|
||||||
|
|
||||||
// these functions handle the old range serialization "format"; bias must
|
// Binary format must not be changed. Function is to be deprecated.
|
||||||
// be manually encoded in a separate part of the stream. NEVER ADD FIELDS
|
|
||||||
// TO THESE FUNCTIONS
|
|
||||||
void legacySerialize(std::ostream &os) const
|
void legacySerialize(std::ostream &os) const
|
||||||
{
|
{
|
||||||
min.serialize(os);
|
min.serialize(os);
|
||||||
@ -182,17 +176,8 @@ namespace ParticleParamTypes
|
|||||||
max.deSerialize(is);
|
max.deSerialize(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
// these functions handle the format used by new fields. new fields go here
|
void serialize(std::ostream &os) const;
|
||||||
void serialize(std::ostream &os) const
|
void deSerialize(std::istream &is);
|
||||||
{
|
|
||||||
legacySerialize(os);
|
|
||||||
writeF32(os, bias);
|
|
||||||
}
|
|
||||||
void deSerialize(std::istream &is)
|
|
||||||
{
|
|
||||||
legacyDeSerialize(is);
|
|
||||||
bias = readF32(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
This interpolate(float fac, const This against) const
|
This interpolate(float fac, const This against) const
|
||||||
{
|
{
|
||||||
@ -203,19 +188,8 @@ namespace ParticleParamTypes
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
T pickWithin() const
|
// Pick a random value (e.g. position) within bounds
|
||||||
{
|
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>
|
template <typename T>
|
||||||
@ -229,8 +203,10 @@ namespace ParticleParamTypes
|
|||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Animation styles (fwd is normal, linear interpolation)
|
||||||
enum class TweenStyle : u8 { fwd, rev, pulse, flicker };
|
enum class TweenStyle : u8 { fwd, rev, pulse, flicker };
|
||||||
|
|
||||||
|
// "Tweened" pretty much means "animated" in this context
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TweenedParameter
|
struct TweenedParameter
|
||||||
{
|
{
|
||||||
@ -238,72 +214,21 @@ namespace ParticleParamTypes
|
|||||||
using This = TweenedParameter<T>;
|
using This = TweenedParameter<T>;
|
||||||
|
|
||||||
TweenStyle style = TweenStyle::fwd;
|
TweenStyle style = TweenStyle::fwd;
|
||||||
u16 reps = 1;
|
u16 reps = 1; // Blending repetitions (same pattern)
|
||||||
f32 beginning = 0.0f;
|
f32 beginning = 0.0f; // Blending start offset
|
||||||
|
|
||||||
T start, end;
|
T start, end;
|
||||||
|
|
||||||
TweenedParameter() = default;
|
TweenedParameter() = default;
|
||||||
TweenedParameter(T _start, T _end) : start(_start), end(_end) {}
|
TweenedParameter(T _start, T _end) : start(_start), end(_end) {}
|
||||||
|
// For initializer lists and assignment
|
||||||
template <typename M> TweenedParameter(M b) : start(b), end(b) {}
|
template <typename M> TweenedParameter(M b) : start(b), end(b) {}
|
||||||
|
|
||||||
T blend(float fac) const
|
// Blend (or animate) the current value
|
||||||
{
|
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
|
void serialize(std::ostream &os) const;
|
||||||
fac *= reps;
|
void deSerialize(std::istream &is);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
Loading…
Reference in New Issue
Block a user