source: trunk/orbital/Lolnament.h @ 1494

Last change on this file since 1494 was 1494, checked in by touky, 9 years ago

Added Rotation & scale to Lolnament.
Brute-fixed all Orbital warnings.

File size: 7.0 KB
Line 
1//
2// Orbital
3//
4// Copyright: (c) 012 Benjamin Huet <huet.benjamin@gmail.com>
5//            (c) 2012 Sam Hocevar <sam@hocevar.net>
6//
7
8#if !defined __LOLNAMENT_H__
9#define __LOLNAMENT_H__
10
11#define DEF_X 30
12#define DEF_Y 1
13#define DEF_Z 30
14#define DEF_SIZE 10
15#define DEF_INF_BLEND 50
16#define DEF_INF_MAX 30
17
18struct transient_infos
19{
20        transient_infos(vec3 base_pos, vec3 base_rot=vec3(0.0f, 0.0f, 0.0f), float base_scale=1.0f, vec3 base_scale_3d=vec3(1.0f, 1.0f, 1.0f))
21                : m_final_pos(vec3(0.0f, 0.0f, 0.0f)),
22                m_final_rot(vec3(0.0f, 0.0f, 0.0f)),
23                m_final_scale(0.0f),
24                m_final_scale_3d(vec3(0.0f, 0.0f, 0.0f)),
25                m_influence(0.0f)
26        {
27                m_base_pos = base_pos;
28                m_base_rot = base_rot;
29                m_base_scale = base_scale;
30                m_base_scale_3d = base_scale_3d;
31        };
32
33        vec3    m_base_pos;
34        vec3    m_base_rot;
35        float   m_base_scale;
36        vec3    m_base_scale_3d;
37
38        float   m_influence;
39
40        vec3    m_final_pos;
41        vec3    m_final_rot;
42        float   m_final_scale;
43        vec3    m_final_scale_3d;
44};
45
46struct work_infos
47{
48        work_infos()
49        {
50                m_pos = vec3(0,0,0);
51                m_rot = vec3(0,0,0);
52                m_scale = 0.0f;
53                m_scale_3d = vec3(0,0,0);
54        }
55
56        vec3    m_pos;
57        vec3    m_rot;
58        float   m_scale;
59        vec3    m_scale_3d;
60};
61
62#define INF_DEFAULT 0 //Basic Blend
63#define INF_WAVE        1 //Blend with wave
64
65struct influence_infos
66{
67        influence_infos(float step, vec3 offset_pos, vec3 offset_rot, float offset_scale=0.0f, vec3 offset_scale_3d=vec3(0.0f, 0.0f, 0.0f), int method=INF_DEFAULT)
68        {
69                m_step = clamp(step, 0.0f, 1.0f);
70                m_offset_pos = offset_pos;
71                m_offset_rot = offset_rot;
72                m_offset_scale = offset_scale;
73                m_offset_scale_3d = offset_scale_3d;
74                m_method = method;
75        };
76
77        float   m_step;
78        int             m_method;
79        vec3    m_offset_pos;
80        vec3    m_offset_rot;
81        float   m_offset_scale;
82        vec3    m_offset_scale_3d;
83};
84
85class Lolnament : public WorldEntity
86{
87public:
88    Lolnament()
89      : m_ready(false)
90    {
91                m_ref_mesh.Compile( "[sc#f80 afcb8 6 6 1]"
92                                                        "[sc#bbd afcb6 8 6 1]"
93                                                        "[sc#44d afcb6 6 8 1]");
94
95                vec3 default_offset = vec3((float)DEF_X, (float)DEF_Y, (float)DEF_Z) * (float)DEF_SIZE * 0.5f;
96                for (int z=0; z < DEF_Z; z++)
97                {
98                        for (int y=0; y < DEF_Y; y++)
99                        {
100                                for (int x=0; x < DEF_X; x++)
101                                {
102                                        m_point_list << transient_infos(vec3((float)x, (float)y, (float)z) * (float)DEF_SIZE - default_offset, vec3(0,0,0));
103                                }
104                        }
105                }
106                wave_angle = 0.0f;
107                debug_point_angle = 0.0f;
108
109                m_influence_list << influence_infos(0.0f, vec3(.0f,   .0f, .0f), vec3(.0f,   .0f,   .0f), 0.0f, vec3(0.0f, 0.0f, 0.0f), INF_WAVE);
110                m_influence_list << influence_infos(0.3f, vec3(.0f, 40.0f, .0f), vec3(.0f, 90.0f,   .0f));
111                m_influence_list << influence_infos(0.7f, vec3(.0f, 40.0f, .0f), vec3(.0f, 90.0f,   .0f));
112                m_influence_list << influence_infos(1.0f, vec3(.0f, 80.0f, .0f), vec3(.0f,   .0f, 90.0f), 0.0f, vec3(2.0f, 0.0f, 0.0f));
113    }
114
115    ~Lolnament()
116    {
117    }
118
119    char const *GetName() { return "<Lolnament>"; }
120
121protected:
122    virtual void TickGame(float seconds)
123    {
124        WorldEntity::TickGame(seconds);
125
126                m_influence_point_list.Empty();
127
128                wave_angle += 3.0f * seconds;
129                debug_point_angle += 1.0f * seconds;
130
131                if (wave_angle > M_PI * 2.0f)
132                        wave_angle -= M_PI * 2.0f;
133                if (debug_point_angle > M_PI * 2.0f)
134                        debug_point_angle -= M_PI * 2.0f;
135
136                m_influence_point_list << vec4(cos(debug_point_angle) * DEF_X * DEF_SIZE * 0.3f, 0, sin(debug_point_angle) * DEF_Z * DEF_SIZE * 0.3f, 1.0f);
137
138                ComputeInfluenceValues();
139
140                ComputePointFromInfluenceValues();
141    }
142
143        void ComputeInfluenceValues()
144    {
145                for (int i=0; i < m_point_list.Count(); i++)
146                {
147                        m_point_list[i].m_influence = 0.0f;
148                        for (int j=0; j < m_influence_point_list.Count(); j++)
149                                m_point_list[i].m_influence = max(m_point_list[i].m_influence, 1.0f - min(1.0f, max(0.0f, length(m_point_list[i].m_base_pos - m_influence_point_list[j].xyz) - DEF_INF_MAX) / DEF_INF_BLEND));
150                }
151        }
152
153        void ComputePointFromInfluenceValues()
154        {
155                for (int i=0; i < m_point_list.Count(); i++)
156                {
157                        int info_a = 0;
158                        int info_b = m_influence_list.Count();
159                        float step_a = -1.0f;
160                        float step_b = 2.0f;
161                        for (int j=0; j < m_influence_list.Count(); j++)
162                        {
163                                if (m_influence_list[j].m_step <= m_point_list[i].m_influence &&
164                                        m_influence_list[j].m_step > step_a)
165                                {
166                                        info_a = j;
167                                        step_a = m_influence_list[j].m_step;
168                                }
169                                if (m_influence_list[j].m_step >= m_point_list[i].m_influence &&
170                                        m_influence_list[j].m_step < step_b)
171                                {
172                                        info_b = j;
173                                        step_b = m_influence_list[j].m_step;
174                                }
175                        }
176
177                        work_infos work_a = work_infos();
178                        work_infos work_b = work_infos();
179                        get_modified_point(m_influence_list[info_a], m_point_list[i], i, work_a);
180                        get_modified_point(m_influence_list[info_b], m_point_list[i], i, work_b);
181
182                        float divider = step_b - step_a;
183                        divider = (divider > .0f)?((m_point_list[i].m_influence - step_a) / divider):(1.0f);
184
185                        m_point_list[i].m_final_pos                     = work_a.m_pos + (work_b.m_pos - work_a.m_pos) * divider;
186                        m_point_list[i].m_final_rot                     = work_a.m_rot + (work_b.m_rot - work_a.m_rot) * divider;
187                        m_point_list[i].m_final_scale           = work_a.m_scale + (work_b.m_scale - work_a.m_scale) * divider;
188                        m_point_list[i].m_final_scale_3d        = work_a.m_scale_3d + (work_b.m_scale_3d - work_a.m_scale_3d) * divider;
189                }
190        }
191
192        void get_modified_point(const influence_infos &src_infos, const transient_infos &src_transient, const int &point_nb, work_infos &dst_work)
193        {
194                //Base setup
195                dst_work.m_pos          = src_transient.m_base_pos;
196                dst_work.m_rot          = src_transient.m_base_rot;
197                dst_work.m_scale        = src_transient.m_base_scale;
198                dst_work.m_scale_3d = src_transient.m_base_scale_3d;
199
200                //Added offset via given method
201                switch (src_infos.m_method)
202                {
203                        case INF_WAVE:
204                        {
205                                float point_angle = wave_angle + (float)point_nb * 2.0f * (float)M_PI * 2.0f / ((float)DEF_X * 1.051f);
206                                dst_work.m_pos += vec3(0.0f, (-1.0f + cos(point_angle)) * 20.0f, 0.0f);
207                                //TODO : dst_work.m_rot += vec3(0,0,0);
208                        }
209                        case INF_DEFAULT:
210                        {
211                                dst_work.m_pos          += src_infos.m_offset_pos;
212                                dst_work.m_rot          += src_infos.m_offset_rot;
213                                dst_work.m_scale        += src_infos.m_offset_scale;
214                                dst_work.m_scale_3d += src_infos.m_offset_scale_3d;
215                                break;
216                        }
217                }
218        }
219
220    virtual void TickDraw(float seconds)
221    {
222        WorldEntity::TickDraw(seconds);
223
224        if (!m_ready)
225        {
226            m_ref_mesh.MeshConvert();
227            m_ready = true;
228        }
229
230                m_rotation *= quat::rotate(seconds * 10.0f, vec3(0, 1, 0));
231                mat4 main_matrix = mat4::translate(m_position) * mat4(m_rotation);
232                for (int i=0; i < m_point_list.Count(); i++)
233                {
234                        mat4 model = main_matrix *
235                                mat4::translate(m_point_list[i].m_final_pos) *
236                                mat4(quat::fromeuler_yxz(m_point_list[i].m_final_rot)) *
237                                mat4::scale(m_point_list[i].m_final_scale_3d * m_point_list[i].m_final_scale);
238                        m_ref_mesh.Render(model);
239                }
240    }
241
242private:
243        //mesh used to render Lolnament
244    Mesh m_ref_mesh;
245        //List of Pos/Rot/Etc... currently applied to the Lolnament's meshes.
246        Array<transient_infos> m_point_list;
247        //List of influence steps
248        Array<influence_infos> m_influence_list;
249
250        Array<vec4> m_influence_point_list;
251
252        float wave_angle;
253        float debug_point_angle;
254    bool m_ready;
255};
256
257#endif /* __LOLNAMENT_H__ */
258
Note: See TracBrowser for help on using the repository browser.