1
/*
2
 *  The Mana World
3
 *  Copyright (C) 2006  The Mana World Development Team
4
 *
5
 *  This file is part of The Mana World.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
22
#include <cmath>
23
24
/**
25
 * Returns a random numeric value that is larger than or equal min and smaller
26
 * than max
27
 */
28
29
enum ChangeFunc
30
{
31
    FUNC_NONE,
32
    FUNC_SINE,
33
    FUNC_SAW,
34
    FUNC_TRIANGLE,
35
    FUNC_SQUARE
36
};
37
38
template <typename T> struct ParticleEmitterProp
39
{
40
    ParticleEmitterProp():
41
        changeFunc(FUNC_NONE)
42
    {
43
    }
44
45
    void set(T min, T max)
46
    {
47
        minVal=min; maxVal=max;
48
    }
49
50
    void set(T val)
51
    {
52
        set(val, val);
53
    }
54
55
    void setFunction(ChangeFunc func, T amplitude, int period, int phase)
56
    {
57
        changeFunc = func;
58
        changeAmplitude = amplitude;
59
        changePeriod = period;
60
        changePhase = phase;
61
    }
62
63
    T value(int tick)
64
    {
65
        tick += changePhase;
66
        T val = (T) (minVal + (maxVal - minVal) * (rand() / ((double) RAND_MAX + 1)));
67
68
        switch (changeFunc)
69
        {
70
            case FUNC_SINE:
71
                val += (T) std::sin(M_PI * 2 * ((double)(tick%changePeriod) / (double)changePeriod)) * changeAmplitude;
72
                break;
73
            case FUNC_SAW:
74
                val += (T) (changeAmplitude * ((double)(tick%changePeriod) / (double)changePeriod)) * 2 - changeAmplitude;
75
                break;
76
            case FUNC_TRIANGLE:
77
                if ((tick%changePeriod) * 2 < changePeriod)
78
                {
79
                    val += changeAmplitude - (T)((tick%changePeriod) / (double)changePeriod) * changeAmplitude * 4;
80
                } else {
81
                    val += changeAmplitude * -3 + (T)((tick%changePeriod) / (double)changePeriod) * changeAmplitude * 4;
82
                    // I have no idea why this works but it does
83
                }
84
                break;
85
            case FUNC_SQUARE:
86
                if ((tick%changePeriod) * 2 < changePeriod)
87
                {
88
                    val += changeAmplitude;
89
                } else {
90
                    val -= changeAmplitude;
91
                }
92
                break;
93
            case FUNC_NONE:
94
            default:
95
                //nothing
96
                break;
97
        }
98
99
        return val;
100
    }
101
102
    T minVal;
103
    T maxVal;
104
105
    ChangeFunc changeFunc;
106
    T changeAmplitude;
107
    int changePeriod;
108
    int changePhase;
109
};