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

Last change on this file since 1554 was 1554, checked in by touky, 11 years ago

Added Location modifier in URO.
Added BtPhystest for Bullet Physics test project.

File size: 7.7 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(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                for (int i = 0; i < EBP_MAX; ++i)
239                {
240                        mat4 WorldMatrix = mat4(1.0f);
241                        int CurParent = m_body_parent[i];
242
243                        if (CurParent != i)
244                                WorldMatrix = m_body_matrix_world[CurParent];
245
246                        m_body_matrix_world[i] = WorldMatrix * m_body_matrix_local[i] * mat4(quat::fromeuler_xyz(m_body_rotation[i]));
247                }
248
249                m_velocity = vec3(20.f, .0f, .0f);
250
251                m_position += m_rotation.transform(m_velocity) * seconds;
252        }
253
254        virtual void TickDraw(float seconds)
255        {
256                WorldEntity::TickDraw(seconds);
257
258                if (!m_ready)
259                {
260                        for (int i = 0; i < m_body_parts.Count(); i++)
261                                m_body_parts[i].MeshConvert();
262                        m_ready = true;
263                }
264
265                m_rotation *= quat::rotate(seconds * 30.0f, vec3(0, 1, 0));
266                mat4 main_matrix = mat4::translate(m_position) * mat4(m_rotation);
267
268                for (int i = 0; i < EBP_MAX; ++i)
269                        m_body_parts[i].Render(main_matrix * m_body_matrix_world[i]);
270        }
271
272private:
273        //Base datas
274        Array<EasyMesh>         m_body_parts;
275        Array<int>                      m_body_parent;
276        Array<mat4>                     m_body_matrix_local;
277        //Frame datas
278        Array<mat4>                     m_body_matrix_world;
279        Array<vec3>                     m_body_rotation;
280        Array<vec3>                     m_body_cos;
281
282        bool                            m_ready;
283};
284
285#endif /* __CHARACTER_H__ */
286
Note: See TracBrowser for help on using the repository browser.