Isle
Loading...
Searching...
No Matches
legoanim.cpp
Go to the documentation of this file.
1#include "legoanim.h"
2
5
6#include <limits.h>
7
18
19// FUNCTION: LEGO1 0x1009f000
21{
22 m_z = 0.0f;
23}
24
25// FUNCTION: LEGO1 0x1009f020
27{
28 LegoResult result;
29
30 if ((result = LegoAnimKey::Read(p_storage)) != SUCCESS) {
31 return result;
32 }
33
34 if ((result = p_storage->Read(&m_z, sizeof(m_z))) != SUCCESS) {
35 return result;
36 }
37
38 return SUCCESS;
39}
40
41// FUNCTION: LEGO1 0x1009f060
42// FUNCTION: BETA10 0x1018133f
44{
45 LegoResult result;
46
47 if ((result = LegoAnimKey::Write(p_storage)) != SUCCESS) {
48 return result;
49 }
50
51 if ((result = p_storage->Write(&m_z, sizeof(m_z))) != SUCCESS) {
52 return result;
53 }
54
55 return SUCCESS;
56}
57
58// FUNCTION: LEGO1 0x1009f0a0
60{
61 m_unk0x00 = 0;
62 m_unk0x04 = NULL;
63 m_unk0x08 = 0;
64 m_unk0x0c = NULL;
65 m_unk0x10 = 0;
66 m_unk0x14 = NULL;
67 m_unk0x18 = 0;
68 m_unk0x1c = 0;
69 m_unk0x20 = 0;
70}
71
72// FUNCTION: LEGO1 0x1009f0d0
74{
75 if (m_unk0x04 != NULL) {
76 delete[] m_unk0x04;
77 m_unk0x04 = NULL;
78 }
79
80 if (m_unk0x0c != NULL) {
81 delete[] m_unk0x0c;
82 m_unk0x0c = NULL;
83 }
84
85 if (m_unk0x14 != NULL) {
86 delete[] m_unk0x14;
87 m_unk0x14 = NULL;
88 }
89}
90
91// FUNCTION: LEGO1 0x1009f120
92// FUNCTION: BETA10 0x101814be
94{
95 LegoResult result;
96 LegoS32 i;
97
98 if ((result = p_storage->Write(&m_unk0x00, sizeof(m_unk0x00))) != SUCCESS) {
99 return result;
100 }
101 if (m_unk0x00 != 0) {
102 for (i = 0; i < m_unk0x00; i++) {
103 if ((result = m_unk0x04[i].Write(p_storage)) != SUCCESS) {
104 return result;
105 }
106 }
107 }
108
109 if ((result = p_storage->Write(&m_unk0x08, sizeof(m_unk0x08))) != SUCCESS) {
110 return result;
111 }
112 if (m_unk0x08 != 0) {
113 for (i = 0; i < m_unk0x08; i++) {
114 if ((result = m_unk0x0c[i].Write(p_storage)) != SUCCESS) {
115 return result;
116 }
117 }
118 }
119
120 if ((result = p_storage->Write(&m_unk0x10, sizeof(m_unk0x10))) != SUCCESS) {
121 return result;
122 }
123 if (m_unk0x10 != 0) {
124 for (i = 0; i < m_unk0x10; i++) {
125 if ((result = m_unk0x14[i].Write(p_storage)) != SUCCESS) {
126 return result;
127 }
128 }
129 }
130
131 return SUCCESS;
132}
133
134// FUNCTION: LEGO1 0x1009f200
136{
137 LegoResult result;
138 LegoS32 i;
139
140 if ((result = p_storage->Read(&m_unk0x00, sizeof(m_unk0x00))) != SUCCESS) {
141 return result;
142 }
143 if (m_unk0x00 != 0) {
144 m_unk0x04 = new LegoTranslationKey[m_unk0x00];
145 for (i = 0; i < m_unk0x00; i++) {
146 if ((result = m_unk0x04[i].Read(p_storage)) != SUCCESS) {
147 goto done;
148 }
149 }
150 }
151
152 if ((result = p_storage->Read(&m_unk0x08, sizeof(m_unk0x08))) != SUCCESS) {
153 return result;
154 }
155 if (m_unk0x08 != 0) {
156 m_unk0x0c = new LegoTranslationKey[m_unk0x08];
157 for (i = 0; i < m_unk0x08; i++) {
158 if ((result = m_unk0x0c[i].Read(p_storage)) != SUCCESS) {
159 goto done;
160 }
161 }
162 }
163
164 if ((result = p_storage->Read(&m_unk0x10, sizeof(m_unk0x10))) != SUCCESS) {
165 return result;
166 }
167 if (m_unk0x10 != 0) {
168 m_unk0x14 = new LegoUnknownKey[m_unk0x10];
169 for (i = 0; i < m_unk0x10; i++) {
170 if ((result = m_unk0x14[i].Read(p_storage)) != SUCCESS) {
171 goto done;
172 }
173 }
174 }
175
176 return SUCCESS;
177
178done:
179 if (m_unk0x04 != NULL) {
180 delete[] m_unk0x04;
181 m_unk0x00 = 0;
182 m_unk0x04 = NULL;
183 }
184
185 if (m_unk0x0c != NULL) {
186 delete[] m_unk0x0c;
187 m_unk0x08 = 0;
188 m_unk0x0c = NULL;
189 }
190
191 if (m_unk0x14 != NULL) {
192 delete[] m_unk0x14;
193 m_unk0x10 = 0;
194 m_unk0x14 = NULL;
195 }
196
197 return result;
198}
199
200// FUNCTION: LEGO1 0x1009f490
201// FUNCTION: BETA10 0x10181a83
203{
204 MxMatrix localb0;
205 MxMatrix local4c;
206
207 Vector3 local5c(localb0[0]);
208 Vector3 local68(localb0[1]);
209 Vector3 local54(localb0[2]);
210 Vector3 localb8(localb0[3]);
211
212 Mx3DPointFloat localcc;
213
214 localb0.SetIdentity();
215
216 LegoU32 local60;
217 if (m_unk0x08 != 0) {
218 local60 = GetUnknown0x18();
219 LegoAnimNodeData::GetTranslation(m_unk0x08, m_unk0x0c, p_time, localb0, local60);
220 SetUnknown0x18(local60);
221 localcc = localb8;
222 localb8.Clear();
223 }
224
225 if (m_unk0x00 != 0) {
226 local60 = GetUnknown0x1c();
227 LegoAnimNodeData::GetTranslation(m_unk0x00, m_unk0x04, p_time, localb0, local60);
228 SetUnknown0x1c(local60);
229 }
230
231 local54 = localcc;
232 local54 -= localb8;
233
234 if (local54.Unitize() == 0) {
235 local5c.EqualsCross(local68, local54);
236
237 if (local5c.Unitize() == 0) {
238 local68.EqualsCross(local54, local5c);
239
240 localcc = p_matrix[3];
241 localcc += localb0[3];
242
243 p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = localb0[3][0] = localb0[3][1] = localb0[3][2] = 0;
244
245 if (m_unk0x10 != 0) {
246 LegoU32 locald0 = -1;
247 LegoU32 locald8;
248 locald0 = GetUnknown0x20();
249
250 LegoU32 localdc =
251 LegoAnimNodeData::FindKeys(p_time, m_unk0x10, m_unk0x14, sizeof(*m_unk0x14), locald8, locald0);
252
253 SetUnknown0x20(locald0);
254
255 switch (localdc) {
256 case 1:
257 p_matrix.RotateZ(m_unk0x14[locald8].GetZ());
258 break;
259 case 2:
260 // Seems to be unused
262 p_time,
263 m_unk0x14[locald8],
264 m_unk0x14[locald8].GetZ(),
265 m_unk0x14[locald8 + 1],
266 m_unk0x14[locald8 + 1].GetZ()
267 );
268 p_matrix.RotateZ(m_unk0x14[locald8].GetZ());
269 break;
270 }
271 }
272
273 local4c = p_matrix;
274 p_matrix.Product(local4c.GetData(), localb0.GetData());
275 p_matrix[3][0] = localcc[0];
276 p_matrix[3][1] = localcc[1];
277 p_matrix[3][2] = localcc[2];
278 }
279 }
280
281 return SUCCESS;
282}
283
284// FUNCTION: LEGO1 0x1009f900
285// FUNCTION: BETA10 0x1017df90
287{
288 m_time = 0;
289 m_flags = 0;
290}
291
292// FUNCTION: LEGO1 0x1009f910
294{
295 LegoResult result;
296 LegoS32 timeAndFlags;
297
298 if ((result = p_storage->Read(&timeAndFlags, sizeof(timeAndFlags))) != SUCCESS) {
299 return result;
300 }
301
302 m_flags = (LegoU32) timeAndFlags >> 24;
303 m_time = timeAndFlags & 0xffffff;
304 return SUCCESS;
305}
306
307// FUNCTION: LEGO1 0x1009f950
308// FUNCTION: BETA10 0x1017e018
310{
311 LegoResult result;
312 LegoS32 timeAndFlags = (LegoS32) m_time | (m_flags << 24);
313
314 if ((result = p_storage->Write(&timeAndFlags, sizeof(timeAndFlags))) != SUCCESS) {
315 return result;
316 }
317
318 return SUCCESS;
319}
320
321// FUNCTION: LEGO1 0x1009f990
323{
324 m_x = 0.0F;
325 m_y = 0.0F;
326 m_z = 0.0F;
327}
328
329// FUNCTION: LEGO1 0x1009f9b0
331{
332 LegoResult result;
333
334 if ((result = LegoAnimKey::Read(p_storage)) != SUCCESS) {
335 return result;
336 }
337
338 if ((result = p_storage->Read(&m_x, sizeof(m_x))) != SUCCESS) {
339 return result;
340 }
341
342 if ((result = p_storage->Read(&m_y, sizeof(m_y))) != SUCCESS) {
343 return result;
344 }
345
346 if ((result = p_storage->Read(&m_z, sizeof(m_z))) != SUCCESS) {
347 return result;
348 }
349
350 if (m_x > 1e-05F || m_x < -1e-05F || m_y > 1e-05F || m_y < -1e-05F || m_z > 1e-05F || m_z < -1e-05F) {
351 m_flags |= c_bit1;
352 }
353
354 return SUCCESS;
355}
356
357// FUNCTION: LEGO1 0x1009fa40
358// FUNCTION: BETA10 0x1017e1fd
360{
361 LegoResult result;
362
363 if ((result = LegoAnimKey::Write(p_storage)) != SUCCESS) {
364 return result;
365 }
366
367 if ((result = p_storage->Write(&m_x, sizeof(m_x))) != SUCCESS) {
368 return result;
369 }
370
371 if ((result = p_storage->Write(&m_y, sizeof(m_y))) != SUCCESS) {
372 return result;
373 }
374
375 if ((result = p_storage->Write(&m_z, sizeof(m_z))) != SUCCESS) {
376 return result;
377 }
378
379 return SUCCESS;
380}
381
382// FUNCTION: LEGO1 0x1009faa0
383// FUNCTION: BETA10 0x1017e2b3
385{
386 m_angle = 1.0F;
387 m_x = 0.0F;
388 m_y = 0.0F;
389 m_z = 0.0F;
390}
391
392// FUNCTION: LEGO1 0x1009fac0
394{
395 LegoResult result;
396
397 if ((result = LegoAnimKey::Read(p_storage)) != SUCCESS) {
398 return result;
399 }
400
401 if ((result = p_storage->Read(&m_angle, sizeof(m_angle))) != SUCCESS) {
402 return result;
403 }
404
405 if ((result = p_storage->Read(&m_x, sizeof(m_x))) != SUCCESS) {
406 return result;
407 }
408
409 if ((result = p_storage->Read(&m_y, sizeof(m_y))) != SUCCESS) {
410 return result;
411 }
412
413 if ((result = p_storage->Read(&m_z, sizeof(m_z))) != SUCCESS) {
414 return result;
415 }
416
417 if (m_angle != 1.0F) {
418 m_flags |= c_bit1;
419 }
420
421 return SUCCESS;
422}
423
424// FUNCTION: LEGO1 0x1009fb30
425// FUNCTION: BETA10 0x1017e3fc
427{
428 LegoResult result;
429
430 if ((result = LegoAnimKey::Write(p_storage)) != SUCCESS) {
431 return result;
432 }
433
434 if ((result = p_storage->Write(&m_angle, sizeof(m_angle))) != SUCCESS) {
435 return result;
436 }
437
438 if ((result = p_storage->Write(&m_x, sizeof(m_x))) != SUCCESS) {
439 return result;
440 }
441
442 if ((result = p_storage->Write(&m_y, sizeof(m_y))) != SUCCESS) {
443 return result;
444 }
445
446 if ((result = p_storage->Write(&m_z, sizeof(m_z))) != SUCCESS) {
447 return result;
448 }
449
450 return SUCCESS;
451}
452
453// FUNCTION: LEGO1 0x1009fba0
455{
456 m_x = 1.0F;
457 m_y = 1.0F;
458 m_z = 1.0F;
459}
460
461// FUNCTION: LEGO1 0x1009fbc0
463{
464 LegoResult result;
465
466 if ((result = LegoAnimKey::Read(p_storage)) != SUCCESS) {
467 return result;
468 }
469
470 if ((result = p_storage->Read(&m_x, sizeof(m_x))) != SUCCESS) {
471 return result;
472 }
473
474 if ((result = p_storage->Read(&m_y, sizeof(m_y))) != SUCCESS) {
475 return result;
476 }
477
478 if ((result = p_storage->Read(&m_z, sizeof(m_z))) != SUCCESS) {
479 return result;
480 }
481
482 if (m_x > 1.00001 || m_x < 0.99999 || m_y > 1.00001 || m_y < 0.99999 || m_z > 1.00001 || m_z < 0.99999) {
483 m_flags |= c_bit1;
484 }
485
486 return SUCCESS;
487}
488
489// FUNCTION: LEGO1 0x1009fc90
490// FUNCTION: BETA10 0x1017e664
492{
493 LegoResult result;
494
495 if ((result = LegoAnimKey::Write(p_storage)) != SUCCESS) {
496 return result;
497 }
498
499 if ((result = p_storage->Write(&m_x, sizeof(m_x))) != SUCCESS) {
500 return result;
501 }
502
503 if ((result = p_storage->Write(&m_y, sizeof(m_y))) != SUCCESS) {
504 return result;
505 }
506
507 if ((result = p_storage->Write(&m_z, sizeof(m_z))) != SUCCESS) {
508 return result;
509 }
510
511 return SUCCESS;
512}
513
514// FUNCTION: LEGO1 0x1009fcf0
515// FUNCTION: BETA10 0x1017e71a
517{
520 m_numScaleKeys = 0;
521 m_numMorphKeys = 0;
522
523 m_name = NULL;
525 m_unk0x20 = 0;
527 m_unk0x22 = 0;
531 m_rotationIndex = 0;
532 m_scaleIndex = 0;
533 m_morphIndex = 0;
534}
535
536// FUNCTION: LEGO1 0x1009fda0
538{
539 if (m_name) {
540 delete[] m_name;
541 }
542 if (m_translationKeys) {
543 delete[] m_translationKeys;
544 }
545 if (m_rotationKeys) {
546 delete[] m_rotationKeys;
547 }
548 if (m_scaleKeys) {
549 delete[] m_scaleKeys;
550 }
551 if (m_morphKeys) {
552 delete[] m_morphKeys;
553 }
554}
555
556// FUNCTION: LEGO1 0x1009fe60
557// FUNCTION: BETA10 0x1017e949
559{
560 LegoResult result;
561
562 LegoU32 length;
563 if ((result = p_storage->Read(&length, sizeof(length))) != SUCCESS) {
564 return result;
565 }
566
567 if (m_name) {
568 delete[] m_name;
569 m_name = NULL;
570 }
571 if (length) {
572 m_name = new LegoChar[length + 1];
573 if ((result = p_storage->Read(m_name, length)) != SUCCESS) {
574 return result;
575 }
576 m_name[length] = '\0';
577 }
578
579 LegoU32 i;
580
581 if ((result = p_storage->Read(&m_numTranslationKeys, sizeof(m_numTranslationKeys))) != SUCCESS) {
582 return result;
583 }
584 if (m_translationKeys) {
585 delete[] m_translationKeys;
587 }
590 for (i = 0; i < m_numTranslationKeys; i++) {
591 if ((result = m_translationKeys[i].Read(p_storage)) != SUCCESS) {
592 return result;
593 }
594 }
595 }
596
597 if ((result = p_storage->Read(&m_numRotationKeys, sizeof(m_numRotationKeys))) != SUCCESS) {
598 return result;
599 }
600 if (m_rotationKeys) {
601 delete[] m_rotationKeys;
603 }
604 if (m_numRotationKeys) {
606 for (i = 0; i < m_numRotationKeys; i++) {
607 if ((result = m_rotationKeys[i].Read(p_storage)) != SUCCESS) {
608 return result;
609 }
610 }
611 }
612
613 if ((result = p_storage->Read(&m_numScaleKeys, sizeof(m_numScaleKeys))) != SUCCESS) {
614 return result;
615 }
616 if (m_scaleKeys) {
617 delete[] m_scaleKeys;
619 }
620 if (m_numScaleKeys) {
622 for (i = 0; i < m_numScaleKeys; i++) {
623 if ((result = m_scaleKeys[i].Read(p_storage)) != SUCCESS) {
624 return result;
625 }
626 }
627 }
628
629 if ((result = p_storage->Read(&m_numMorphKeys, sizeof(m_numMorphKeys))) != SUCCESS) {
630 return result;
631 }
632 if (m_morphKeys) {
633 delete[] m_morphKeys;
635 }
636 if (m_numMorphKeys) {
638 for (i = 0; i < m_numMorphKeys; i++) {
639 if ((result = m_morphKeys[i].Read(p_storage)) != SUCCESS) {
640 return result;
641 }
642 }
643 }
644
645 return SUCCESS;
646}
647
648// FUNCTION: LEGO1 0x100a01e0
649// FUNCTION: BETA10 0x1017ef0f
651{
652 LegoResult result;
653 LegoU32 length = 0;
654 LegoU32 i;
655
656 if (m_name != NULL) {
657 length = strlen(m_name);
658 }
659
660 if ((result = p_storage->Write(&length, sizeof(length))) != SUCCESS) {
661 return result;
662 }
663
664 if (m_name != NULL && (result = p_storage->Write(m_name, length)) != SUCCESS) {
665 return result;
666 }
667
668 if ((result = p_storage->Write(&m_numTranslationKeys, sizeof(m_numTranslationKeys))) != SUCCESS) {
669 return result;
670 }
671 if (m_numTranslationKeys != 0) {
672 for (i = 0; i < m_numTranslationKeys; i++) {
673 if ((result = m_translationKeys[i].Write(p_storage)) != SUCCESS) {
674 return result;
675 }
676 }
677 }
678
679 if ((result = p_storage->Write(&m_numRotationKeys, sizeof(m_numRotationKeys))) != SUCCESS) {
680 return result;
681 }
682 if (m_numRotationKeys != 0) {
683 for (i = 0; i < m_numRotationKeys; i++) {
684 if ((result = m_rotationKeys[i].Write(p_storage)) != SUCCESS) {
685 return result;
686 }
687 }
688 }
689
690 if ((result = p_storage->Write(&m_numScaleKeys, sizeof(m_numScaleKeys))) != SUCCESS) {
691 return result;
692 }
693 if (m_numScaleKeys != 0) {
694 for (i = 0; i < m_numScaleKeys; i++) {
695 if ((result = m_scaleKeys[i].Write(p_storage)) != SUCCESS) {
696 return result;
697 }
698 }
699 }
700
701 if ((result = p_storage->Write(&m_numMorphKeys, sizeof(m_numMorphKeys))) != SUCCESS) {
702 return result;
703 }
704 if (m_numMorphKeys != 0) {
705 for (i = 0; i < m_numMorphKeys; i++) {
706 if ((result = m_morphKeys[i].Write(p_storage)) != SUCCESS) {
707 return result;
708 }
709 }
710 }
711
712 return SUCCESS;
713}
714
715// FUNCTION: LEGO1 0x100a0360
716// FUNCTION: BETA10 0x1017f1e5
718{
719 if (m_name != NULL) {
720 delete[] m_name;
721 }
722
723 m_name = new LegoChar[strlen(p_name) + 1];
724 strcpy(m_name, p_name);
725}
726
727// FUNCTION: LEGO1 0x100a03c0
729{
730 LegoU32 index;
731
732 if (m_scaleKeys != NULL) {
733 index = GetScaleIndex();
734 GetScale(m_numScaleKeys, m_scaleKeys, p_time, p_matrix, index);
735 SetScaleIndex(index);
736
737 if (m_rotationKeys != NULL) {
738 MxMatrix a, b;
739 a.SetIdentity();
740
741 index = GetRotationIndex();
742 GetRotation(m_numRotationKeys, m_rotationKeys, p_time, a, index);
743 SetRotationIndex(index);
744
745 b = p_matrix;
746 p_matrix.Product(b, a);
747 }
748 }
749 else if (m_rotationKeys != NULL) {
750 index = GetRotationIndex();
751 GetRotation(m_numRotationKeys, m_rotationKeys, p_time, p_matrix, index);
752 SetRotationIndex(index);
753 }
754
755 if (m_translationKeys != NULL) {
756 index = GetTranslationIndex();
757 GetTranslation(m_numTranslationKeys, m_translationKeys, p_time, p_matrix, index);
758 SetTranslationIndex(index);
759 }
760
761 return SUCCESS;
762}
763
764// FUNCTION: LEGO1 0x100a0600
766 LegoU16 p_numTranslationKeys,
767 LegoTranslationKey* p_translationKeys,
768 LegoFloat p_time,
769 Matrix4& p_matrix,
770 LegoU32& p_old_index
771)
772{
773 LegoU32 i, n;
774 LegoFloat x, y, z;
775 n = FindKeys(
776 p_time,
777 p_numTranslationKeys & USHRT_MAX,
778 p_translationKeys,
779 sizeof(*p_translationKeys),
780 i,
781 p_old_index
782 );
783
784 switch (n) {
785 case 0:
786 return;
787 case 1:
788 if (!p_translationKeys[i].TestBit1()) {
789 return;
790 }
791
792 x = p_translationKeys[i].GetX();
793 y = p_translationKeys[i].GetY();
794 z = p_translationKeys[i].GetZ();
795 break;
796 case 2:
797 if (!p_translationKeys[i].TestBit1() && !p_translationKeys[i + 1].TestBit1()) {
798 return;
799 }
800
801 x = Interpolate(
802 p_time,
803 p_translationKeys[i],
804 p_translationKeys[i].GetX(),
805 p_translationKeys[i + 1],
806 p_translationKeys[i + 1].GetX()
807 );
808 y = Interpolate(
809 p_time,
810 p_translationKeys[i],
811 p_translationKeys[i].GetY(),
812 p_translationKeys[i + 1],
813 p_translationKeys[i + 1].GetY()
814 );
815 z = Interpolate(
816 p_time,
817 p_translationKeys[i],
818 p_translationKeys[i].GetZ(),
819 p_translationKeys[i + 1],
820 p_translationKeys[i + 1].GetZ()
821 );
822 break;
823 }
824
825 p_matrix.TranslateBy(x, y, z);
826}
827
828// FUNCTION: LEGO1 0x100a06f0
830 LegoU16 p_numRotationKeys,
831 LegoRotationKey* p_rotationKeys,
832 LegoFloat p_time,
833 Matrix4& p_matrix,
834 LegoU32& p_old_index
835)
836{
837 LegoU32 i, n;
838 n = FindKeys(p_time, p_numRotationKeys & USHRT_MAX, p_rotationKeys, sizeof(*p_rotationKeys), i, p_old_index);
839
840 switch (n) {
841 case 0:
842 return;
843 case 1:
844 if (p_rotationKeys[i].TestBit1()) {
846 p_rotationKeys[i].GetX(),
847 p_rotationKeys[i].GetY(),
848 p_rotationKeys[i].GetZ(),
849 p_rotationKeys[i].GetAngle()
850 ));
851 }
852 break;
853 case 2:
856
857 if (p_rotationKeys[i].TestBit1() || p_rotationKeys[i + 1].TestBit1()) {
858 a[0] = p_rotationKeys[i].GetX();
859 a[1] = p_rotationKeys[i].GetY();
860 a[2] = p_rotationKeys[i].GetZ();
861 a[3] = p_rotationKeys[i].GetAngle();
862
863 if (p_rotationKeys[i + 1].TestBit3()) {
864 p_matrix.FromQuaternion(a);
865 return;
866 }
867
869 if (p_rotationKeys[i + 1].TestBit2()) {
870 c[0] = -p_rotationKeys[i + 1].GetX();
871 c[1] = -p_rotationKeys[i + 1].GetY();
872 c[2] = -p_rotationKeys[i + 1].GetZ();
873 c[3] = -p_rotationKeys[i + 1].GetAngle();
874 }
875 else {
876 c[0] = p_rotationKeys[i + 1].GetX();
877 c[1] = p_rotationKeys[i + 1].GetY();
878 c[2] = p_rotationKeys[i + 1].GetZ();
879 c[3] = p_rotationKeys[i + 1].GetAngle();
880 }
881
882 b.SetStart(a);
883 b.SetEnd(c);
885 p_matrix,
886 (p_time - p_rotationKeys[i].GetTime()) / (p_rotationKeys[i + 1].GetTime() - p_rotationKeys[i].GetTime())
887 );
888 }
889 }
890}
891
893 LegoU16 p_numScaleKeys,
894 LegoScaleKey* p_scaleKeys,
895 LegoFloat p_time,
896 Matrix4& p_matrix,
897 LegoU32& p_old_index
898)
899{
900 LegoU32 i, n;
901 LegoFloat x, y, z;
902 n = FindKeys(p_time, p_numScaleKeys & USHRT_MAX, p_scaleKeys, sizeof(*p_scaleKeys), i, p_old_index);
903
904 switch (n) {
905 case 0:
906 return;
907 case 1:
908 x = p_scaleKeys[i].GetX();
909 y = p_scaleKeys[i].GetY();
910 z = p_scaleKeys[i].GetZ();
911 break;
912 case 2:
913 x = Interpolate(p_time, p_scaleKeys[i], p_scaleKeys[i].GetX(), p_scaleKeys[i + 1], p_scaleKeys[i + 1].GetX());
914 y = Interpolate(p_time, p_scaleKeys[i], p_scaleKeys[i].GetY(), p_scaleKeys[i + 1], p_scaleKeys[i + 1].GetY());
915 z = Interpolate(p_time, p_scaleKeys[i], p_scaleKeys[i].GetZ(), p_scaleKeys[i + 1], p_scaleKeys[i + 1].GetZ());
916 break;
917 }
918
919 p_matrix.Scale(x, y, z);
920}
921
922// FUNCTION: LEGO1 0x100a0990
924{
925 LegoU32 i, n;
926 LegoU32 index = GetMorphIndex();
927 LegoBool result;
928
929 n = FindKeys(p_time, m_numMorphKeys, m_morphKeys, sizeof(*m_morphKeys), i, index);
930 SetMorphIndex(index);
931
932 switch (n) {
933 case 0:
934 result = TRUE;
935 break;
936 case 1:
937 case 2:
938 result = m_morphKeys[i].GetUnknown0x08();
939 break;
940 }
941
942 return result;
943}
944
945// FUNCTION: LEGO1 0x100a0a00
947 LegoFloat p_time,
948 LegoU32 p_numKeys,
949 LegoAnimKey* p_keys,
950 LegoU32 p_size,
951 LegoU32& p_new_index,
952 LegoU32& p_old_index
953)
954{
955 LegoU32 numKeys;
956 if (p_numKeys == 0) {
957 numKeys = 0;
958 }
959 else if (p_time < GetKey(0, p_keys, p_size).GetTime()) {
960 numKeys = 0;
961 }
962 else if (p_time > GetKey(p_numKeys - 1, p_keys, p_size).GetTime()) {
963 p_new_index = p_numKeys - 1;
964 numKeys = 1;
965 }
966 else {
967 if (GetKey(p_old_index, p_keys, p_size).GetTime() <= p_time) {
968 for (p_new_index = p_old_index;
969 p_new_index < p_numKeys - 1 && p_time >= GetKey(p_new_index + 1, p_keys, p_size).GetTime();
970 p_new_index++) {
971 }
972 }
973 else {
974 for (p_new_index = 0;
975 p_new_index < p_numKeys - 1 && p_time >= GetKey(p_new_index + 1, p_keys, p_size).GetTime();
976 p_new_index++) {
977 }
978 }
979
980 p_old_index = p_new_index;
981 if (p_time == GetKey(p_new_index, p_keys, p_size).GetTime()) {
982 numKeys = 1;
983 }
984 else if (p_new_index < p_numKeys - 1) {
985 numKeys = 2;
986 }
987 else {
988 numKeys = 0;
989 }
990 }
991
992 return numKeys;
993}
994
995// FUNCTION: LEGO1 0x100a0b00
997 LegoFloat p_time,
998 LegoAnimKey& p_key1,
999 LegoFloat p_value1,
1000 LegoAnimKey& p_key2,
1001 LegoFloat p_value2
1002)
1003{
1004 return p_value1 + (p_value2 - p_value1) * (p_time - p_key1.GetTime()) / (p_key2.GetTime() - p_key1.GetTime());
1005}
1006
1008{
1009 return *((LegoAnimKey*) (((LegoU8*) p_keys) + (p_i * p_size)));
1010}
1011
1012// FUNCTION: LEGO1 0x100a0b30
1014{
1015 m_duration = 0;
1016 m_modelList = NULL;
1017 m_numActors = 0;
1018 m_camAnim = NULL;
1019}
1020
1021// FUNCTION: LEGO1 0x100a0bc0
1023{
1024 if (m_modelList != NULL) {
1025 for (LegoU32 i = 0; i < m_numActors; i++) {
1026 delete[] m_modelList[i].m_name;
1027 }
1028
1029 delete[] m_modelList;
1030 }
1031
1032 if (m_camAnim != NULL) {
1033 delete m_camAnim;
1034 }
1035}
1036
1037// FUNCTION: LEGO1 0x100a0c70
1039{
1040 LegoResult result = FAILURE;
1041 LegoU32 length, i;
1042
1043 if (p_storage->Read(&length, sizeof(length)) != SUCCESS) {
1044 goto done;
1045 }
1046
1047 m_modelList = new LegoAnimActorEntry[length];
1048 m_numActors = 0;
1049
1050 for (i = 0; i < length; i++) {
1051 LegoU32 length;
1052 if (p_storage->Read(&length, sizeof(length)) != SUCCESS) {
1053 goto done;
1054 }
1055
1056 if (length) {
1057 m_modelList[i].m_name = new LegoChar[length + 1];
1058
1059 if (p_storage->Read(m_modelList[i].m_name, length) != SUCCESS) {
1060 goto done;
1061 }
1062
1063 m_modelList[i].m_name[length] = '\0';
1064
1065 if (p_storage->Read(&m_modelList[i].m_unk0x04, sizeof(m_modelList[i].m_unk0x04)) != SUCCESS) {
1066 goto done;
1067 }
1068 }
1069
1070 m_numActors++;
1071 }
1072
1073 if ((result = p_storage->Read(&m_duration, sizeof(m_duration))) != SUCCESS) {
1074 goto done;
1075 }
1076
1077 if (p_parseScene) {
1078 m_camAnim = new LegoAnimScene();
1079
1080 result = m_camAnim->Read(p_storage);
1081
1082 if (result != SUCCESS) {
1083 goto done;
1084 }
1085 }
1086
1087 result = LegoTree::Read(p_storage);
1088
1089done:
1090 if (result != SUCCESS && m_modelList != NULL) {
1091 for (i = 0; i < m_numActors; i++) {
1092 delete[] m_modelList[i].m_name;
1093 }
1094
1095 m_numActors = 0;
1096 delete[] m_modelList;
1097 m_modelList = NULL;
1098 }
1099
1100 return result;
1101}
1102
1103// FUNCTION: LEGO1 0x100a0e30
1104// FUNCTION: BETA10 0x1017fe3a
1106{
1107 LegoResult result = FAILURE;
1108 LegoU32 i;
1109
1110 if (p_storage->Write(&m_numActors, sizeof(m_numActors)) != SUCCESS) {
1111 goto done;
1112 }
1113
1114 for (i = 0; i < m_numActors; i++) {
1115 LegoU32 length = strlen(m_modelList[i].m_name);
1116
1117 if (p_storage->Write(&length, sizeof(length)) != SUCCESS) {
1118 goto done;
1119 }
1120
1121 if (length != 0) {
1122 if (p_storage->Write(m_modelList[i].m_name, length) != SUCCESS) {
1123 goto done;
1124 }
1125
1126 if (p_storage->Write(&m_modelList[i].m_unk0x04, sizeof(m_modelList[i].m_unk0x04)) != SUCCESS) {
1127 goto done;
1128 }
1129 }
1130 }
1131
1132 if (p_storage->Write(&m_duration, sizeof(m_duration)) != SUCCESS) {
1133 goto done;
1134 }
1135
1136 if (m_camAnim != NULL) {
1137 if (m_camAnim->Write(p_storage) != SUCCESS) {
1138 goto done;
1139 }
1140 }
1141
1142 result = LegoTree::Write(p_storage);
1143
1144done:
1145 return result;
1146}
1147
1148// FUNCTION: LEGO1 0x100a0f20
1149// FUNCTION: BETA10 0x101801fd
1151{
1152 if (p_index < m_numActors) {
1153 return m_modelList[p_index].m_name;
1154 }
1155
1156 return NULL;
1157}
1158
1159// FUNCTION: LEGO1 0x100a0f40
1160// FUNCTION: BETA10 0x1018023c
1162{
1163 if (p_index < m_numActors) {
1164 return m_modelList[p_index].m_unk0x04;
1165 }
1166
1167 return 0;
1168}
1169
1170// FUNCTION: LEGO1 0x100a0f60
1171// FUNCTION: BETA10 0x1018027c
1173{
1174 m_unk0x08 = 0;
1175}
1176
1177// FUNCTION: LEGO1 0x100a0f70
1179{
1180 LegoResult result;
1181
1182 if ((result = LegoAnimKey::Read(p_storage)) != SUCCESS) {
1183 return result;
1184 }
1185
1186 if ((result = p_storage->Read(&m_unk0x08, sizeof(m_unk0x08))) != SUCCESS) {
1187 return result;
1188 }
1189
1190 return SUCCESS;
1191}
1192
1193// FUNCTION: LEGO1 0x100a0fb0
1194// FUNCTION: BETA10 0x10180308
1196{
1197 LegoResult result;
1198
1199 if ((result = LegoAnimKey::Write(p_storage)) != SUCCESS) {
1200 return result;
1201 }
1202
1203 if ((result = p_storage->Write(&m_unk0x08, sizeof(m_unk0x08))) != SUCCESS) {
1204 return result;
1205 }
1206
1207 return SUCCESS;
1208}
[AI] Represents a single generic animation keyframe, containing timing and per-keyframe flags.
Definition: legoanim.h:12
LegoFloat GetTime()
[AI] Retrieves the time (frame/tick) of this key.
Definition: legoanim.h:24
@ c_bit1
[AI] Indicates if the key affects the output (meaning depends on derived type).
Definition: legoanim.h:16
LegoAnimKey()
[AI] Constructs an animation key with zero time and cleared flags.
Definition: legoanim.cpp:286
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the animation key to storage.
Definition: legoanim.cpp:309
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the animation key from storage.
Definition: legoanim.cpp:293
LegoFloat m_time
[AI] Time/sample/frame when this key occurs.
Definition: legoanim.h:46
LegoU8 m_flags
[AI] Flags controlling key behavior or interpolation (see Flags enum).
Definition: legoanim.h:45
[AI] Holds per-node animation data for a model's animation tree.
Definition: legoanim.h:144
LegoU32 GetRotationIndex()
[AI] Gets last used/optimized rotation index for interpolation.
Definition: legoanim.h:176
LegoRotationKey * m_rotationKeys
[AI] Array of rotation keyframes.
Definition: legoanim.h:300
static LegoAnimKey & GetKey(LegoU32 p_i, LegoAnimKey *p_keys, LegoU32 p_size)
[AI] Retrieves a reference to the p_i-th LegoAnimKey of given size.
Definition: legoanim.cpp:1007
LegoU32 m_rotationIndex
[AI] Index cache for optimized rotation lookup/interpolation.
Definition: legoanim.h:306
LegoU16 m_numTranslationKeys
[AI] Number of translation keyframes.
Definition: legoanim.h:295
LegoChar * m_name
[AI] Animation node name.
Definition: legoanim.h:294
void SetScaleIndex(LegoU32 p_scaleIndex)
[AI] Sets last used scale index.
Definition: legoanim.h:189
LegoU32 m_morphIndex
[AI] Index cache for optimized morph lookup/interpolation.
Definition: legoanim.h:308
LegoU16 m_numScaleKeys
[AI] Number of scale keyframes.
Definition: legoanim.h:297
~LegoAnimNodeData() override
[AI] Cleans up all allocated animation key arrays and the node name. [AI]
Definition: legoanim.cpp:537
LegoU16 m_numRotationKeys
[AI] Number of rotation keyframes.
Definition: legoanim.h:296
static LegoFloat Interpolate(LegoFloat p_time, LegoAnimKey &p_key1, LegoFloat p_value1, LegoAnimKey &p_key2, LegoFloat p_value2)
[AI] Performs linear interpolation between two key values for the given time.
Definition: legoanim.cpp:996
void SetTranslationIndex(LegoU32 p_translationIndex)
[AI] Sets last used translation index.
Definition: legoanim.h:187
LegoAnimNodeData()
[AI] Default-initializes all animation key counts to zero and pointers to NULL. [AI]
Definition: legoanim.cpp:516
static void GetTranslation(LegoU16 p_numTranslationKeys, LegoTranslationKey *p_translationKeys, LegoFloat p_time, Matrix4 &p_matrix, LegoU32 &p_old_index)
[AI] Computes interpolated translation for a node at specified time, filling p_matrix.
Definition: legoanim.cpp:765
LegoResult CreateLocalTransform(LegoFloat p_time, Matrix4 &p_matrix)
[AI] Computes the interpolated local transformation matrix for this node at the given animation time.
Definition: legoanim.cpp:728
LegoU32 GetScaleIndex()
[AI] Gets last used/optimized scale index for interpolation.
Definition: legoanim.h:177
void SetMorphIndex(LegoU32 p_morphIndex)
[AI] Sets last used morph index.
Definition: legoanim.h:190
LegoScaleKey * m_scaleKeys
[AI] Array of scale keyframes.
Definition: legoanim.h:301
LegoResult Read(LegoStorage *p_storage) override
[AI] Reads all node keyframe arrays, name, and meta from storage.
Definition: legoanim.cpp:558
LegoBool FUN_100a0990(LegoFloat p_time)
[AI] Evaluates morph keys at the given animation time and returns result (typically affects mesh shap...
Definition: legoanim.cpp:923
void SetName(LegoChar *p_name)
[AI] Sets the node's name (deep-copies string).
Definition: legoanim.cpp:717
LegoMorphKey * m_morphKeys
[AI] Array of morph keyframes.
Definition: legoanim.h:302
LegoU32 GetTranslationIndex()
[AI] Gets last used/optimized translation index for interpolation.
Definition: legoanim.h:175
static void GetScale(LegoU16 p_numScaleKeys, LegoScaleKey *p_scaleKeys, LegoFloat p_time, Matrix4 &p_matrix, LegoU32 &p_old_index)
[AI] Computes interpolated scaling on a node at given time, updating p_matrix.
Definition: legoanim.cpp:892
LegoTranslationKey * m_translationKeys
[AI] Array of translation keyframes.
Definition: legoanim.h:299
void SetRotationIndex(LegoU32 p_rotationIndex)
[AI] Sets last used rotation index.
Definition: legoanim.h:188
LegoU32 m_scaleIndex
[AI] Index cache for optimized scale lookup/interpolation.
Definition: legoanim.h:307
static LegoU32 FindKeys(LegoFloat p_time, LegoU32 p_numKeys, LegoAnimKey *p_keys, LegoU32 p_size, LegoU32 &p_new_index, LegoU32 &p_old_index)
[AI] Finds surrounding key(s) for interpolation at p_time.
Definition: legoanim.cpp:946
LegoResult Write(LegoStorage *p_storage) override
[AI] Writes all node keyframe arrays, name, and meta to storage.
Definition: legoanim.cpp:650
static void GetRotation(LegoU16 p_numRotationKeys, LegoRotationKey *p_rotationKeys, LegoFloat p_time, Matrix4 &p_matrix, LegoU32 &p_old_index)
[AI] Computes interpolated rotation at a given time, filling p_matrix.
Definition: legoanim.cpp:829
LegoU16 m_unk0x22
[AI] Unknown, used in camera/scene morph/rotation (purpose unclear).
Definition: legoanim.h:304
LegoU32 m_translationIndex
[AI] Index cache for optimized translation lookup/interpolation.
Definition: legoanim.h:305
LegoU32 GetMorphIndex()
[AI] Gets last used/optimized morph index for interpolation.
Definition: legoanim.h:178
LegoU16 m_unk0x20
[AI] Unknown, used in camera/scene morph/rotation (purpose unclear).
Definition: legoanim.h:303
LegoU16 m_numMorphKeys
[AI] Number of morph keyframes.
Definition: legoanim.h:298
[AI] Represents an animation scene; possibly used for camera motion or global transforms.
Definition: legoanim.h:321
LegoU32 GetUnknown0x1c()
[AI] Cached index for translation key interpolation (for second translation key array).
Definition: legoanim.h:334
LegoResult FUN_1009f490(LegoFloat p_time, Matrix4 &p_matrix)
[AI] Evaluates this scene's animation at the given time, updating the passed matrix.
Definition: legoanim.cpp:202
LegoAnimScene()
[AI] Default construction, zeroes all data pointers and counters.
Definition: legoanim.cpp:59
~LegoAnimScene()
[AI] Destroys the scene, frees all allocated key arrays.
Definition: legoanim.cpp:73
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the entire scene data to storage, including all translation/unknown key arrays.
Definition: legoanim.cpp:93
LegoResult Read(LegoStorage *p_storage)
[AI] Reads the entire scene data from storage, including all translation/unknown key arrays.
Definition: legoanim.cpp:135
void SetUnknown0x18(LegoU32 p_unk0x18)
[AI] Sets cached translation index (first stream).
Definition: legoanim.h:337
void SetUnknown0x1c(LegoU32 p_unk0x1c)
[AI] Sets cached translation index (second stream).
Definition: legoanim.h:338
void SetUnknown0x20(LegoU32 p_unk0x20)
[AI] Sets cached key interpolation index (unknown key type).
Definition: legoanim.h:339
LegoU32 GetUnknown0x20()
[AI] Cached index for unknown key interpolation.
Definition: legoanim.h:335
LegoU32 GetUnknown0x18()
[AI] Cached index for translation key interpolation (for first translation key array).
Definition: legoanim.h:333
[AI] Root class for all node-based animation blending/structure.
Definition: legoanim.h:356
LegoAnimActorEntry * m_modelList
[AI] Array of actor/model entries animated by this object.
Definition: legoanim.h:382
virtual LegoResult Read(LegoStorage *p_storage, LegoS32 p_parseScene)
[AI] Loads model and animation data from storage, optionally including scene/camera animation.
Definition: legoanim.cpp:1038
LegoAnimScene * m_camAnim
[AI] Pointer to camera/scene animation (may be nullptr).
Definition: legoanim.h:384
LegoU32 m_numActors
[AI] Number of actors/models.
Definition: legoanim.h:383
~LegoAnim() override
[AI] Destructor, deallocates actors and camera animation.
Definition: legoanim.cpp:1022
undefined4 GetActorUnknown0x04(LegoU32 p_index)
[AI] Gets the actor's "unk0x04" property at a given index.
Definition: legoanim.cpp:1161
LegoTime m_duration
[AI] Animation duration in time units.
Definition: legoanim.h:381
LegoAnim()
[AI] Constructs an empty animation object, with no actors or tracks.
Definition: legoanim.cpp:1013
const LegoChar * GetActorName(LegoU32 p_index)
[AI] Gets the name of the actor at a given index.
Definition: legoanim.cpp:1150
LegoResult Write(LegoStorage *p_storage) override
[AI] Serializes all model and animation data to storage.
Definition: legoanim.cpp:1105
[AI] Animation key for morphing states or mesh morphing.
Definition: legoanim.h:115
LegoBool GetUnknown0x08()
[AI] Gets the morph Boolean value (meaning unknown).
Definition: legoanim.h:120
LegoMorphKey()
[AI] Constructs a morph key with an unset ("off") state.
Definition: legoanim.cpp:1172
LegoBool m_unk0x08
[AI][AI_SUGGESTED_NAME: m_morphState] Morphing state or flag at this key (meaning unknown).
Definition: legoanim.h:124
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the morph key to storage.
Definition: legoanim.cpp:1195
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the morph key from storage.
Definition: legoanim.cpp:1178
[AI] Animation key class for rotations (axis-angle format).
Definition: legoanim.h:71
LegoFloat GetY()
[AI] Gets the Y-axis of the rotation.
Definition: legoanim.h:81
LegoFloat m_z
[AI] Axis-angle rotation: Z component.
Definition: legoanim.h:90
LegoRotationKey()
[AI] Constructs a rotation key with default (identity) rotation.
Definition: legoanim.cpp:384
LegoFloat m_x
[AI] Axis-angle rotation: X component.
Definition: legoanim.h:88
LegoFloat GetZ()
[AI] Gets the Z-axis of the rotation.
Definition: legoanim.h:83
LegoFloat m_y
[AI] Axis-angle rotation: Y component.
Definition: legoanim.h:89
LegoFloat GetX()
[AI] Gets the X-axis of the rotation.
Definition: legoanim.h:79
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the rotation key from storage.
Definition: legoanim.cpp:393
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the rotation key to storage.
Definition: legoanim.cpp:426
LegoFloat GetAngle()
[AI] Gets the rotation angle (around the axis).
Definition: legoanim.h:77
LegoFloat m_angle
[AI] Axis-angle rotation: the angle value.
Definition: legoanim.h:87
[AI] Animation key class for scaling transformations.
Definition: legoanim.h:95
LegoFloat GetX()
[AI] Gets the scaling X factor.
Definition: legoanim.h:100
LegoFloat m_x
[AI] Scale along the X-axis.
Definition: legoanim.h:108
LegoFloat m_z
[AI] Scale along the Z-axis.
Definition: legoanim.h:110
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the scale key to storage.
Definition: legoanim.cpp:491
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the scale key from storage.
Definition: legoanim.cpp:462
LegoFloat GetZ()
[AI] Gets the scaling Z factor.
Definition: legoanim.h:104
LegoFloat m_y
[AI] Scale along the Y-axis.
Definition: legoanim.h:109
LegoFloat GetY()
[AI] Gets the scaling Y factor.
Definition: legoanim.h:102
LegoScaleKey()
[AI] Constructs a scale key (default: scale factor 1,1,1).
Definition: legoanim.cpp:454
Abstract base class providing an interface for file-like storage with binary and text read/write oper...
Definition: legostorage.h:16
virtual LegoResult Write(const void *p_buffer, LegoU32 p_size)=0
Write bytes from buffer into storage.
virtual LegoResult Read(void *p_buffer, LegoU32 p_size)=0
Read bytes from storage into buffer.
[AI] Animation key class for translations (vector 3D positions).
Definition: legoanim.h:51
LegoFloat m_y
[AI] Translation along Y-axis.
Definition: legoanim.h:65
LegoTranslationKey()
[AI] Constructs a translation key with all translation components set to zero.
Definition: legoanim.cpp:322
LegoFloat m_z
[AI] Translation along Z-axis.
Definition: legoanim.h:66
LegoFloat m_x
[AI] Translation along X-axis.
Definition: legoanim.h:64
LegoFloat GetZ()
[AI] Gets the translation Z component.
Definition: legoanim.h:60
LegoFloat GetX()
[AI] Gets the translation X component.
Definition: legoanim.h:56
LegoFloat GetY()
[AI] Gets the translation Y component.
Definition: legoanim.h:58
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes this translation key from storage.
Definition: legoanim.cpp:330
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes this translation key to storage.
Definition: legoanim.cpp:359
virtual LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the tree structure recursively to the given storage.
Definition: legotree.cpp:52
virtual LegoResult Read(LegoStorage *p_storage)
[AI] Loads the tree structure recursively from the given storage.
Definition: legotree.cpp:46
[AI] Animation key of unknown type, used internally by camera/track animation.
Definition: legoanim.h:129
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the unknown key from storage.
Definition: legoanim.cpp:26
LegoFloat m_z
[AI][AI_SUGGESTED_NAME: m_angleOrZ] Tracks either a Z translation or angle for camera movement.
Definition: legoanim.h:138
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the unknown key to storage.
Definition: legoanim.cpp:43
4x4 Matrix class with virtual interface for manipulation and transformation.
Definition: matrix.h:24
virtual float(* GetData())[4]
Gets modifiable access to the 4x4 float matrix.
virtual void TranslateBy(const float &p_x, const float &p_y, const float &p_z)
Applies translation by amounts along X, Y, Z axes.
void Scale(const float &p_x, const float &p_y, const float &p_z)
Applies scaling factors along X, Y, and Z axes.
void RotateZ(const float &p_angle)
Applies a rotation (in radians or degrees) about the Z axis.
virtual void Product(float(*p_a)[4], float(*p_b)[4])
Multiplies two 4x4 float matrices, storing result in this.
virtual void SetIdentity()
Sets this matrix to identity (diagonal 1, others 0).
virtual int FromQuaternion(const Vector4 &p_vec)
Initializes the matrix from a quaternion (Vector4).
[AI] Represents a 3D point with floating-point precision, inheriting from Vector3.
Definition: mxgeometry3d.h:14
[AI] 4D point class for floating point values.
Definition: mxgeometry4d.h:18
[AI] Represents a 4x4 transformation matrix, specialized for the LEGO Island engine and derived from ...
Definition: mxmatrix.h:16
Quaternion interpolation utility for 4D transformations, supporting quaternion start/end points and s...
Definition: mxquaternion.h:14
void SetEnd(Matrix4 &p_m)
Sets the end quaternion from a matrix.
void SetStart(Matrix4 &p_m)
Sets the start quaternion from a matrix.
int InterpolateToMatrix(Matrix4 &p_matrix, float p_f)
Interpolates between start and end quaternions using spherical interpolation (slerp) and produces a 4...
virtual int Unitize()
[AI] Scales the vector so its norm is 1 (unit vector).
[AI] 3D vector class, providing vector and cross-product operations in 3D space.
Definition: vector.h:249
void Clear() override
[AI] Sets every coordinate (x, y, z) to zero.
virtual void EqualsCross(const Vector3 &p_a, const Vector3 &p_b)
[AI] Sets this vector to be the cross product of p_a and p_b.
#define TRUE
Definition: d3drmdef.h:28
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
unsigned int undefined4
Definition: decomp.h:28
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
unsigned long LegoU32
[AI] Unsigned 32-bit integer type for cross-platform compatibility.
Definition: legotypes.h:71
char LegoChar
[AI] Alias for char, for use in character/byte data and string handling.
Definition: legotypes.h:83
#define FAILURE
[AI] Used to indicate a failed operation in result codes.
Definition: legotypes.h:34
unsigned char LegoU8
[AI] Unsigned 8-bit integer type used throughout LEGO Island.
Definition: legotypes.h:47
LegoS32 LegoResult
[AI] Function result type (return code): typically SUCCESS (0) or FAILURE (-1).
Definition: legotypes.h:101
long LegoS32
[AI] Signed 32-bit integer type for cross-platform compatibility.
Definition: legotypes.h:65
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
Definition: legotypes.h:30
unsigned short LegoU16
[AI] Unsigned 16-bit integer type for cross-platform compatibility.
Definition: legotypes.h:59
float LegoFloat
[AI] Floating point type used throughout LEGO Island.
Definition: legotypes.h:77
LegoU8 LegoBool
[AI] Boolean value used throughout the codebase.
Definition: legotypes.h:89
[AI] Describes a single actor or model referenced by an animation.
Definition: legoanim.h:313
LegoChar * m_name
[AI] Name of the actor/model.
Definition: legoanim.h:314
undefined4 m_unk0x04
[AI] Unknown. May refer to a flag, index, or property (purpose unclear). [AI_SUGGESTED_NAME: m_actorP...
Definition: legoanim.h:315