]> git.jsancho.org Git - lugaru.git/blob - Source/Animation/Animation.cpp
Moved Skeleton and Animation to their own folder.
[lugaru.git] / Source / Animation / Animation.cpp
1 /*
2 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Lugaru is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "Animation/Skeleton.h"
21 #include "Animation/Animation.h"
22 #include "Utils/Folders.h"
23 #include "Game.h"
24
25 extern bool visibleloading;
26
27 //~ struct animation_data_elt {
28     //~ const std::string& filename;
29     //~ int height;
30     //~ int attack;
31 //~ };
32
33 //~ static animation_data_elt animation_data[animation_count] = {
34 //~ #define DECLARE_ANIM(id, file, height, attack, ...) {file, height, attack},
35 //~ #include "Animation.def"
36 //~ #undef DECLARE_ANIM
37 //~ };
38 std::vector<Animation> Animation::animations;
39
40 void Animation::loadAll()
41 {
42     int i = 0;
43 #define DECLARE_ANIM(id, file, height, attack, ...) if (i++ < loadable_anim_end) animations.emplace_back(file, height, attack);
44 #include "Animation.def"
45 #undef DECLARE_ANIM
46 }
47
48
49 Animation::Animation():
50     numframes(0),
51     height(0),
52     attack(0),
53     joints(0),
54     weapontargetnum(0),
55
56     position(0),
57     twist(0),
58     twist2(0),
59     speed(0),
60     onground(0),
61     forward(0),
62     label(0),
63     weapontarget(0)
64 {
65 }
66
67 /* EFFECT
68  * load an animation from file
69  */
70 Animation::Animation(const std::string& filename, int aheight, int aattack):
71     Animation()
72 {
73     FILE *tfile;
74     int i, j;
75     XYZ endoffset;
76
77     LOGFUNC;
78
79     // Changing the filename into something the OS can understand
80     std::string filepath = Folders::getResourcePath("Animations/"+filename);
81
82     LOG(std::string("Loading animation...") + filepath);
83
84     height = aheight;
85     attack = aattack;
86
87     if (visibleloading)
88         Game::LoadingScreen();
89
90     // read file in binary mode
91     tfile = Folders::openMandatoryFile( filepath, "rb" );
92
93     // read numframes, joints to know how much memory to allocate
94     funpackf(tfile, "Bi Bi", &numframes, &joints);
95
96     // allocate memory for everything
97
98     position = (XYZ**)malloc(sizeof(XYZ*) * joints);
99     for (i = 0; i < joints; i++)
100         position[i] = (XYZ*)malloc(sizeof(XYZ) * numframes);
101
102     twist = (float**)malloc(sizeof(float*) * joints);
103     for (i = 0; i < joints; i++)
104         twist[i] = (float*)malloc(sizeof(float) * numframes);
105
106     twist2 = (float**)malloc(sizeof(float*) * joints);
107     for (i = 0; i < joints; i++)
108         twist2[i] = (float*)malloc(sizeof(float) * numframes);
109
110     speed = (float*)malloc(sizeof(float) * numframes);
111
112     onground = (bool**)malloc(sizeof(bool*) * joints);
113     for (i = 0; i < joints; i++)
114         onground[i] = (bool*)malloc(sizeof(bool) * numframes);
115
116     forward = (XYZ*)malloc(sizeof(XYZ) * numframes);
117     weapontarget = (XYZ*)malloc(sizeof(XYZ) * numframes);
118     label = (int*)malloc(sizeof(int) * numframes);
119
120     // read binary data as animation
121
122     // for each frame...
123     for (i = 0; i < numframes; i++) {
124         // for each joint in the skeleton...
125         for (j = 0; j < joints; j++) {
126             // read joint position
127             funpackf(tfile, "Bf Bf Bf", &position[j][i].x, &position[j][i].y, &position[j][i].z);
128         }
129         for (j = 0; j < joints; j++) {
130             // read twist
131             funpackf(tfile, "Bf", &twist[j][i]);
132         }
133         for (j = 0; j < joints; j++) {
134             // read onground (boolean)
135             unsigned char uch;
136             funpackf(tfile, "Bb", &uch);
137             onground[j][i] = (uch != 0);
138         }
139         // read frame speed (?)
140         funpackf(tfile, "Bf", &speed[i]);
141     }
142     // read twist2 for whole animation
143     for (i = 0; i < numframes; i++) {
144         for (j = 0; j < joints; j++) {
145             funpackf(tfile, "Bf", &twist2[j][i]);
146         }
147     }
148     // read label for each frame
149     for (i = 0; i < numframes; i++) {
150         funpackf(tfile, "Bf", &label[i]);
151     }
152     // read weapontargetnum
153     funpackf(tfile, "Bi", &weapontargetnum);
154     // read weapontarget positions for each frame
155     for (i = 0; i < numframes; i++) {
156         funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x, &weapontarget[i].y, &weapontarget[i].z);
157     }
158
159     fclose(tfile);
160
161     endoffset = 0;
162     // find average position of certain joints on last frames
163     // and save in endoffset
164     // (not sure what exactly this accomplishes. the y < 1 test confuses me.)
165     for (j = 0; j < joints; j++) {
166         if (position[j][numframes - 1].y < 1)
167             endoffset += position[j][numframes - 1];
168     }
169     endoffset /= joints;
170     offset = endoffset;
171     offset.y = 0;
172 }
173
174 Animation::~Animation()
175 {
176     //~ deallocate();
177 }
178
179 void Animation::deallocate()
180 {
181     int i = 0;
182
183     if (position) {
184         for (i = 0; i < joints; i++)
185             free(position[i]);
186
187         free(position);
188     }
189     position = 0;
190
191     if (twist) {
192         for (i = 0; i < joints; i++)
193             free(twist[i]);
194
195         free(twist);
196     }
197     twist = 0;
198
199     if (twist2) {
200         for (i = 0; i < joints; i++)
201             free(twist2[i]);
202
203         free(twist2);
204     }
205     twist2 = 0;
206
207     if (onground) {
208         for (i = 0; i < joints; i++)
209             free(onground[i]);
210
211         free(onground);
212     }
213     onground = 0;
214
215     if (speed)
216         free(speed);
217     speed = 0;
218
219     if (forward)
220         free(forward);
221     forward = 0;
222
223     if (weapontarget)
224         free(weapontarget);
225     weapontarget = 0;
226
227     if (label)
228         free(label);
229     label = 0;
230
231     joints = 0;
232 }
233
234 Animation & Animation::operator = (const Animation & ani)
235 {
236     int i = 0;
237
238     bool allocate = ((ani.numframes != numframes) || (ani.joints != joints));
239
240     if (allocate)
241         deallocate();
242
243     numframes = ani.numframes;
244     height = ani.height;
245     attack = ani.attack;
246     joints = ani.joints;
247     weapontargetnum = ani.weapontargetnum;
248     offset = ani.offset;
249
250     if (allocate)
251         position = (XYZ**)malloc(sizeof(XYZ*)*ani.joints);
252     for (i = 0; i < ani.joints; i++) {
253         if (allocate)
254             position[i] = (XYZ*)malloc(sizeof(XYZ) * ani.numframes);
255         memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes);
256     }
257
258     if (allocate)
259         twist = (float**)malloc(sizeof(float*)*ani.joints);
260     for (i = 0; i < ani.joints; i++) {
261         if (allocate)
262             twist[i] = (float*)malloc(sizeof(float) * ani.numframes);
263         memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes);
264     }
265
266     if (allocate)
267         twist2 = (float**)malloc(sizeof(float*)*ani.joints);
268     for (i = 0; i < ani.joints; i++) {
269         if (allocate)
270             twist2[i] = (float*)malloc(sizeof(float) * ani.numframes);
271         memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes);
272     }
273
274     if (allocate)
275         speed = (float*)malloc(sizeof(float) * ani.numframes);
276     memcpy(speed, ani.speed, sizeof(float)*ani.numframes);
277
278     if (allocate)
279         onground = (bool**)malloc(sizeof(bool*)*ani.joints);
280     for (i = 0; i < ani.joints; i++) {
281         if (allocate)
282             onground[i] = (bool*)malloc(sizeof(bool) * ani.numframes);
283         memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes);
284     }
285
286     if (allocate)
287         forward = (XYZ*)malloc(sizeof(XYZ) * ani.numframes);
288     memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes);
289
290     if (allocate)
291         weapontarget = (XYZ*)malloc(sizeof(XYZ) * ani.numframes);
292     memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes);
293
294     if (allocate)
295         label = (int*)malloc(sizeof(int) * ani.numframes);
296     memcpy(label, ani.label, sizeof(int)*ani.numframes);
297
298     return (*this);
299 }