source: trunk/games/ToukyDemo/Character.h @ 1555

Last change on this file since 1555 was 1555, checked in by sam, 11 years ago

toukydemo: use std::sprintf to fix the PS3 build.

File size: 7.5 KB
Line 
1//
2// Orbital
3//
4// Copyright: (c) 2009-2012 Cédric Lecacheur <jordx@free.fr>
5//            (c) 2009-2012 Benjamin Huet <huet.benjamin@gmail.com>
6//            (c) 2012 Sam Hocevar <sam@hocevar.net>
7//
8
9/* FIXME: this file is pure crap; it's only a test. */
10
11#if !defined __CHARACTER_H__
12#define __CHARACTER_H__
13
14#include <cstdio>
15
16enum body_parts
17{
18        EBP_Torso,
19        EBP_Head,
20        EBP_LeftArm,
21        EBP_LeftForeArm,
22        EBP_LeftThigh,
23        EBP_LeftLowerLeg,
24        EBP_RightArm,
25        EBP_RightForeArm,
26        EBP_RightThigh,
27        EBP_RightLowerLeg,
28
29        EBP_MAX
30};
31
32#define HEAD_SIZE_X             5.0f
33#define HEAD_SIZE_Y             (HEAD_SIZE_X * 1.5f)
34#define HEAD_SIZE_Z             (HEAD_SIZE_X * 1.0f)
35#define HEAD_CHAMFER    (HEAD_SIZE_X * 0.1f)
36
37class Character : public WorldEntity
38{
39public:
40        Character()
41                : m_ready(false)
42        {
43                //m_rotation = quat::rotate(RandF(0.f, 360.f), vec3(0, 1, 0));
44
45                //Mesh size calculation
46                Array<vec4> MeshSize;
47                Array<vec3> MeshOffset;
48                for (int i = 0; i < EBP_MAX; ++i)
49                {
50                        vec4 NewSize = vec4(.0f);
51                        vec3 NewOffset = vec3(.0f);
52                        switch (i)
53                        {
54                                case EBP_Head:
55                                {
56                                        NewSize = vec4(HEAD_SIZE_X, HEAD_SIZE_Y, HEAD_SIZE_Z, HEAD_CHAMFER);
57                                        NewOffset = vec3(.5f, HEAD_SIZE_Y * 0.5f, .0f);
58                                        break;
59                                }
60                                case EBP_Torso:
61                                {
62                                        //Man : Torse : 3 TetesH H (dont 1/4 cou), 2 TetesH L
63                                        NewSize = vec4(HEAD_SIZE_X, HEAD_SIZE_Y * 3.0f, HEAD_SIZE_Z * 2.0f, HEAD_CHAMFER);
64                                        break;
65                                }
66                                case EBP_RightArm:
67                                case EBP_LeftArm:
68                                {
69                                        //Man : bras  : 3 TetesH + 1 TetesL (epaule) (1H+1L + 2H)
70                                        NewSize = vec4(HEAD_SIZE_X * 0.8f, HEAD_SIZE_Y + HEAD_SIZE_X, HEAD_SIZE_Z * 0.8f, HEAD_CHAMFER);
71                                        NewOffset = vec3(.0f, -NewSize.y * 0.4f, .0f);
72                                        break;
73                                }
74                                case EBP_RightForeArm:
75                                case EBP_LeftForeArm:
76                                {
77                                        NewSize = vec4(HEAD_SIZE_X * 0.8f, HEAD_SIZE_Y + HEAD_SIZE_Y, HEAD_SIZE_Z * 0.8f, HEAD_CHAMFER);
78                                        NewOffset = vec3(.0f, -NewSize.y * 0.5f, .0f);
79                                        break;
80                                }
81                                case EBP_RightThigh:
82                                case EBP_LeftThigh:
83                                {
84                                        //Man : Jambe : 4 TetesH (2H * 2H)
85                                        NewSize = vec4(HEAD_SIZE_X * 0.8f, HEAD_SIZE_Y + HEAD_SIZE_Y, HEAD_SIZE_Z * 0.8f, HEAD_CHAMFER);
86                                        NewOffset = vec3(.0f, -NewSize.y * 0.5f, .0f);
87                                        break;
88                                }
89                                case EBP_RightLowerLeg:
90                                case EBP_LeftLowerLeg:
91                                {
92                                        NewSize = vec4(HEAD_SIZE_X * 0.8f, HEAD_SIZE_Y + HEAD_SIZE_Y, HEAD_SIZE_Z * 0.8f, HEAD_CHAMFER);
93                                        NewOffset = vec3(.0f, -NewSize.y * 0.5f, .0f);
94                                        break;
95                                }
96                        }
97                        MeshSize << NewSize;
98                        MeshOffset << NewOffset;
99                }
100
101                //Mesh ref matrix calculation
102                mat4 NewMatrix;
103                int ParentMatrix = EBP_Torso;
104                for (int i = 0; i < EBP_MAX; ++i)
105                {
106                        vec3 BaseCos = vec3(0.0f);
107                        switch (i)
108                        {
109                                case EBP_Head:
110                                {
111                                        NewMatrix = mat4::translate(vec3(.0f, MeshSize[EBP_Torso].y, .0f) * .5f);
112                                        ParentMatrix = EBP_Torso;
113                                        break;
114                                }
115                                case EBP_Torso:
116                                {
117                                        //Man : Torse : 3 TetesH H (dont 1/4 cou), 2 TetesH L
118                                        NewMatrix = mat4::translate(vec3(.0f, MeshSize[EBP_Torso].y * .5f + MeshSize[EBP_RightLowerLeg].y + MeshSize[EBP_RightThigh].y, .0f));
119                                        ParentMatrix = EBP_Torso;
120                                        break;
121                                }
122                                case EBP_RightArm:
123                                case EBP_LeftArm:
124                                {
125                                        //Man : bras  : 3 TetesH + 1 TetesL (epaule) (1H+1L + 2H)
126                                        vec3 NewTranslation = vec3(.0f, MeshSize[EBP_Torso].y * .5f - MeshSize[EBP_RightArm].y * .1f, MeshSize[EBP_RightArm].z + MeshSize[EBP_Torso].z) * vec3(.0f, 1.0f, .5f);
127                                        if (i == EBP_LeftArm)
128                                                NewTranslation *= vec3(1.0f, 1.0f, -1.0f);
129                                        NewMatrix = mat4::translate(NewTranslation);
130                                        ParentMatrix = EBP_Torso;
131                                        break;
132                                }
133                                case EBP_RightForeArm:
134                                case EBP_LeftForeArm:
135                                {
136                                        NewMatrix = mat4::translate(vec3(.0f, MeshSize[EBP_RightArm].y * .3f + MeshSize[EBP_RightForeArm].y * .5f, .0f) * -1.0f);
137                                        if (i == EBP_RightForeArm)
138                                                ParentMatrix = EBP_RightArm;
139                                        else
140                                                ParentMatrix = EBP_LeftArm;
141                                        break;
142                                }
143                                case EBP_RightThigh:
144                                case EBP_LeftThigh:
145                                {
146                                        //Man : Jambe : 4 TetesH (2H * 2H)
147                                        vec3 NewTranslation = vec3(.0f, -MeshSize[EBP_Torso].y * .5f, MeshSize[EBP_Torso].z - MeshSize[EBP_RightThigh].z) * vec3(.0f, 1.0f, .5f);
148                                        if (i == EBP_LeftThigh)
149                                                NewTranslation *= vec3(1.0f, 1.0f, -1.0f);
150                                        NewMatrix = mat4::translate(NewTranslation);
151                                        ParentMatrix = EBP_Torso;
152                                        if (i == EBP_LeftThigh)
153                                                BaseCos = vec3(M_PI);
154                                        break;
155                                }
156                                case EBP_RightLowerLeg:
157                                case EBP_LeftLowerLeg:
158                                {
159                                        NewMatrix = mat4::translate(vec3(.0f, MeshSize[EBP_RightThigh].y + MeshSize[EBP_RightLowerLeg].y, .0f) * -.5f);
160                                        if (i == EBP_RightLowerLeg)
161                                                ParentMatrix = EBP_RightThigh;
162                                        else
163                                                ParentMatrix = EBP_LeftThigh;
164                                        break;
165                                }
166                        }
167                        m_body_matrix_local << NewMatrix;
168                        m_body_parent << ParentMatrix;
169                        m_body_matrix_world << mat4(1.0);
170                        m_body_rotation << vec3(.0f);
171                        m_body_cos << BaseCos;
172
173                        char NewMesh[200];
174                        EasyMesh TmpMesh;
175                        std::sprintf(NewMesh, "[sc#ddd afcb%.3f %.3f %.3f -%.3f t%.3f %.3f %.3f]", MeshSize[i].x, MeshSize[i].y, MeshSize[i].z, MeshSize[i].w, MeshOffset[i].x, MeshOffset[i].y, MeshOffset[i].z);
176                        TmpMesh.Compile(NewMesh);
177                        m_body_parts << TmpMesh;
178                }
179        }
180
181        ~Character()
182        {
183        }
184
185        char const *GetName() { return "<Character>"; }
186
187protected:
188        virtual void TickGame(float seconds)
189        {
190                WorldEntity::TickGame(seconds);
191
192                for (int i = 0; i < EBP_MAX; ++i)
193                {
194                        switch (i)
195                        {
196                                case EBP_Head:
197                                {
198                                        //m_body_rotation[i].y += 10.0f * seconds;
199                                        break;
200                                }
201                                case EBP_Torso:
202                                {
203                                        break;
204                                }
205                                case EBP_RightArm:
206                                case EBP_LeftArm:
207                                {
208                                        m_body_rotation[i].z = lol::cos(m_body_cos[i - (EBP_LeftArm - EBP_LeftThigh)].z) * -10.0f;
209                                        break;
210                                }
211                                case EBP_RightForeArm:
212                                case EBP_LeftForeArm:
213                                {
214                                        m_body_rotation[i].z = 5.0f + m_body_rotation[i - (EBP_LeftForeArm - EBP_LeftLowerLeg)].z * -.25f;
215                                        break;
216                                }
217                                case EBP_LeftThigh:
218                                case EBP_RightThigh:
219                                {
220                                        m_body_cos[i].z += 2.0f * seconds;
221                                        m_body_rotation[i].z = lol::cos(m_body_cos[i].z) * 30.0f;
222                                        break;
223                                }
224                                case EBP_LeftLowerLeg:
225                                case EBP_RightLowerLeg:
226                                {
227                                        float NewSin = -lol::sin(m_body_cos[i - (EBP_LeftLowerLeg - EBP_LeftThigh)].z);
228                                        float NewCos = -lol::cos(m_body_cos[i - (EBP_LeftLowerLeg - EBP_LeftThigh)].z);
229                                        if (NewSin <= .0f)
230                                                m_body_rotation[i].z = 0.0f;
231                                        else if (NewSin > .0f && NewCos < .0f)
232                                                m_body_rotation[i].z = NewSin * NewSin * NewSin * -40.0f;
233                                        else if (NewSin > .0f && NewCos > .0f)
234                                                m_body_rotation[i].z = (1.0f - NewCos * NewCos * NewCos * NewCos) * -40.0f;
235                                        break;
236                                }
237                        }
238                }
239
240                for (int i = 0; i < EBP_MAX; ++i)
241                {
242                        mat4 WorldMatrix = mat4(1.0f);
243                        int CurParent = m_body_parent[i];
244
245                        if (CurParent != i)
246                                WorldMatrix = m_body_matrix_world[CurParent];
247
248                        m_body_matrix_world[i] = WorldMatrix * m_body_matrix_local[i] * mat4(quat::fromeuler_xyz(m_body_rotation[i]));
249                }
250
251                m_velocity = vec3(20.f, .0f, .0f);
252
253                m_position += m_rotation.transform(m_velocity) * seconds;
254        }
255
256        virtual void TickDraw(float seconds)
257        {
258                WorldEntity::TickDraw(seconds);
259
260                if (!m_ready)
261                {
262                        for (int i = 0; i < m_body_parts.Count(); i++)
263                                m_body_parts[i].MeshConvert();
264                        m_ready = true;
265                }
266
267                m_rotation *= quat::rotate(seconds * 30.0f, vec3(0, 1, 0));
268                mat4 main_matrix = mat4::translate(m_position) * mat4(m_rotation);
269
270                for (int i = 0; i < EBP_MAX; ++i)
271                        m_body_parts[i].Render(main_matrix * m_body_matrix_world[i]);
272        }
273
274private:
275        //Base datas
276        Array<EasyMesh>         m_body_parts;
277        Array<int>                      m_body_parent;
278        Array<mat4>                     m_body_matrix_local;
279        //Frame datas
280        Array<mat4>                     m_body_matrix_world;
281        Array<vec3>                     m_body_rotation;
282        Array<vec3>                     m_body_cos;
283
284        bool                            m_ready;
285};
286
287#endif /* __CHARACTER_H__ */
288
Note: See TracBrowser for help on using the repository browser.