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 | |
---|
16 | enum 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 | |
---|
37 | class Character : public WorldEntity |
---|
38 | { |
---|
39 | public: |
---|
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 | |
---|
187 | protected: |
---|
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 | |
---|
274 | private: |
---|
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 | |
---|