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

Last change on this file since 1547 was 1547, checked in by touky, 8 years ago

Added basic character logic.

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