Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
animator.c
Go to the documentation of this file.
1#include "model.h"
2#include "animation_script.h"
3#include "model.h"
4
5typedef struct DisplayListBufferHandle {
6 /* 0x0 */ s32 ttl;
7 /* 0x4 */ void* addr;
8} DisplayListBufferHandle; // size = 0x8
9
11
13
32
33extern Gfx Gfx_RM1_SURFACE_OPA[];
34extern Gfx Gfx_RM1_DECAL_OPA[];
35extern Gfx Gfx_RM1_INTERSECTING_OPA[];
36extern Gfx Gfx_RM1_ALPHATEST[];
37extern Gfx Gfx_RM1_SURFACE_XLU[];
38extern Gfx Gfx_RM1_DECAL_XLU[];
39extern Gfx Gfx_RM1_INTERSECTING_XLU[];
40extern Gfx Gfx_RM3_SURFACE_OPA[];
41extern Gfx Gfx_RM3_DECAL_OPA[];
42extern Gfx Gfx_RM3_INTERSECTING_OPA[];
43extern Gfx Gfx_RM3_ALPHATEST[];
44extern Gfx Gfx_RM3_SURFACE_XLU[];
45extern Gfx Gfx_RM3_DECAL_XLU[];
46extern Gfx Gfx_RM3_INTERSECTING_XLU[];
47
52
54
55// copy Vtx array from node->fcData.vtxList, but overwrite xyz coordinates with ones from buffer
56// if animator has own vertexArray, buffer is offset within it
62 s32 i;
63
64 for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
65 handle = &D_801533C0[i];
66 if (handle->ttl < 0) {
67 break;
68 }
69 }
70
72
73 bufferMem = general_heap_malloc((vtxCount + overhead) * sizeof(*bufferMem));
74 handle->addr = bufferMem;
75
76 ASSERT(bufferMem != nullptr);
77
78 handle->ttl = 3;
79 nodeVtxList = &node->fcData.vtxList[startIdx];
80
81 if (animator->baseAddr != nullptr) {
82 i = ((s32)buffer & 0xFFFFFF); // needed to match
83 buffer = (Vec3s*)(i + (s32)animator->baseAddr);
84 }
85
86 for (i = 0; i < vtxCount; i++) {
88 bufferMem->v.ob[0] = buffer->x;
89 bufferMem->v.ob[1] = buffer->y;
90 bufferMem->v.ob[2] = buffer->z;
91 bufferMem++;
92 buffer++;
94 }
95 return handle->addr;
96}
97
99 guMtxIdentF(mtx);
100 mtx[0][0] = 1.0f;
101 mtx[1][1] = 1.0f;
102 mtx[2][2] = -1.0f;
103 mtx[3][3] = 1.0f;
104}
105
107 guMtxIdentF(mtx);
108 mtx[0][0] = 1.0f;
109 mtx[1][1] = -1.0f;
110 mtx[2][2] = 1.0f;
111 mtx[3][3] = 1.0f;
112}
113
115 guMtxIdentF(mtx);
116 mtx[0][0] = -1.0f;
117 mtx[1][1] = 1.0f;
118 mtx[2][2] = 1.0f;
119 mtx[3][3] = 1.0f;
120}
121
123 guMtxIdentF(mtx);
124 mtx[0][0] = 1.0f;
125 mtx[1][1] = 1.0f;
126 mtx[2][2] = 1.0f;
127 mtx[3][3] = 1.0f;
128}
129
131 s32 i;
132
133 if (node->uniqueIndex == id) {
134 return node;
135 }
136
137 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
138 if (node->children[i] != nullptr) {
139 AnimatorNode* child = get_animator_child_with_id_helper(node->children[i], id);
140 if (child != nullptr) {
141 return child;
142 }
143 }
144 }
145
146 return nullptr;
147}
148
150 AnimatorNode *node = animator->rootNode;
151 s32 i;
152
153 if (animator->nodeCache[id] != nullptr && animator->nodeCache[id]->uniqueIndex == id) {
154 return animator->nodeCache[id];
155 }
156 if (node->uniqueIndex == id) {
157 return node;
158 }
159
160 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
161 if (node->children[i] != nullptr) {
162 AnimatorNode* child = get_animator_child_with_id_helper(node->children[i], id);
163
164 if (child != nullptr) {
165 animator->nodeCache[id] = child;
166 return child;
167 }
168
169 }
170 }
171
172 return nullptr;
173}
174
176 s32 i;
177
178 if (node->fcData.modelID == modelId) {
179 return node;
180 }
181
182 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
183 if (node->children[i] != nullptr) {
185
186 if (child != nullptr) {
187 return child;
188 }
189
190 }
191 }
192
193 return nullptr;
194}
195
197 s32 i;
198
199 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
200 if (node->children[i] != nullptr) {
201 free_animator_nodes_helper(node->children[i]);
202 }
203 }
205}
206
208 AnimatorNode *root = animator->rootNode;
209 s32 i;
210
211 for (i = 0; i < ARRAY_COUNT(animator->nodeCache); i++) {
212 animator->nodeCache[i] = nullptr;
213 }
214 for (i = 0; i < ARRAY_COUNT(root->children); i++) {
215 if (root->children[i] != nullptr) {
217 }
218 }
219 heap_free(root);
220}
221
223 s32 i;
224
227 for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
228 D_801533C0[i].ttl = -1;
229 }
230
231 for (i = 0; i < ARRAY_COUNT(D_801536C0); i++) {
232 D_801536C0[i].ttl = -1;
233 }
234 } else {
236 }
237
238 for (i = 0; i < ARRAY_COUNT(*gCurrentAnimMeshListPtr); i++) {
239 (*gCurrentAnimMeshListPtr)[i] = nullptr;
240 }
241
242 gAnimModelFogR = 10;
243 gAnimModelFogG = 10;
244 gAnimModelFogB = 10;
245 gAnimModelFogA = 10;
246 gAnimModelFogStart = 800;
247 gAnimCount = 0;
249 gAnimModelFogEnd = 1000;
250}
251
255 } else {
257 }
258
259 gAnimModelFogR = 10;
260 gAnimModelFogG = 10;
261 gAnimModelFogB = 10;
262 gAnimModelFogA = 10;
263 gAnimModelFogStart = 800;
264 gAnimCount = 0;
266 gAnimModelFogEnd = 1000;
267}
268
270 s32 i;
271
272 node->flags = 0;
273
274 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
275 if (node->children[i] != nullptr) {
276 delete_model_animator_node(node->children[i]);
277 node->children[i] = nullptr;
278 }
279 }
280
282}
283
285 s32 i;
286
287 animator->nextUniqueID = 0;
288 for (i = 0; i < ARRAY_COUNT(animator->nodeCache); i++) {
289 animator->nodeCache[i] = nullptr;
290 }
291 if (animator->rootNode != nullptr) {
293 animator->rootNode = nullptr;
294 }
295}
296
298 s32 i;
299
300 animator->nextUniqueID = 0;
301
302 if (animator->rootNode != nullptr) {
304 animator->rootNode = nullptr;
305
306 for (i = 0; i < ARRAY_COUNT(*gCurrentAnimMeshListPtr); i++) {
307 if ((*gCurrentAnimMeshListPtr)[i] == animator) {
308 (*gCurrentAnimMeshListPtr)[i] = nullptr;
309 break;
310 }
311 }
312
314 gAnimCount--;
315 }
316}
317
320 s32 i, j;
321
322 for (i = 0; i < ARRAY_COUNT(*gCurrentAnimMeshListPtr); i++) {
323 if ((*gCurrentAnimMeshListPtr)[i] == nullptr) {
324 break;
325 }
326 }
327
329
330 (*gCurrentAnimMeshListPtr)[i] = animator = heap_malloc(sizeof(*animator));
331 gAnimCount++;
332
333 ASSERT(animator != nullptr);
334
336 animator->renderMode = RENDER_MODE_ALPHATEST;
337 animator->nextUpdateTime = 1.0f;
338 animator->timeScale = 1.0f;
339 animator->animReadPos = animPos;
340
341 if (animPos == nullptr) {
342 animator->animReadPos = gAnimScriptDefault;
343 }
344
345 animator->savedReadPos = animPos;
346 animator->animationBuffer = nullptr;
347 animator->baseAddr = nullptr;
348 animator->fpRenderCallback = nullptr;
349 animator->rootNode = nullptr;
350 animator->nextUniqueID = 0;
351
352 for (j = 0; j < ARRAY_COUNT(animator->nodeCache); j++) {
353 animator->nodeCache[j] = nullptr;
354 }
355
356 for (j = 0; j < ARRAY_COUNT(animator->staticNodeIDs); j++) {
357 animator->staticNodeIDs[j] = j + 1;
358 }
359
361 i |= BATTLE_ID_BIT;
362 }
363 return i;
364}
365
368 s32 i, j;
369
370 for (i = 0; i < ARRAY_COUNT(*gCurrentAnimMeshListPtr); i++) {
371 if ((*gCurrentAnimMeshListPtr)[i] == nullptr) {
372 break;
373 }
374 }
375
377
378 (*gCurrentAnimMeshListPtr)[i] = animator = heap_malloc(sizeof(*animator));
379 gAnimCount++;
380
381 ASSERT(animator != nullptr);
382
384 animator->renderMode = RENDER_MODE_ALPHATEST;
385 animator->baseAddr = nullptr;
386 animator->fpRenderCallback = nullptr;
387 animator->rootNode = nullptr;
388 animator->nextUniqueID = 0;
389 animator->animationBuffer = animBuffer;
390 animator->nextUpdateTime = 1.0f;
391 animator->timeScale = 1.0f;
392 animPos = (s16*)(((s32)animPos & 0xFFFFFF) + (s32)animator->animationBuffer);
393 animator->animReadPos = animPos;
394 animator->savedReadPos = animPos;
395
396 for (j = 0; j < ARRAY_COUNT(animator->nodeCache); j++) {
397 animator->nodeCache[j] = nullptr;
398 }
399
400 for (j = 0; j < ARRAY_COUNT(animator->staticNodeIDs); j++) {
401 animator->staticNodeIDs[j] = j + 1;
402 }
403
405 i |= BATTLE_ID_BIT;
406 }
407 return i;
408}
409
412 AnimatorNode* child;
413 s32 nextUniqueID;
414 s32 i;
415
416 ret = heap_malloc(sizeof(*ret));
417 ASSERT(ret != nullptr);
418
420 ret->displayList = nodeBP->displayList;
421 ret->basePos.x = nodeBP->basePos.x;
422 ret->basePos.y = nodeBP->basePos.y;
423 ret->basePos.z = nodeBP->basePos.z;
424 ret->pos.x = 0.0f;
425 ret->pos.y = 0.0f;
426 ret->pos.z = 0.0f;
427 ret->rot.x = nodeBP->rot.x;
428 ret->rot.y = nodeBP->rot.y;
429 ret->rot.z = nodeBP->rot.z;
430 ret->scale.x = 1.0f;
431 ret->scale.y = 1.0f;
432 ret->scale.z = 1.0f;
433 ret->vertexStartOffset = -1;
434
435 for (i = 0; i < ARRAY_COUNT(ret->children); i++) {
436 ret->children[i] = nullptr;
437 }
438
439 nextUniqueID = animator->nextUniqueID;
440 nextUniqueID = nextUniqueID + 1;
441
442 if (parentNodeID == 0) {
443 s32 nullRootNode = animator->rootNode == nullptr; // todo ???
444
445 ret->uniqueIndex = nextUniqueID;
446
447 if (nullRootNode) {
448 animator->rootNode = ret;
449 } else {
451 ASSERT(child != nullptr);
452
453 for (i = 0; i < ARRAY_COUNT(child->children); i++) {
454 if (child->children[i] == nullptr) {
455 child->children[i] = ret;
456 break;
457 }
458 }
459
460 ASSERT(i < ARRAY_COUNT(child->children));
461 }
462 } else {
463 ret->uniqueIndex = nextUniqueID;
465 ASSERT(child != nullptr);
466
467 for (i = 0; i < ARRAY_COUNT(child->children); i++) {
468 if (child->children[i] == nullptr) {
469 child->children[i] = ret;
470 break;
471 }
472 }
473
474 ASSERT(i < ARRAY_COUNT(child->children));
475 }
476
477 animator->nextUniqueID = nextUniqueID;
478 return ret;
479}
480
483 s32 temp;
484 s32 i;
485
487 return;
488 }
489
491 animator = (*gCurrentAnimMeshListPtr)[animatorID];
492
493 if (animator == nullptr || animator->flags == 0) {
494 return;
495 }
496
498 return;
499 }
500
502 animator->nextUpdateTime -= animator->timeScale;
503
504 temp = 0;
505 if (animator->nextUpdateTime <= 0.0f) {
506 if (!(animator->flags & MODEL_ANIMATOR_FLAG_MESH)) {
507 do {
509 } while (temp > 0);
510 } else {
511 animator->nextUpdateTime = 1.0f;
513 do {
515 } while (temp > 0);
516 }
517 }
518 if (temp == -1) {
519 return;
520 }
521
523
524 for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
525 if (D_801533C0[i].ttl >= 0) {
526 D_801533C0[i].ttl--;
527 if (D_801533C0[i].ttl == 0) {
528 D_801533C0[i].ttl = -1;
530 }
531 }
532 }
533
534 for (i = 0; i < ARRAY_COUNT(D_801536C0); i++) {
535 if (D_801536C0[i].ttl >= 0) {
536 D_801536C0[i].ttl--;
537 if (D_801536C0[i].ttl == 0) {
538 D_801536C0[i].ttl = -1;
540 }
541 }
542 }
543}
544
547 s32 temp;
548 s32 i;
549
551 return;
552 }
553
555 animator = (*gCurrentAnimMeshListPtr)[animatorID];
556
557 if (animator == nullptr || animator->flags == 0) {
558 return;
559 }
560
562 return;
563 }
564
566 animator->nextUpdateTime -= animator->timeScale;
567
568 temp = 0;
569 if (animator->nextUpdateTime <= 0.0f) {
570 if (!(animator->flags & MODEL_ANIMATOR_FLAG_MESH)) {
571 do {
573 } while (temp > 0);
574 } else {
575 animator->nextUpdateTime = 1.0f;
577 do {
579 } while (temp > 0);
580 }
581 }
582 if (temp == -1) {
583 return;
584 }
585
587
588 for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
589 if (D_801533C0[i].ttl >= 0) {
590 D_801533C0[i].ttl--;
591 if (D_801533C0[i].ttl == 0) {
592 D_801533C0[i].ttl = -1;
594 }
595 }
596 }
597
598 for (i = 0; i < ARRAY_COUNT(D_801536C0); i++) {
599 if (D_801536C0[i].ttl >= 0) {
600 D_801536C0[i].ttl--;
601 if (D_801536C0[i].ttl == 0) {
602 D_801536C0[i].ttl = -1;
604 }
605 }
606 }
607}
608
610 s16* args = animator->animReadPos;
612 f32 x, y, z;
613 s32 flags;
614 s32 nodeId;
615
616 switch (*args++) {
617 case AS_END:
618 return -1;
620 animator->renderMode = *args++;
621 animator->animReadPos = args;
622 return 1;
623 case AS_WAIT:
624 animator->nextUpdateTime = *args++;
625 animator->animReadPos = args;
626 break;
627 case AS_END_LOOP:
628 animator->animReadPos = animator->savedReadPos;
629 return 1;
630 case AS_LOOP:
631 animator->animReadPos = animator->savedReadPos = args;
632 return 1;
633 case AS_SET_FLAGS:
634 flags = *args++;
635 animator->animReadPos = args;
636 animator->flags |= flags & 0xFFFF;
637 return 1;
639 node = get_animator_child_with_id(animator, animator->staticNodeIDs[*args++ - 1]);
640 flags = *args++;
641 node->flags |= flags;
642 animator->animReadPos = args;
643 return 1;
645 node = get_animator_child_with_id(animator, animator->staticNodeIDs[*args++ - 1]);
646 flags = *args++;
647 node->flags &= ~flags;
648 animator->animReadPos = args;
649 return 1;
650 case AS_OP_19:
652 animator->animReadPos = args;
653 return 1;
654 case AS_SET_ROTATION:
655 nodeId = animator->staticNodeIDs[*args++ - 1];
656 x = (f32)*args++ * 180.0 / 32767.0;
657 y = (f32)*args++ * 180.0 / 32767.0;
658 z = (f32)*args++ * 180.0 / 32767.0;
659 animator->animReadPos = args;
660
662 ASSERT(node != nullptr);
663 node->rot.x = x;
664 node->rot.y = y;
665 node->rot.z = z;
666 return 1;
667 case AS_ADD_ROTATION:
668 nodeId = animator->staticNodeIDs[*args++ - 1];
669 x = (f32)*args++ * 180.0 / 32767.0;
670 y = (f32)*args++ * 180.0 / 32767.0;
671 z = (f32)*args++ * 180.0 / 32767.0;
672 animator->animReadPos = args;
673
675 ASSERT(node != nullptr);
676 node->rot.x += x;
677 node->rot.y += y;
678 node->rot.z += z;
679 return 1;
680 case AS_SET_POS:
681 nodeId = animator->staticNodeIDs[*args++ - 1];
682 x = *args++;
683 y = *args++;
684 z = *args++;
685 animator->animReadPos = args;
687 ASSERT(node != nullptr);
688 node->pos.x = x;
689 node->pos.y = y;
690 node->pos.z = z;
691 return 1;
692 case AS_SET_SCALE:
693 nodeId = animator->staticNodeIDs[*args++ - 1];
694 x = (f32)*args++ * 180.0 / 32767.0;
695 y = (f32)*args++ * 180.0 / 32767.0;
696 z = (f32)*args++ * 180.0 / 32767.0;
697 animator->animReadPos = args;
698
700 ASSERT(node != nullptr);
701 node->scale.x = x;
702 node->scale.y = y;
703 node->scale.z = z;
704 return 1;
705 }
706 return 0;
707}
708
730
734 s32 i;
735
737 guScaleF(gAnimScaleMtx, node->scale.x, node->scale.y, node->scale.z);
738 guTranslateF(gAnimTranslateMtx, node->basePos.x + node->pos.x, node->basePos.y + node->pos.y, node->basePos.z + node->pos.z);
741
742 if (!(animator->flags & MODEL_ANIMATOR_FLAG_NO_FLIP)) {
744 }
745
746 copy_matrix(sp10, node->mtx);
747
748 if (node->flags & MODEL_ANIMATOR_FLAG_HAS_MODEL) {
750
751 copy_matrix(sp10, model->userTransformMtx);
753 guMtxCatF(model->userTransformMtx, sp10, model->userTransformMtx);
755 }
756
757 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
758 if (node->children[i] != nullptr) {
760 }
761 }
762}
763
767 RenderTask* rtPtr = &rt;
768
770 return;
771 }
772
774 animator = (*gCurrentAnimMeshListPtr)[animatorID];
775
776 if (animator == nullptr || animator->flags == 0) {
777 return;
778 }
779
781 && animator->flags & (1 << gCurrentCamID)
783 ) {
784 animator->mtx = *rootTransform;
785 animator->baseAddr = nullptr;
787 rtPtr->appendGfx = (void (*)(void*))appendGfx_animator;
788 rtPtr->dist = 0;
789 rtPtr->renderMode = animator->renderMode;
791 }
792}
793
797 RenderTask* rtPtr = &rt;
798
800 return;
801 }
802
804 animator = (*gCurrentAnimMeshListPtr)[animatorID];
805
806 if (animator == nullptr || animator->flags == 0) {
807 return;
808 }
809
811 && animator->flags & (1 << gCurrentCamID)
813 ) {
814 animator->mtx = *rootTransform;
816 animator->baseAddr = baseAddr;
818 rtPtr->appendGfx = (void (*)(void*))appendGfx_animator;
819 rtPtr->dist = 0;
820 rtPtr->renderMode = animator->renderMode;
822 }
823}
824
827
828 if (animator->baseAddr != nullptr) {
830 }
831
834
835 //TODO find better match
836 switch (gAnimModelFogEnabled != 0) {
837 case false:
838 switch (animator->renderMode) {
841 break;
844 break;
847 break;
850 break;
853 break;
856 break;
859 break;
860 }
861 break;
862 case true:
863 switch (animator->renderMode) {
866 break;
869 break;
872 break;
875 break;
878 break;
881 break;
884 break;
885 }
886
889 break;
890 }
891
892 guMtxL2F(sp10, &animator->mtx);
895}
896
899 u32 w0,w1;
900 s32 cmd;
901 s32 i;
902
903 if (node->flags & MODEL_ANIMATOR_FLAG_HIDDEN) {
904 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
905 if (node->children[i] != nullptr) {
906 guMtxCatF(node->mtx, mtx, node->mtx);
907 appendGfx_animator_node(animator, node->children[i], node->mtx);
908 }
909 }
910 return;
911 }
912
913 guMtxCatF(node->mtx, mtx, node->mtx);
917
924 }
927 } else {
929 }
931
932 if (animator->fpRenderCallback != nullptr) animator->fpRenderCallback(animator->renderCallbackArg);
933
935
936 if (node->displayList != nullptr) {
937 if (node->vertexStartOffset < 0) {
938 gSPDisplayList(gMainGfxPos++, node->displayList);
939 } else {
940 Gfx* gfxPos;
942 s32 j = 0;
943 s32 k;
944
945 if ((node->displayList[0].words.w0 >> 0x18) != G_ENDDL) {
946 Gfx* gfxPtr = node->displayList;
947 s32 endDL = G_ENDDL;
948
949 for(;; j++) {
950 w0 = gfxPtr->words.w0;
951 gfxPtr++;
952 cmd = w0 >> 0x18;
953 if (cmd == endDL) {
954 break;
955 }
956 }
957 }
958 j++;
959 for (k = 0; k < ARRAY_COUNT(D_801536C0); k++) {
961 if (bufferHandle->ttl < 0) {
962 break;
963 }
964 }
966
967 bufferHandle->addr = gfxPos = general_heap_malloc(j * sizeof(Gfx));
968 ASSERT(gfxPos != nullptr);
969 bufferHandle->ttl = 3;
970
971 vtxIdx = 0;
972 dlIdx = 0;
973
974 do {
975 w0 = ((s32*)node->displayList)[dlIdx++];
976 w1 = ((s32*)node->displayList)[dlIdx++];
977 cmd = w0 >> 0x18;
978 if (cmd == G_ENDDL) {
979 break;
980 }
981 if (cmd == G_VTX) {
982 s32 startIdx = _SHIFTR(w0,1,7);
983 s32 vtxCount = _SHIFTR(w0,12,8);
984 Vtx* newBuffer;
985
986 startIdx -= vtxCount;
987
988 if (node->fcData.vtxList == nullptr) {
989 newBuffer = &((Vtx*)w1)[node->vertexStartOffset + vtxIdx];
990 gSPVertex(gfxPos++, newBuffer, vtxCount, startIdx);
991 } else {
993 animator,
994 node,
995 (Vec3s*)(w1 + (node->vertexStartOffset + vtxIdx) * 0x6),
996 vtxCount,
997 startIdx,
998 vtxIdx
999 );
1000 gSPVertex(gfxPos++, newBuffer, vtxCount, startIdx);
1001 }
1002 vtxIdx += vtxCount;
1003 } else {
1004 Gfx* temp[1] = {gfxPos++}; // required to match
1005 temp[0]->words.w0 = w0;
1006 temp[0]->words.w1 = w1;
1007 }
1008 } while (true);
1009
1012 }
1013 }
1015
1016 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
1017 if (node->children[i] != nullptr) {
1018 appendGfx_animator_node(animator, node->children[i], node->mtx);
1019 }
1020 }
1021}
1022
1026
1030
1032 s32 i;
1033
1034 for (i = 0; i < count; i++) {
1035 animator->staticNodeIDs[i] = *nodeIDs;
1036 nodeIDs++;
1037 }
1038}
1039
1041 return (*gCurrentAnimMeshListPtr)[animModelID & ~BATTLE_ID_BIT];
1042}
1043
1045 ModelAnimator* ret = (*gCurrentAnimMeshListPtr)[animModelID & ~BATTLE_ID_BIT];
1046
1048 ret->renderCallbackArg = callbackArg;
1049 return ret;
1050}
1051
1053 gAnimModelFogEnabled = true;
1054}
1055
1057 gAnimModelFogEnabled = false;
1058}
1059
1061 gAnimModelFogStart = start;
1062 gAnimModelFogEnd = end;
1063}
1064
1066 gAnimModelFogR = r;
1067 gAnimModelFogG = g;
1068 gAnimModelFogB = b;
1069 gAnimModelFogA = a;
1070}
1071
1075
1077 *start = gAnimModelFogStart;
1078 *end = gAnimModelFogEnd;
1079}
1080
1082 *r = gAnimModelFogR;
1083 *g = gAnimModelFogG;
1084 *b = gAnimModelFogB;
1085 *a = gAnimModelFogA;
1086}
1087
1089 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[index & ~BATTLE_ID_BIT];
1090
1091 animator->flags |= bits;
1092}
1093
1095 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[index & ~BATTLE_ID_BIT];
1096
1097 animator->flags &= ~bits;
1098}
1099
1101 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[index & ~BATTLE_ID_BIT];
1102
1103 if (animator->animationBuffer != nullptr) {
1104 animPos = (s16*) (((s32)animPos & 0xFFFFFF) + (s32)animator->animationBuffer); // TODO: array access? / cleanup
1105 }
1107 animator->savedReadPos = animPos;
1108 animator->treeIndexPos = 0;
1109 animator->nextUpdateTime = 1.0f;
1110}
1111
1113 s32 indexMasked = index & ~BATTLE_ID_BIT;
1114 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[indexMasked];
1115 s32 i;
1116
1117 if (animator->animationBuffer != nullptr) {
1118 animPos = (s16*) (((s32)animPos & 0xFFFFFF) + (s32)animator->animationBuffer); // TODO: array access? / cleanup
1119 }
1120
1122 animator->savedReadPos = animPos;
1123 animator->treeIndexPos = 0;
1124 animator->nextUpdateTime = 1.0f;
1125
1126 for (i = 0; i < framesToSkip; i++) {
1128 }
1129}
1130
1135 s32 i;
1136
1137 if (node != nullptr) {
1138 bpPtr->displayList = node->displayList;
1139 bpPtr->basePos.x = 0.0f;
1140 bpPtr->basePos.y = 0.0f;
1141 bpPtr->basePos.z = 0.0f;
1142 bpPtr->rot.x = ((f32) node->rot.x * 180.0) / 32767.0;
1143 bpPtr->rot.y = ((f32) node->rot.y * 180.0) / 32767.0;
1144 bpPtr->rot.z = ((f32) node->rot.z * 180.0) / 32767.0;
1145
1147
1148 if (node->modelID != 0) {
1149 newNode->fcData.modelID = node->modelID - 1;
1151 }
1152
1153 i = 0;
1154 while (gAnimTreeRoot[i] != node) {
1155 i++;
1156 }
1157
1158 treeIndexToNodeIDs[i] = newNode->uniqueIndex;
1159
1160 if (node->child != nullptr) {
1162 }
1163
1164 if (node->sibling != nullptr) {
1166 }
1167 }
1168}
1169
1171 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[index & ~BATTLE_ID_BIT];
1172 s32 nodeIDs[ARRAY_COUNT(animator->staticNodeIDs)];
1173
1174 if (animator == nullptr || animator->flags == 0) {
1175 return;
1176 }
1177
1181}
1182
1184 if (node != nullptr) {
1185 if (node->child != nullptr && parentNodeID == 0) {
1187 } else {
1188 do {
1189 animator->staticNodes[parentNodeID] = node;
1190 node = node->sibling;
1191 parentNodeID++;
1192 } while (node != nullptr);
1193 }
1194 }
1195}
1196
1198 s32 indexMasked = index & ~BATTLE_ID_BIT;
1199 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[indexMasked];
1200 s32 nodeIDs[ARRAY_COUNT(animator->staticNodeIDs)];
1201 s32 i;
1202
1203 if (animator == nullptr || animator->flags == 0) {
1204 return;
1205 }
1206
1207 if ((*tree)->vertexStartOffset == 0) {
1209 return;
1210 }
1211
1213 animator->staticRoot = tree;
1214 animator->treeIndexPos = 0;
1215 animator->savedTreePos = 0;
1216
1217 for (i = 0; i < ARRAY_COUNT(animator->staticNodes); i++) {
1218 animator->staticNodes[i] = nullptr;
1219 }
1220
1223}
1224
1229 s32 i;
1230
1231 if (node != nullptr) {
1232 bpPtr->displayList = node->displayList;
1233 bpPtr->basePos.x = 0.0f;
1234 bpPtr->basePos.y = 0.0f;
1235 bpPtr->basePos.z = 0.0f;
1236 bpPtr->rot.x = ((f32) node->rot.x * 180.0) / 32767.0;
1237 bpPtr->rot.y = ((f32) node->rot.y * 180.0) / 32767.0;
1238 bpPtr->rot.z = ((f32) node->rot.z * 180.0) / 32767.0;
1239
1241 newNode->vertexStartOffset = node->vertexStartOffset;
1242 newNode->fcData.vtxList = node->vtxList;
1243
1244 i = 0;
1245 while (gAnimTreeRoot[i] != node) {
1246 i++;
1247 }
1248
1249 treeIndexToNodeIDs[i] = newNode->uniqueIndex;
1250
1251 if (node->child != nullptr) {
1253 }
1254 }
1255}
1256
1258 s32 nodeIDs[ARRAY_COUNT(animator->staticNodeIDs)];
1259 s32 i;
1260
1262 gAnimTreeRoot = animator->staticRoot;
1263
1264 for (i = 0; i < ARRAY_COUNT(animator->staticNodes); i++) {
1265 nodeIDs[i] = 0;
1266 }
1267
1268 reload_mesh_animator_node(animator->staticNodes[animator->treeIndexPos], animator, 0, nodeIDs);
1269 nodeIDs[0] = -1;
1271}
1272
1274 s16* args = animator->animReadPos;
1275 s16* oldPos = animator->animReadPos;
1277 f32 x, y, z;
1278 s32 flags;
1279 s32 nodeId;
1280
1281 switch (*args++) {
1282 case AS_END:
1283 return -1;
1284 case AS_SET_RENDER_MODE:
1285 animator->renderMode = *args++;
1286 animator->animReadPos = args;
1287 return 1;
1288 case AS_WAIT:
1289 args++;
1290 animator->animReadPos = args;
1291 return 1;
1292 case AS_END_LOOP:
1293 animator->animReadPos = animator->savedReadPos;
1294 animator->treeIndexPos = animator->savedTreePos;
1296 return 1;
1297 case AS_OP_4:
1298 animator->animReadPos = animator->savedReadPos;
1299 animator->treeIndexPos = animator->savedTreePos;
1300 break;
1301 case AS_LOOP:
1302 animator->animReadPos = animator->savedReadPos = args;
1303 animator->savedTreePos = animator->treeIndexPos;
1304 return 1;
1305 case AS_SET_FLAGS:
1306 flags = *args++;
1307 animator->animReadPos = args;
1308 animator->flags |= flags & 0xFFFF;
1309 return 1;
1310 case AS_SET_NODE_FLAGS:
1311 node = get_animator_child_with_id(animator, animator->staticNodeIDs[*args++ - 1]);
1312 flags = *args++;
1313 node->flags |= flags;
1314 animator->animReadPos = args;
1315 return 1;
1317 node = get_animator_child_with_id(animator, animator->staticNodeIDs[*args++ - 1]);
1318 flags = *args++;
1319 node->flags &= ~flags;
1320 animator->animReadPos = args;
1321 return 1;
1322 case AS_OP_19:
1324 animator->animReadPos = args;
1325 return 1;
1326 case AS_SET_ROTATION:
1327 nodeId = animator->staticNodeIDs[*args++ - 1];
1328 x = (f32)*args++ * 180.0 / 32767.0;
1329 y = (f32)*args++ * 180.0 / 32767.0;
1330 z = (f32)*args++ * 180.0 / 32767.0;
1331 animator->animReadPos = args;
1332 if (nodeId != 0xFF) {
1334 if (node != nullptr) {
1335 node->rot.x = x;
1336 node->rot.y = y;
1337 node->rot.z = z;
1338 return 1;
1339 } else {
1340 animator->animReadPos = oldPos;
1341 animator->treeIndexPos++;
1342 break;
1343 }
1344 }
1345 return 1;
1346 case AS_ADD_ROTATION:
1347 nodeId = animator->staticNodeIDs[*args++ - 1];
1348 x = (f32)*args++ * 180.0 / 32767.0;
1349 y = (f32)*args++ * 180.0 / 32767.0;
1350 z = (f32)*args++ * 180.0 / 32767.0;
1351 animator->animReadPos = args;
1352 if (nodeId != 0xFF) {
1354 if (node != nullptr) {
1355 node->rot.x += x;
1356 node->rot.y += y;
1357 node->rot.z += z;
1358 return 1;
1359 } else {
1360 animator->animReadPos = oldPos;
1361 animator->treeIndexPos++;
1362 break;
1363 }
1364 }
1365 return 1;
1366 case AS_SET_POS:
1367 nodeId = animator->staticNodeIDs[*args++ - 1];
1368 x = *args++;
1369 y = *args++;
1370 z = *args++;
1371 animator->animReadPos = args;
1372 if (nodeId != 0xFF) {
1374 if (node != nullptr) {
1375 node->pos.x = x;
1376 node->pos.y = y;
1377 node->pos.z = z;
1378 return 1;
1379 } else {
1380 animator->animReadPos = oldPos;
1381 animator->treeIndexPos++;
1382 break;
1383 }
1384 }
1385 return 1;
1386 case AS_SET_SCALE:
1387 nodeId = animator->staticNodeIDs[*args++ - 1];
1388 x = (f32)*args++ * 180.0 / 32767.0;
1389 y = (f32)*args++ * 180.0 / 32767.0;
1390 z = (f32)*args++ * 180.0 / 32767.0;
1391 animator->animReadPos = args;
1392 if (nodeId != 0xFF) {
1394 if (node != nullptr) {
1395 node->scale.x = x;
1396 node->scale.y = y;
1397 node->scale.z = z;
1398 return 1;
1399 } else {
1400 animator->animReadPos = oldPos;
1401 animator->treeIndexPos++;
1402 break;
1403 }
1404 }
1405 return 1;
1406 }
1407 return 0;
1408}
BSS s32 PopupMenu_SelectedIndex
#define as_Wait(time)
s16 AnimScript[]
#define as_End
@ AS_CLEAR_NODE_FLAGS
@ AS_SET_FLAGS
@ AS_SET_NODE_FLAGS
@ AS_SET_POS
@ AS_SET_RENDER_MODE
@ AS_END_LOOP
@ AS_SET_ROTATION
@ AS_OP_4
@ AS_ADD_ROTATION
@ AS_END
@ AS_SET_SCALE
@ AS_OP_19
@ AS_WAIT
@ AS_LOOP
BSS Matrix4f gAnimRotScaleMtx
Definition animator.c:30
Gfx Gfx_RM3_DECAL_OPA[]
Definition model.c:1077
BSS s32 gAnimModelFogR
Definition animator.c:20
BSS s32 gAnimModelFogG
Definition animator.c:21
void play_model_animation(s32 index, s16 *animPos)
Definition animator.c:1100
BSS AnimatedMeshVertexCopyList D_801536C0
Definition animator.c:15
void clear_animator_list(void)
Definition animator.c:222
BSS AnimatedMeshList D_801539C0
Definition animator.c:16
void render_animated_model_with_vertices(s32 animatorID, Mtx *rootTransform, s32 segment, void *baseAddr)
Definition animator.c:794
void set_anim_model_fog_color(s32 r, s32 g, s32 b, s32 a)
Definition animator.c:1065
void set_animator_tree_to_node_map(ModelAnimator *animator, s32 *nodeIDs, s32 count)
Definition animator.c:1031
Gfx Gfx_RM3_SURFACE_OPA[]
Definition model.c:1067
void reset_animator_list(void)
Definition animator.c:252
Gfx Gfx_RM3_DECAL_XLU[]
Definition model.c:1117
BSS AnimatedMeshList D_80153A00
Definition animator.c:17
AnimatorNode * add_anim_node(ModelAnimator *animator, s32 parentNodeID, AnimatorNodeBlueprint *nodeBP)
Definition animator.c:410
void get_anim_model_fog_distance(s32 *start, s32 *end)
Definition animator.c:1076
ModelAnimator * set_animator_render_callback(s32 animModelID, void *callbackArg, void(*callbackFunc)(void *))
Definition animator.c:1044
void disable_anim_model_fog(void)
Definition animator.c:1056
void render_animated_model(s32 animatorID, Mtx *rootTransform)
Definition animator.c:764
s32 gAnimCount
Definition animator.c:12
BSS s32 gAnimModelFogEnd
Definition animator.c:25
BSS s32 gAnimModelFogA
Definition animator.c:23
void enable_anim_model_fog(void)
Definition animator.c:1052
BSS s32 gAnimModelFogStart
Definition animator.c:24
void set_animator_flags(s32 index, s32 bits)
Definition animator.c:1088
void appendGfx_animator_node(ModelAnimator *, AnimatorNode *, Matrix4f)
Definition animator.c:897
AnimatorNode * get_animator_node_with_id(ModelAnimator *animator, s32 id)
Definition animator.c:1027
BSS s32 gAnimVtxSegment
Definition animator.c:26
Gfx Gfx_RM1_ALPHATEST[]
Definition model.c:676
void animator_node_update_model_transform(ModelAnimator *animator, f32(*flipMtx)[4], AnimatorNode *node, Mtx *rootTransform)
Definition animator.c:731
void reload_mesh_animator_tree(ModelAnimator *animator)
Definition animator.c:1257
void delete_model_animator_nodes(ModelAnimator *animator)
Definition animator.c:284
void get_anim_model_fog_color(s32 *r, s32 *g, s32 *b, s32 *a)
Definition animator.c:1081
void delete_model_animator(ModelAnimator *animator)
Definition animator.c:297
void clear_animator_flags(s32 index, s32 bits)
Definition animator.c:1094
void play_model_animation_starting_from(s32 index, s16 *animPos, s32 framesToSkip)
Definition animator.c:1112
void load_mesh_animator_node(StaticAnimatorNode *node, ModelAnimator *animator, s32 parentNodeID, s32 *treeIndexToNodeIDs)
Definition animator.c:1183
void delete_model_animator_node(AnimatorNode *node)
Definition animator.c:269
ModelAnimator * get_animator_by_index(s32 animModelID)
Definition animator.c:1040
BSS Matrix4f gAnimTranslateMtx
Definition animator.c:29
AnimatorNode * get_animator_child_for_model(AnimatorNode *node, s32 modelId)
Definition animator.c:175
void animator_make_identity(Matrix4f mtx)
Definition animator.c:122
Vtx * animator_copy_vertices_to_buffer(ModelAnimator *animator, AnimatorNode *node, Vec3s *buffer, s32 vtxCount, s32 overhead, s32 startIdx)
Definition animator.c:57
Gfx Gfx_RM1_INTERSECTING_OPA[]
Definition model.c:665
void animator_make_mirrorX(Matrix4f mtx)
Definition animator.c:114
Gfx Gfx_RM1_INTERSECTING_XLU[]
Definition model.c:706
DisplayListBufferHandle AnimatedMeshVertexCopyList[0x60]
Definition animator.c:10
void load_mesh_animator_tree(s32 index, StaticAnimatorNode **tree)
Definition animator.c:1197
s32 create_model_animator(s16 *animPos)
Definition animator.c:318
BSS s32 gAnimModelFogB
Definition animator.c:22
s32 is_anim_model_fog_enabled(void)
Definition animator.c:1072
void free_animator_nodes(ModelAnimator *animator)
Definition animator.c:207
Gfx Gfx_RM3_ALPHATEST[]
Definition model.c:1097
void update_model_animator(s32 animatorID)
Definition animator.c:481
void appendGfx_animator(ModelAnimator *animator)
Definition animator.c:825
Gfx Gfx_RM1_SURFACE_XLU[]
Definition model.c:686
void load_model_animator_tree(s32 index, StaticAnimatorNode **tree)
Definition animator.c:1170
void animator_make_mirrorY(Matrix4f mtx)
Definition animator.c:106
void load_model_animator_node(StaticAnimatorNode *node, ModelAnimator *animator, s32 parentNodeID, s32 *treeIndexToNodeIDs)
Definition animator.c:1131
s32 step_mesh_animator(ModelAnimator *animator)
Definition animator.c:1273
s32 step_model_animator(ModelAnimator *animator)
Definition animator.c:609
void update_model_animator_with_transform(s32 animatorID, Mtx *mtx)
Definition animator.c:545
Gfx Gfx_RM3_INTERSECTING_OPA[]
Definition model.c:1087
BSS Matrix4f gAnimRotMtx
Definition animator.c:27
AnimatorNode * get_animator_child_with_id_helper(AnimatorNode *node, s32 id)
Definition animator.c:130
void reload_mesh_animator_node(StaticAnimatorNode *node, ModelAnimator *animator, s32 parentNodeID, s32 *treeIndexToNodeIDs)
Definition animator.c:1225
Gfx Gfx_RM1_DECAL_OPA[]
Definition model.c:654
s32 create_mesh_animator(s16 *animPos, s16 *animBuffer)
Definition animator.c:366
BSS AnimatedMeshVertexCopyList D_801533C0
Definition animator.c:14
Gfx Gfx_RM1_DECAL_XLU[]
Definition model.c:696
void free_animator_nodes_helper(AnimatorNode *node)
Definition animator.c:196
void animator_make_mirrorZ(Matrix4f mtx)
Definition animator.c:98
Gfx Gfx_RM3_INTERSECTING_XLU[]
Definition model.c:1127
Gfx Gfx_RM1_SURFACE_OPA[]
Definition model.c:643
AnimatorNode * get_animator_node_for_tree_index(ModelAnimator *animator, s32 arg1)
Definition animator.c:1023
BSS StaticAnimatorNode ** gAnimTreeRoot
Definition animator.c:31
void set_anim_model_fog_dist(s32 start, s32 end)
Definition animator.c:1060
void animator_update_model_transforms(ModelAnimator *animator, Mtx *rootTransform)
Definition animator.c:709
AnimScript gAnimScriptDefault
Definition animator.c:48
BSS Matrix4f gAnimScaleMtx
Definition animator.c:28
AnimatorNode * get_animator_child_with_id(ModelAnimator *animator, s32 id)
Definition animator.c:149
Gfx Gfx_RM3_SURFACE_XLU[]
Definition model.c:1107
BSS AnimatedMeshList * gCurrentAnimMeshListPtr
Definition animator.c:18
BSS s32 gAnimModelFogEnabled
Definition animator.c:19
Mtx matrixStack[0x200]
f32 Matrix4f[4][4]
struct AnimatorNode * children[32]
ModelAnimator * AnimatedMeshList[16]
s8 flags
Definition demo_api.c:15
#define general_heap_malloc
#define queue_render_task
#define guMtxF2L
#define guTranslateF
#define guMtxCatF
#define clamp_angle
#define guScaleF
#define ASSERT(condition)
@ MODEL_FLAG_MATRIX_DIRTY
Definition enums.h:3954
@ MODEL_ANIMATOR_FLAG_CAM_2
Definition enums.h:4498
@ MODEL_ANIMATOR_FLAG_HAS_MODEL
Definition enums.h:4508
@ MODEL_ANIMATOR_FLAG_CULL_BACK
Definition enums.h:4512
@ MODEL_ANIMATOR_FLAG_NO_FLIP
Definition enums.h:4513
@ MODEL_ANIMATOR_FLAG_MESH
Definition enums.h:4511
@ MODEL_ANIMATOR_FLAG_CAM_1
Definition enums.h:4497
@ MODEL_ANIMATOR_FLAG_FREEZE_ANIMATION
Definition enums.h:4514
@ MODEL_ANIMATOR_FLAG_FLIP_Y
Definition enums.h:4505
@ MODEL_ANIMATOR_FLAG_FLIP_X
Definition enums.h:4506
@ MODEL_ANIMATOR_FLAG_CAM_0
Definition enums.h:4496
@ MODEL_ANIMATOR_FLAG_HIDDEN
Definition enums.h:4503
@ MODEL_ANIMATOR_FLAG_ENABLED
Definition enums.h:4500
@ MODEL_ANIMATOR_FLAG_FLIP_Z
Definition enums.h:4504
@ MODEL_ANIMATOR_FLAG_UPDATE_PENDING
Definition enums.h:4502
@ CONTEXT_WORLD
Definition enums.h:3562
@ RENDER_MODE_DECAL_OPA
Definition enums.h:3302
@ RENDER_MODE_INTERSECTING_XLU
Definition enums.h:3337
@ RENDER_MODE_DECAL_XLU
Definition enums.h:3325
@ RENDER_MODE_INTERSECTING_OPA
Definition enums.h:3306
@ RENDER_MODE_ALPHATEST
Definition enums.h:3310
@ RENDER_MODE_SURFACE_OPA
Definition enums.h:3298
@ RENDER_MODE_SURFACE_XLU_LAYER1
Definition enums.h:3316
s32 get_model_list_index_from_tree_index(s32 treeIndex)
Definition model.c:3393
struct Model * get_model_from_list_index(s32 listIndex)
Definition model.c:3312
s32 heap_free(void *ptr)
Definition heap.c:42
void copy_matrix(Matrix4f src, Matrix4f dest)
Definition 43F0.c:437
s32 general_heap_free(void *data)
Definition heap.c:18
void * heap_malloc(s32 size)
Definition heap.c:34
Definition model.h:59
#define BSS
Definition macros.h:6
#define ARRAY_COUNT(arr)
Definition macros.h:39
#define PM_CC2_MULTIPLY_SHADE
Definition macros.h:320
#define PM_CC_42
Definition macros.h:479
#define BATTLE_ID_BIT
Definition macros.h:155
#define VIRTUAL_TO_PHYSICAL(addr)
Definition macros.h:46
void(* fpRenderCallback)(void *)
void * appendGfxArg
GameStatus * gGameStatusPtr
Definition main_loop.c:31
Gfx * gMainGfxPos
Definition cam_main.c:14
u16 gMatrixListPos
Definition main_loop.c:44
DisplayContext * gDisplayContext
Definition cam_main.c:15
s16 gCurrentCamID
Definition cam_main.c:12