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
57Vtx* animator_copy_vertices_to_buffer(ModelAnimator* animator, AnimatorNode* node, Vec3s* buffer, s32 vtxCount,
58 s32 overhead, s32 startIdx) {
60 Vtx* bufferMem;
61 Vtx* nodeVtxList;
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 != NULL);
77
78 handle->ttl = 3;
79 nodeVtxList = &node->fcData.vtxList[startIdx];
80
81 if (animator->baseAddr != NULL) {
82 i = ((s32)buffer & 0xFFFFFF); // needed to match
83 buffer = (Vec3s*)(i + (s32)animator->baseAddr);
84 }
85
86 for (i = 0; i < vtxCount; i++) {
87 *bufferMem = *nodeVtxList;
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++;
93 nodeVtxList++;
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] != NULL) {
140 if (child != NULL) {
141 return child;
142 }
143 }
144 }
145
146 return NULL;
147}
148
150 AnimatorNode *node = animator->rootNode;
151 s32 i;
152
153 if (animator->nodeCache[id] != NULL && 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] != NULL) {
163
164 if (child != NULL) {
165 animator->nodeCache[id] = child;
166 return child;
167 }
168
169 }
170 }
171
172 return NULL;
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] != NULL) {
184 AnimatorNode* child = get_animator_child_for_model(node->children[i], modelId);
185
186 if (child != NULL) {
187 return child;
188 }
189
190 }
191 }
192
193 return NULL;
194}
195
197 s32 i;
198
199 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
200 if (node->children[i] != NULL) {
202 }
203 }
204 heap_free(node);
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] = NULL;
213 }
214 for (i = 0; i < ARRAY_COUNT(root->children); i++) {
215 if (root->children[i] != NULL) {
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] = NULL;
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] != NULL) {
277 node->children[i] = NULL;
278 }
279 }
280
281 heap_free(node);
282}
283
285 s32 i;
286
287 animator->nextUniqueID = 0;
288 for (i = 0; i < ARRAY_COUNT(animator->nodeCache); i++) {
289 animator->nodeCache[i] = NULL;
290 }
291 if (animator->rootNode != NULL) {
293 animator->rootNode = NULL;
294 }
295}
296
298 s32 i;
299
300 animator->nextUniqueID = 0;
301
302 if (animator->rootNode != NULL) {
304 animator->rootNode = NULL;
305
306 for (i = 0; i < ARRAY_COUNT(*gCurrentAnimMeshListPtr); i++) {
307 if ((*gCurrentAnimMeshListPtr)[i] == animator) {
308 (*gCurrentAnimMeshListPtr)[i] = NULL;
309 break;
310 }
311 }
312
313 heap_free(animator);
314 gAnimCount--;
315 }
316}
317
318s32 create_model_animator(s16* animPos) {
319 ModelAnimator* animator;
320 s32 i, j;
321
322 for (i = 0; i < ARRAY_COUNT(*gCurrentAnimMeshListPtr); i++) {
323 if ((*gCurrentAnimMeshListPtr)[i] == NULL) {
324 break;
325 }
326 }
327
329
330 (*gCurrentAnimMeshListPtr)[i] = animator = heap_malloc(sizeof(*animator));
331 gAnimCount += 1;
332
333 ASSERT(animator != NULL);
334
337 animator->nextUpdateTime = 1.0f;
338 animator->timeScale = 1.0f;
339 animator->animReadPos = animPos;
340
341 if (animPos == NULL) {
343 }
344
345 animator->savedReadPos = animPos;
346 animator->animationBuffer = NULL;
347 animator->baseAddr = NULL;
348 animator->fpRenderCallback = NULL;
349 animator->rootNode = NULL;
350 animator->nextUniqueID = 0;
351
352 for (j = 0; j < ARRAY_COUNT(animator->nodeCache); j++) {
353 animator->nodeCache[j] = NULL;
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
366s32 create_mesh_animator(s16* animPos, s16* animBuffer) {
367 ModelAnimator* animator;
368 s32 i, j;
369
370 for (i = 0; i < ARRAY_COUNT(*gCurrentAnimMeshListPtr); i++) {
371 if ((*gCurrentAnimMeshListPtr)[i] == NULL) {
372 break;
373 }
374 }
375
377
378 (*gCurrentAnimMeshListPtr)[i] = animator = heap_malloc(sizeof(*animator));
379 gAnimCount += 1;
380
381 ASSERT(animator != NULL);
382
385 animator->baseAddr = NULL;
386 animator->fpRenderCallback = NULL;
387 animator->rootNode = NULL;
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] = NULL;
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
410AnimatorNode* add_anim_node(ModelAnimator* animator, s32 parentNodeID, AnimatorNodeBlueprint* nodeBP) {
411 AnimatorNode* ret;
412 AnimatorNode* child;
413 s32 nextUniqueID;
414 s32 nullRootNode;
415 s32 i;
416
417 ret = heap_malloc(sizeof(*ret));
418 ASSERT(ret != NULL);
419
421 ret->displayList = nodeBP->displayList;
422 ret->basePos.x = nodeBP->basePos.x;
423 ret->basePos.y = nodeBP->basePos.y;
424 ret->basePos.z = nodeBP->basePos.z;
425 ret->pos.x = 0.0f;
426 ret->pos.y = 0.0f;
427 ret->pos.z = 0.0f;
428 ret->rot.x = nodeBP->rot.x;
429 ret->rot.y = nodeBP->rot.y;
430 ret->rot.z = nodeBP->rot.z;
431 ret->scale.x = 1.0f;
432 ret->scale.y = 1.0f;
433 ret->scale.z = 1.0f;
434 ret->vertexStartOffset = -1;
435
436 for (i = 0; i < ARRAY_COUNT(ret->children); i++) {
437 ret->children[i] = NULL;
438 }
439
440 nextUniqueID = animator->nextUniqueID;
441 nextUniqueID = nextUniqueID + 1;
442
443 if (parentNodeID == 0) {
444 s32 nullRootNode = animator->rootNode == NULL; // todo ???
445
446 ret->uniqueIndex = nextUniqueID;
447
448 if (nullRootNode) {
449 animator->rootNode = ret;
450 } else {
451 child = get_animator_child_with_id(animator, 1);
452 ASSERT(child != NULL);
453
454 for (i = 0; i < ARRAY_COUNT(child->children); i++) {
455 if (child->children[i] == NULL) {
456 child->children[i] = ret;
457 break;
458 }
459 }
460
461 ASSERT(i < ARRAY_COUNT(child->children));
462 }
463 } else {
464 ret->uniqueIndex = nextUniqueID;
465 child = get_animator_child_with_id(animator, parentNodeID);
466 ASSERT(child != NULL);
467
468 for (i = 0; i < ARRAY_COUNT(child->children); i++) {
469 if (child->children[i] == NULL) {
470 child->children[i] = ret;
471 break;
472 }
473 }
474
475 ASSERT(i < ARRAY_COUNT(child->children));
476 }
477
478 animator->nextUniqueID = nextUniqueID;
479 return ret;
480}
481
482void update_model_animator(s32 animatorID) {
483 ModelAnimator* animator;
484 s32 temp;
485 s32 i;
486
487 if (gGameStatusPtr->context != CONTEXT_WORLD && !(animatorID & BATTLE_ID_BIT)) {
488 return;
489 }
490
491 animatorID &= ~BATTLE_ID_BIT;
492 animator = (*gCurrentAnimMeshListPtr)[animatorID];
493
494 if (animator == NULL || animator->flags == 0) {
495 return;
496 }
497
499 return;
500 }
501
502 animator->flags &= ~MODEL_ANIMATOR_FLAG_UPDATE_PENDING;
503 animator->nextUpdateTime -= animator->timeScale;
504
505 temp = 0;
506 if (animator->nextUpdateTime <= 0.0f) {
507 if (!(animator->flags & MODEL_ANIMATOR_FLAG_MESH)) {
508 do {
509 temp = step_model_animator(animator);
510 } while (temp > 0);
511 } else {
512 animator->nextUpdateTime = 1.0f;
514 do {
515 temp = step_mesh_animator(animator);
516 } while (temp > 0);
517 }
518 }
519 if (temp == -1) {
520 return;
521 }
522
523 animator_update_model_transforms(animator, NULL);
524
525 for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
526 if (D_801533C0[i].ttl >= 0) {
527 D_801533C0[i].ttl--;
528 if (D_801533C0[i].ttl == 0) {
529 D_801533C0[i].ttl = -1;
531 }
532 }
533 }
534
535 for (i = 0; i < ARRAY_COUNT(D_801536C0); i++) {
536 if (D_801536C0[i].ttl >= 0) {
537 D_801536C0[i].ttl--;
538 if (D_801536C0[i].ttl == 0) {
539 D_801536C0[i].ttl = -1;
541 }
542 }
543 }
544}
545
546void update_model_animator_with_transform(s32 animatorID, Mtx* mtx) {
547 ModelAnimator* animator;
548 s32 temp;
549 s32 i;
550
551 if (gGameStatusPtr->context != CONTEXT_WORLD && !(animatorID & BATTLE_ID_BIT)) {
552 return;
553 }
554
555 animatorID &= ~BATTLE_ID_BIT;
556 animator = (*gCurrentAnimMeshListPtr)[animatorID];
557
558 if (animator == NULL || animator->flags == 0) {
559 return;
560 }
561
563 return;
564 }
565
566 animator->flags &= ~MODEL_ANIMATOR_FLAG_UPDATE_PENDING;
567 animator->nextUpdateTime -= animator->timeScale;
568
569 temp = 0;
570 if (animator->nextUpdateTime <= 0.0f) {
571 if (!(animator->flags & MODEL_ANIMATOR_FLAG_MESH)) {
572 do {
573 temp = step_model_animator(animator);
574 } while (temp > 0);
575 } else {
576 animator->nextUpdateTime = 1.0f;
578 do {
579 temp = step_mesh_animator(animator);
580 } while (temp > 0);
581 }
582 }
583 if (temp == -1) {
584 return;
585 }
586
588
589 for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
590 if (D_801533C0[i].ttl >= 0) {
591 D_801533C0[i].ttl--;
592 if (D_801533C0[i].ttl == 0) {
593 D_801533C0[i].ttl = -1;
595 }
596 }
597 }
598
599 for (i = 0; i < ARRAY_COUNT(D_801536C0); i++) {
600 if (D_801536C0[i].ttl >= 0) {
601 D_801536C0[i].ttl--;
602 if (D_801536C0[i].ttl == 0) {
603 D_801536C0[i].ttl = -1;
605 }
606 }
607 }
608}
609
611 s16* args = animator->animReadPos;
612 AnimatorNode* node;
613 f32 x, y, z;
614 s32 flags;
615 s32 nodeId;
616
617 switch (*args++) {
618 case AS_END:
619 return -1;
621 animator->renderMode = *args++;
622 animator->animReadPos = args;
623 return 1;
624 case AS_WAIT:
625 animator->nextUpdateTime = *args++;
626 animator->animReadPos = args;
627 break;
628 case AS_END_LOOP:
629 animator->animReadPos = animator->savedReadPos;
630 return 1;
631 case AS_LOOP:
632 animator->animReadPos = animator->savedReadPos = args;
633 return 1;
634 case AS_SET_FLAGS:
635 flags = *args++;
636 animator->animReadPos = args;
637 animator->flags |= flags & 0xFFFF;
638 return 1;
640 node = get_animator_child_with_id(animator, animator->staticNodeIDs[*args++ - 1]);
641 flags = *args++;
642 node->flags |= flags;
643 animator->animReadPos = args;
644 return 1;
646 node = get_animator_child_with_id(animator, animator->staticNodeIDs[*args++ - 1]);
647 flags = *args++;
648 node->flags &= ~flags;
649 animator->animReadPos = args;
650 return 1;
651 case AS_OP_19:
653 animator->animReadPos = args;
654 return 1;
655 case AS_SET_ROTATION:
656 nodeId = animator->staticNodeIDs[*args++ - 1];
657 x = (f32)*args++ * 180.0 / 32767.0;
658 y = (f32)*args++ * 180.0 / 32767.0;
659 z = (f32)*args++ * 180.0 / 32767.0;
660 animator->animReadPos = args;
661
662 node = get_animator_child_with_id(animator, nodeId);
663 ASSERT(node != NULL);
664 node->rot.x = x;
665 node->rot.y = y;
666 node->rot.z = z;
667 return 1;
668 case AS_ADD_ROTATION:
669 nodeId = animator->staticNodeIDs[*args++ - 1];
670 x = (f32)*args++ * 180.0 / 32767.0;
671 y = (f32)*args++ * 180.0 / 32767.0;
672 z = (f32)*args++ * 180.0 / 32767.0;
673 animator->animReadPos = args;
674
675 node = get_animator_child_with_id(animator, nodeId);
676 ASSERT(node != NULL);
677 node->rot.x += x;
678 node->rot.y += y;
679 node->rot.z += z;
680 return 1;
681 case AS_SET_POS:
682 nodeId = animator->staticNodeIDs[*args++ - 1];
683 x = *args++;
684 y = *args++;
685 z = *args++;
686 animator->animReadPos = args;
687 node = get_animator_child_with_id(animator, nodeId);
688 ASSERT(node != NULL);
689 node->pos.x = x;
690 node->pos.y = y;
691 node->pos.z = z;
692 return 1;
693 case AS_SET_SCALE:
694 nodeId = animator->staticNodeIDs[*args++ - 1];
695 x = (f32)*args++ * 180.0 / 32767.0;
696 y = (f32)*args++ * 180.0 / 32767.0;
697 z = (f32)*args++ * 180.0 / 32767.0;
698 animator->animReadPos = args;
699
700 node = get_animator_child_with_id(animator, nodeId);
701 ASSERT(node != NULL);
702 node->scale.x = x;
703 node->scale.y = y;
704 node->scale.z = z;
705 return 1;
706 }
707 return 0;
708}
709
710void animator_update_model_transforms(ModelAnimator* animator, Mtx* rootTransform) {
711 Matrix4f flipMtx;
712
713 if (animator->rootNode != NULL) {
716 animator_make_mirrorZ(flipMtx);
717 break;
719 animator_make_mirrorY(flipMtx);
720 break;
722 animator_make_mirrorX(flipMtx);
723 break;
724 default:
725 animator_make_identity(flipMtx);
726 break;
727 }
728 animator_node_update_model_transform(animator, flipMtx, animator->rootNode, rootTransform);
729 }
730}
731
732void animator_node_update_model_transform(ModelAnimator* animator, f32 (*flipMtx)[4], AnimatorNode* node,
733 Mtx* rootTransform) {
734 Matrix4f sp10;
735 s32 i;
736
737 guRotateRPYF(gAnimRotMtx, clamp_angle(node->rot.x), clamp_angle(node->rot.y), clamp_angle(node->rot.z));
738 guScaleF(gAnimScaleMtx, node->scale.x, node->scale.y, node->scale.z);
739 guTranslateF(gAnimTranslateMtx, node->basePos.x + node->pos.x, node->basePos.y + node->pos.y, node->basePos.z + node->pos.z);
742
743 if (!(animator->flags & MODEL_ANIMATOR_FLAG_NO_FLIP)) {
744 guMtxCatF(sp10, flipMtx, sp10);
745 }
746
747 copy_matrix(sp10, node->mtx);
748
751
752 copy_matrix(sp10, model->userTransformMtx);
753 guMtxL2F(sp10, rootTransform);
754 guMtxCatF(model->userTransformMtx, sp10, model->userTransformMtx);
756 }
757
758 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
759 if (node->children[i] != NULL) {
760 animator_node_update_model_transform(animator, sp10, node->children[i], rootTransform);
761 }
762 }
763}
764
765void render_animated_model(s32 animatorID, Mtx* rootTransform) {
766 ModelAnimator* animator;
767 RenderTask rt;
768 RenderTask* rtPtr = &rt;
769
770 if (gGameStatusPtr->context != CONTEXT_WORLD && !(animatorID & BATTLE_ID_BIT)) {
771 return;
772 }
773
774 animatorID &= ~BATTLE_ID_BIT;
775 animator = (*gCurrentAnimMeshListPtr)[animatorID];
776
777 if (animator == NULL || animator->flags == 0) {
778 return;
779 }
780
782 && animator->flags & (1 << gCurrentCamID)
783 && !(animator->flags & MODEL_ANIMATOR_FLAG_HIDDEN)
784 ) {
785 animator->mtx = *rootTransform;
786 animator->baseAddr = NULL;
787 rtPtr->appendGfxArg = animator;
788 rtPtr->appendGfx = (void (*)(void*))appendGfx_animator;
789 rtPtr->dist = 0;
790 rtPtr->renderMode = animator->renderMode;
791 queue_render_task(rtPtr);
792 }
793}
794
795void render_animated_model_with_vertices(s32 animatorID, Mtx* rootTransform, s32 segment, void* baseAddr) {
796 ModelAnimator* animator;
797 RenderTask rt;
798 RenderTask* rtPtr = &rt;
799
800 if (gGameStatusPtr->context != CONTEXT_WORLD && !(animatorID & BATTLE_ID_BIT)) {
801 return;
802 }
803
804 animatorID &= ~BATTLE_ID_BIT;
805 animator = (*gCurrentAnimMeshListPtr)[animatorID];
806
807 if (animator == NULL || animator->flags == 0) {
808 return;
809 }
810
812 && animator->flags & (1 << gCurrentCamID)
813 && !(animator->flags & MODEL_ANIMATOR_FLAG_HIDDEN)
814 ) {
815 animator->mtx = *rootTransform;
816 gAnimVtxSegment = segment;
817 animator->baseAddr = baseAddr;
818 rtPtr->appendGfxArg = animator;
819 rtPtr->appendGfx = (void (*)(void*))appendGfx_animator;
820 rtPtr->dist = 0;
821 rtPtr->renderMode = animator->renderMode;
822 queue_render_task(rtPtr);
823 }
824}
825
827 Matrix4f sp10;
828
829 if (animator->baseAddr != NULL) {
830 gSPSegment(gMainGfxPos++, gAnimVtxSegment, VIRTUAL_TO_PHYSICAL(animator->baseAddr));
831 }
832
834 gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
835
836 //TODO find better match
837 switch (gAnimModelFogEnabled != 0) {
838 case FALSE:
839 switch (animator->renderMode) {
841 gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_OPA);
842 break;
844 gSPDisplayList(gMainGfxPos++, Gfx_RM1_DECAL_OPA);
845 break;
847 gSPDisplayList(gMainGfxPos++, Gfx_RM1_INTERSECTING_OPA);
848 break;
850 gSPDisplayList(gMainGfxPos++, Gfx_RM1_ALPHATEST);
851 break;
853 gSPDisplayList(gMainGfxPos++, Gfx_RM1_SURFACE_XLU);
854 break;
856 gSPDisplayList(gMainGfxPos++, Gfx_RM1_DECAL_XLU);
857 break;
859 gSPDisplayList(gMainGfxPos++, Gfx_RM1_INTERSECTING_XLU);
860 break;
861 }
862 break;
863 case TRUE:
864 switch (animator->renderMode) {
866 gSPDisplayList(gMainGfxPos++, Gfx_RM3_SURFACE_OPA);
867 break;
869 gSPDisplayList(gMainGfxPos++, Gfx_RM3_DECAL_OPA);
870 break;
872 gSPDisplayList(gMainGfxPos++, Gfx_RM3_INTERSECTING_OPA);
873 break;
875 gSPDisplayList(gMainGfxPos++, Gfx_RM3_ALPHATEST);
876 break;
878 gSPDisplayList(gMainGfxPos++, Gfx_RM3_SURFACE_XLU);
879 break;
881 gSPDisplayList(gMainGfxPos++, Gfx_RM3_DECAL_XLU);
882 break;
884 gSPDisplayList(gMainGfxPos++, Gfx_RM3_INTERSECTING_XLU);
885 break;
886 }
887
890 break;
891 }
892
893 guMtxL2F(sp10, &animator->mtx);
894 appendGfx_animator_node(animator, animator->rootNode, sp10);
895 gSPPopMatrix(gMainGfxPos++, G_MTX_MODELVIEW);
896}
897
899 DisplayListBufferHandle* bufferHandle;
900 u32 w0,w1;
901 s32 cmd;
902 s32 i;
903
904 if (node->flags & MODEL_ANIMATOR_FLAG_HIDDEN) {
905 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
906 if (node->children[i] != NULL) {
907 guMtxCatF(node->mtx, mtx, node->mtx);
908 appendGfx_animator_node(animator, node->children[i], node->mtx);
909 }
910 }
911 return;
912 }
913
914 guMtxCatF(node->mtx, mtx, node->mtx);
916 gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
917 gDPPipeSync(gMainGfxPos++);
918
919 gSPTexture(gMainGfxPos++, 0, 0, 0, G_TX_RENDERTILE, G_OFF);
920 gDPSetTextureLOD(gMainGfxPos++, G_TL_TILE);
921 gDPSetTextureLUT(gMainGfxPos++, G_TT_NONE);
922 gSPClearGeometryMode(gMainGfxPos++, G_LIGHTING);
923 if (animator->flags & MODEL_ANIMATOR_FLAG_CULL_BACK) {
924 gSPSetGeometryMode(gMainGfxPos++, G_CULL_BACK);
925 }
927 gDPSetCombineMode(gMainGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA);
928 } else {
929 gDPSetCombineMode(gMainGfxPos++, PM_CC_42, PM_CC2_MULTIPLY_SHADE);
930 }
931 gDPPipeSync(gMainGfxPos++);
932
933 if (animator->fpRenderCallback != NULL) animator->fpRenderCallback(animator->renderCallbackArg);
934
935 gDPPipeSync(gMainGfxPos++);
936
937 if (node->displayList != NULL) {
938 if (node->vertexStartOffset < 0) {
939 gSPDisplayList(gMainGfxPos++, node->displayList);
940 } else {
941 Gfx* gfxPos;
942 s32 vtxIdx, dlIdx;
943 s32 j = 0;
944 s32 k;
945
946 if ((node->displayList[0].words.w0 >> 0x18) != G_ENDDL) {
947 Gfx* gfxPtr = node->displayList;
948 s32 endDL = G_ENDDL;
949
950 for(;; j++) {
951 w0 = gfxPtr->words.w0;
952 gfxPtr++;
953 cmd = w0 >> 0x18;
954 if (cmd == endDL) {
955 break;
956 }
957 }
958 }
959 j++;
960 for (k = 0; k < ARRAY_COUNT(D_801536C0); k++) {
961 bufferHandle = &D_801536C0[k];
962 if (bufferHandle->ttl < 0) {
963 break;
964 }
965 }
967
968 bufferHandle->addr = gfxPos = general_heap_malloc(j * sizeof(Gfx));
969 ASSERT(gfxPos != NULL);
970 bufferHandle->ttl = 3;
971
972 vtxIdx = 0;
973 dlIdx = 0;
974
975 do {
976 w0 = ((s32*)node->displayList)[dlIdx++];
977 w1 = ((s32*)node->displayList)[dlIdx++];
978 cmd = w0 >> 0x18;
979 if (cmd == G_ENDDL) {
980 break;
981 }
982 if (cmd == G_VTX) {
983 s32 startIdx = _SHIFTR(w0,1,7);
984 s32 vtxCount = _SHIFTR(w0,12,8);
985 Vtx* newBuffer;
986
987 startIdx -= vtxCount;
988
989 if (node->fcData.vtxList == NULL) {
990 newBuffer = &((Vtx*)w1)[node->vertexStartOffset + vtxIdx];
991 gSPVertex(gfxPos++, newBuffer, vtxCount, startIdx);
992 } else {
994 animator,
995 node,
996 (Vec3s*)(w1 + (node->vertexStartOffset + vtxIdx) * 0x6),
997 vtxCount,
998 startIdx,
999 vtxIdx
1000 );
1001 gSPVertex(gfxPos++, newBuffer, vtxCount, startIdx);
1002 }
1003 vtxIdx += vtxCount;
1004 } else {
1005 Gfx* temp[1] = {gfxPos++}; // required to match
1006 temp[0]->words.w0 = w0;
1007 temp[0]->words.w1 = w1;
1008 }
1009 } while (TRUE);
1010
1011 gSPEndDisplayList(gfxPos++);
1012 gSPDisplayList(gMainGfxPos++, bufferHandle->addr);
1013 }
1014 }
1015 gDPPipeSync(gMainGfxPos++);
1016
1017 for (i = 0; i < ARRAY_COUNT(node->children); i++) {
1018 if (node->children[i] != NULL) {
1019 appendGfx_animator_node(animator, node->children[i], node->mtx);
1020 }
1021 }
1022}
1023
1025 return get_animator_child_with_id(animator, animator->staticNodeIDs[arg1 - 1]);
1026}
1027
1029 return get_animator_child_for_model(animator->rootNode, id);
1030}
1031
1032void set_animator_tree_to_node_map(ModelAnimator* animator, s32* nodeIDs, s32 count) {
1033 s32 i;
1034
1035 for (i = 0; i < count; i++) {
1036 animator->staticNodeIDs[i] = *nodeIDs;
1037 nodeIDs++;
1038 }
1039}
1040
1042 return (*gCurrentAnimMeshListPtr)[animModelID & ~BATTLE_ID_BIT];
1043}
1044
1045ModelAnimator* set_animator_render_callback(s32 animModelID, void* callbackArg, void (*callbackFunc)(void*)) {
1046 ModelAnimator* ret = (*gCurrentAnimMeshListPtr)[animModelID & ~BATTLE_ID_BIT];
1047
1048 ret->fpRenderCallback = callbackFunc;
1049 ret->renderCallbackArg = callbackArg;
1050 return ret;
1051}
1052
1054 gAnimModelFogEnabled = TRUE;
1055}
1056
1058 gAnimModelFogEnabled = FALSE;
1059}
1060
1061void set_anim_model_fog_dist(s32 start, s32 end) {
1062 gAnimModelFogStart = start;
1063 gAnimModelFogEnd = end;
1064}
1065
1066void set_anim_model_fog_color(s32 r, s32 g, s32 b, s32 a) {
1067 gAnimModelFogR = r;
1068 gAnimModelFogG = g;
1069 gAnimModelFogB = b;
1070 gAnimModelFogA = a;
1071}
1072
1076
1077void get_anim_model_fog_distance(s32* start, s32* end) {
1078 *start = gAnimModelFogStart;
1079 *end = gAnimModelFogEnd;
1080}
1081
1082void get_anim_model_fog_color(s32* r, s32* g, s32* b, s32* a) {
1083 *r = gAnimModelFogR;
1084 *g = gAnimModelFogG;
1085 *b = gAnimModelFogB;
1086 *a = gAnimModelFogA;
1087}
1088
1089void set_animator_flags(s32 index, s32 bits) {
1090 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[index & ~BATTLE_ID_BIT];
1091
1092 animator->flags |= bits;
1093}
1094
1095void clear_animator_flags(s32 index, s32 bits) {
1096 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[index & ~BATTLE_ID_BIT];
1097
1098 animator->flags &= ~bits;
1099}
1100
1101void play_model_animation(s32 index, s16* animPos) {
1102 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[index & ~BATTLE_ID_BIT];
1103
1104 if (animator->animationBuffer != NULL) {
1105 animPos = (s16*) (((s32)animPos & 0xFFFFFF) + (s32)animator->animationBuffer); // TODO: array access? / cleanup
1106 }
1107 animator->animReadPos = animPos;
1108 animator->savedReadPos = animPos;
1109 animator->treeIndexPos = 0;
1110 animator->nextUpdateTime = 1.0f;
1111}
1112
1113void play_model_animation_starting_from(s32 index, s16* animPos, s32 framesToSkip) {
1114 s32 indexMasked = index & ~BATTLE_ID_BIT;
1115 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[indexMasked];
1116 s32 i;
1117
1118 if (animator->animationBuffer != NULL) {
1119 animPos = (s16*) (((s32)animPos & 0xFFFFFF) + (s32)animator->animationBuffer); // TODO: array access? / cleanup
1120 }
1121
1122 animator->animReadPos = animPos;
1123 animator->savedReadPos = animPos;
1124 animator->treeIndexPos = 0;
1125 animator->nextUpdateTime = 1.0f;
1126
1127 for (i = 0; i < framesToSkip; i++) {
1128 update_model_animator(indexMasked);
1129 }
1130}
1131
1132void load_model_animator_node(StaticAnimatorNode* node, ModelAnimator* animator, s32 parentNodeID, s32* treeIndexToNodeIDs) {
1134 AnimatorNodeBlueprint* bpPtr = &bp;
1135 AnimatorNode* newNode;
1136 s32 i;
1137
1138 if (node != NULL) {
1139 bpPtr->displayList = node->displayList;
1140 bpPtr->basePos.x = 0.0f;
1141 bpPtr->basePos.y = 0.0f;
1142 bpPtr->basePos.z = 0.0f;
1143 bpPtr->rot.x = ((f32) node->rot.x * 180.0) / 32767.0;
1144 bpPtr->rot.y = ((f32) node->rot.y * 180.0) / 32767.0;
1145 bpPtr->rot.z = ((f32) node->rot.z * 180.0) / 32767.0;
1146
1147 newNode = add_anim_node(animator, parentNodeID, bpPtr);
1148
1149 if (node->modelID != 0) {
1150 newNode->fcData.modelID = node->modelID - 1;
1152 }
1153
1154 i = 0;
1155 while (gAnimTreeRoot[i] != node) {
1156 i++;
1157 }
1158
1159 treeIndexToNodeIDs[i] = newNode->uniqueIndex;
1160
1161 if (node->child != NULL) {
1162 load_model_animator_node(node->child, animator, newNode->uniqueIndex, treeIndexToNodeIDs);
1163 }
1164
1165 if (node->sibling != NULL) {
1166 load_model_animator_node(node->sibling, animator, parentNodeID, treeIndexToNodeIDs);
1167 }
1168 }
1169}
1170
1172 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[index & ~BATTLE_ID_BIT];
1173 s32 nodeIDs[ARRAY_COUNT(animator->staticNodeIDs)];
1174
1175 if (animator == NULL || animator->flags == 0) {
1176 return;
1177 }
1178
1179 gAnimTreeRoot = tree;
1180 load_model_animator_node(*tree, animator, 0, nodeIDs);
1181 set_animator_tree_to_node_map(animator, nodeIDs, ARRAY_COUNT(animator->staticNodeIDs));
1182}
1183
1184void load_mesh_animator_node(StaticAnimatorNode* node, ModelAnimator* animator, s32 parentNodeID, s32* treeIndexToNodeIDs) {
1185 if (node != NULL) {
1186 if (node->child != NULL && parentNodeID == 0) {
1187 load_mesh_animator_node(node->child, animator, 0, treeIndexToNodeIDs);
1188 } else {
1189 do {
1190 animator->staticNodes[parentNodeID] = node;
1191 node = node->sibling;
1192 parentNodeID++;
1193 } while (node != NULL);
1194 }
1195 }
1196}
1197
1199 s32 indexMasked = index & ~BATTLE_ID_BIT;
1200 ModelAnimator* animator = (*gCurrentAnimMeshListPtr)[indexMasked];
1201 s32 nodeIDs[ARRAY_COUNT(animator->staticNodeIDs)];
1202 s32 i;
1203
1204 if (animator == NULL || animator->flags == 0) {
1205 return;
1206 }
1207
1208 if ((*tree)->vertexStartOffset == 0) {
1209 load_model_animator_tree(indexMasked, tree);
1210 return;
1211 }
1212
1213 gAnimTreeRoot = tree;
1214 animator->staticRoot = tree;
1215 animator->treeIndexPos = 0;
1216 animator->savedTreePos = 0;
1217
1218 for (i = 0; i < ARRAY_COUNT(animator->staticNodes); i++) {
1219 animator->staticNodes[i] = NULL;
1220 }
1221
1222 load_mesh_animator_node(*gAnimTreeRoot, animator, 0, nodeIDs);
1223 animator->flags |= MODEL_ANIMATOR_FLAG_MESH;
1224}
1225
1226void reload_mesh_animator_node(StaticAnimatorNode* node, ModelAnimator* animator, s32 parentNodeID, s32* treeIndexToNodeIDs) {
1228 AnimatorNodeBlueprint* bpPtr = &bp;
1229 AnimatorNode* newNode;
1230 s32 i;
1231
1232 if (node != NULL) {
1233 bpPtr->displayList = node->displayList;
1234 bpPtr->basePos.x = 0.0f;
1235 bpPtr->basePos.y = 0.0f;
1236 bpPtr->basePos.z = 0.0f;
1237 bpPtr->rot.x = ((f32) node->rot.x * 180.0) / 32767.0;
1238 bpPtr->rot.y = ((f32) node->rot.y * 180.0) / 32767.0;
1239 bpPtr->rot.z = ((f32) node->rot.z * 180.0) / 32767.0;
1240
1241 newNode = add_anim_node(animator, parentNodeID, bpPtr);
1242 newNode->vertexStartOffset = node->vertexStartOffset;
1243 newNode->fcData.vtxList = node->vtxList;
1244
1245 i = 0;
1246 while (gAnimTreeRoot[i] != node) {
1247 i++;
1248 }
1249
1250 treeIndexToNodeIDs[i] = newNode->uniqueIndex;
1251
1252 if (node->child != NULL) {
1253 reload_mesh_animator_node(node->child, animator, newNode->uniqueIndex, treeIndexToNodeIDs);
1254 }
1255 }
1256}
1257
1259 s32 nodeIDs[ARRAY_COUNT(animator->staticNodeIDs)];
1260 s32 i;
1261
1263 gAnimTreeRoot = animator->staticRoot;
1264
1265 for (i = 0; i < ARRAY_COUNT(animator->staticNodes); i++) {
1266 nodeIDs[i] = 0;
1267 }
1268
1269 reload_mesh_animator_node(animator->staticNodes[animator->treeIndexPos], animator, 0, nodeIDs);
1270 nodeIDs[0] = -1;
1271 set_animator_tree_to_node_map(animator, nodeIDs, ARRAY_COUNT(nodeIDs));
1272}
1273
1275 s16* args = animator->animReadPos;
1276 s16* oldPos = animator->animReadPos;
1277 AnimatorNode* node;
1278 f32 x, y, z;
1279 s32 flags;
1280 s32 nodeId;
1281
1282 switch (*args++) {
1283 case AS_END:
1284 return -1;
1285 case AS_SET_RENDER_MODE:
1286 animator->renderMode = *args++;
1287 animator->animReadPos = args;
1288 return 1;
1289 case AS_WAIT:
1290 args++;
1291 animator->animReadPos = args;
1292 return 1;
1293 case AS_END_LOOP:
1294 animator->animReadPos = animator->savedReadPos;
1295 animator->treeIndexPos = animator->savedTreePos;
1296 reload_mesh_animator_tree(animator);
1297 return 1;
1298 case AS_OP_4:
1299 animator->animReadPos = animator->savedReadPos;
1300 animator->treeIndexPos = animator->savedTreePos;
1301 break;
1302 case AS_LOOP:
1303 animator->animReadPos = animator->savedReadPos = args;
1304 animator->savedTreePos = animator->treeIndexPos;
1305 return 1;
1306 case AS_SET_FLAGS:
1307 flags = *args++;
1308 animator->animReadPos = args;
1309 animator->flags |= flags & 0xFFFF;
1310 return 1;
1311 case AS_SET_NODE_FLAGS:
1312 node = get_animator_child_with_id(animator, animator->staticNodeIDs[*args++ - 1]);
1313 flags = *args++;
1314 node->flags |= flags;
1315 animator->animReadPos = args;
1316 return 1;
1318 node = get_animator_child_with_id(animator, animator->staticNodeIDs[*args++ - 1]);
1319 flags = *args++;
1320 node->flags &= ~flags;
1321 animator->animReadPos = args;
1322 return 1;
1323 case AS_OP_19:
1325 animator->animReadPos = args;
1326 return 1;
1327 case AS_SET_ROTATION:
1328 nodeId = animator->staticNodeIDs[*args++ - 1];
1329 x = (f32)*args++ * 180.0 / 32767.0;
1330 y = (f32)*args++ * 180.0 / 32767.0;
1331 z = (f32)*args++ * 180.0 / 32767.0;
1332 animator->animReadPos = args;
1333 if (nodeId != 0xFF) {
1334 node = get_animator_child_with_id(animator, nodeId);
1335 if (node != NULL) {
1336 node->rot.x = x;
1337 node->rot.y = y;
1338 node->rot.z = z;
1339 return 1;
1340 } else {
1341 animator->animReadPos = oldPos;
1342 animator->treeIndexPos++;
1343 break;
1344 }
1345 }
1346 return 1;
1347 case AS_ADD_ROTATION:
1348 nodeId = animator->staticNodeIDs[*args++ - 1];
1349 x = (f32)*args++ * 180.0 / 32767.0;
1350 y = (f32)*args++ * 180.0 / 32767.0;
1351 z = (f32)*args++ * 180.0 / 32767.0;
1352 animator->animReadPos = args;
1353 if (nodeId != 0xFF) {
1354 node = get_animator_child_with_id(animator, nodeId);
1355 if (node != NULL) {
1356 node->rot.x += x;
1357 node->rot.y += y;
1358 node->rot.z += z;
1359 return 1;
1360 } else {
1361 animator->animReadPos = oldPos;
1362 animator->treeIndexPos++;
1363 break;
1364 }
1365 }
1366 return 1;
1367 case AS_SET_POS:
1368 nodeId = animator->staticNodeIDs[*args++ - 1];
1369 x = *args++;
1370 y = *args++;
1371 z = *args++;
1372 animator->animReadPos = args;
1373 if (nodeId != 0xFF) {
1374 node = get_animator_child_with_id(animator, nodeId);
1375 if (node != NULL) {
1376 node->pos.x = x;
1377 node->pos.y = y;
1378 node->pos.z = z;
1379 return 1;
1380 } else {
1381 animator->animReadPos = oldPos;
1382 animator->treeIndexPos++;
1383 break;
1384 }
1385 }
1386 return 1;
1387 case AS_SET_SCALE:
1388 nodeId = animator->staticNodeIDs[*args++ - 1];
1389 x = (f32)*args++ * 180.0 / 32767.0;
1390 y = (f32)*args++ * 180.0 / 32767.0;
1391 z = (f32)*args++ * 180.0 / 32767.0;
1392 animator->animReadPos = args;
1393 if (nodeId != 0xFF) {
1394 node = get_animator_child_with_id(animator, nodeId);
1395 if (node != NULL) {
1396 node->scale.x = x;
1397 node->scale.y = y;
1398 node->scale.z = z;
1399 return 1;
1400 } else {
1401 animator->animReadPos = oldPos;
1402 animator->treeIndexPos++;
1403 break;
1404 }
1405 }
1406 return 1;
1407 }
1408 return 0;
1409}
#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:1101
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:795
void set_anim_model_fog_color(s32 r, s32 g, s32 b, s32 a)
Definition animator.c:1066
void set_animator_tree_to_node_map(ModelAnimator *animator, s32 *nodeIDs, s32 count)
Definition animator.c:1032
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:1077
ModelAnimator * set_animator_render_callback(s32 animModelID, void *callbackArg, void(*callbackFunc)(void *))
Definition animator.c:1045
void disable_anim_model_fog(void)
Definition animator.c:1057
void render_animated_model(s32 animatorID, Mtx *rootTransform)
Definition animator.c:765
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:1053
BSS s32 gAnimModelFogStart
Definition animator.c:24
void set_animator_flags(s32 index, s32 bits)
Definition animator.c:1089
void appendGfx_animator_node(ModelAnimator *, AnimatorNode *, Matrix4f)
Definition animator.c:898
AnimatorNode * get_animator_node_with_id(ModelAnimator *animator, s32 id)
Definition animator.c:1028
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:732
void reload_mesh_animator_tree(ModelAnimator *animator)
Definition animator.c:1258
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:1082
void delete_model_animator(ModelAnimator *animator)
Definition animator.c:297
void clear_animator_flags(s32 index, s32 bits)
Definition animator.c:1095
void play_model_animation_starting_from(s32 index, s16 *animPos, s32 framesToSkip)
Definition animator.c:1113
void load_mesh_animator_node(StaticAnimatorNode *node, ModelAnimator *animator, s32 parentNodeID, s32 *treeIndexToNodeIDs)
Definition animator.c:1184
void delete_model_animator_node(AnimatorNode *node)
Definition animator.c:269
ModelAnimator * get_animator_by_index(s32 animModelID)
Definition animator.c:1041
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:1198
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:1073
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:482
void appendGfx_animator(ModelAnimator *animator)
Definition animator.c:826
Gfx Gfx_RM1_SURFACE_XLU[]
Definition model.c:686
void load_model_animator_tree(s32 index, StaticAnimatorNode **tree)
Definition animator.c:1171
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:1132
s32 step_mesh_animator(ModelAnimator *animator)
Definition animator.c:1274
s32 step_model_animator(ModelAnimator *animator)
Definition animator.c:610
void update_model_animator_with_transform(s32 animatorID, Mtx *mtx)
Definition animator.c:546
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:1226
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:1024
BSS StaticAnimatorNode ** gAnimTreeRoot
Definition animator.c:31
void set_anim_model_fog_dist(s32 start, s32 end)
Definition animator.c:1061
void animator_update_model_transforms(ModelAnimator *animator, Mtx *rootTransform)
Definition animator.c:710
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
struct StaticAnimatorNode * child
struct StaticAnimatorNode * sibling
Mtx matrixStack[0x200]
union AnimatorNode::@29 fcData
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:4369
@ MODEL_ANIMATOR_FLAG_CAM_2
Definition enums.h:4913
@ MODEL_ANIMATOR_FLAG_HAS_MODEL
Definition enums.h:4923
@ MODEL_ANIMATOR_FLAG_CULL_BACK
Definition enums.h:4927
@ MODEL_ANIMATOR_FLAG_NO_FLIP
Definition enums.h:4928
@ MODEL_ANIMATOR_FLAG_MESH
Definition enums.h:4926
@ MODEL_ANIMATOR_FLAG_CAM_1
Definition enums.h:4912
@ MODEL_ANIMATOR_FLAG_FREEZE_ANIMATION
Definition enums.h:4929
@ MODEL_ANIMATOR_FLAG_FLIP_Y
Definition enums.h:4920
@ MODEL_ANIMATOR_FLAG_FLIP_X
Definition enums.h:4921
@ MODEL_ANIMATOR_FLAG_CAM_0
Definition enums.h:4911
@ MODEL_ANIMATOR_FLAG_HIDDEN
Definition enums.h:4918
@ MODEL_ANIMATOR_FLAG_ENABLED
Definition enums.h:4915
@ MODEL_ANIMATOR_FLAG_FLIP_Z
Definition enums.h:4919
@ MODEL_ANIMATOR_FLAG_UPDATE_PENDING
Definition enums.h:4917
@ CONTEXT_WORLD
Definition enums.h:3529
@ RENDER_MODE_DECAL_OPA
Definition enums.h:3268
@ RENDER_MODE_INTERSECTING_XLU
Definition enums.h:3303
@ RENDER_MODE_DECAL_XLU
Definition enums.h:3291
@ RENDER_MODE_INTERSECTING_OPA
Definition enums.h:3272
@ RENDER_MODE_ALPHATEST
Definition enums.h:3276
@ RENDER_MODE_SURFACE_OPA
Definition enums.h:3264
@ RENDER_MODE_SURFACE_XLU_LAYER1
Definition enums.h:3282
s32 get_model_list_index_from_tree_index(s32 treeIndex)
Definition model.c:3397
struct Model * get_model_from_list_index(s32 listIndex)
Definition model.c:3315
s32 heap_free(void *ptr)
Definition heap.c:42
void copy_matrix(Matrix4f src, Matrix4f dest)
Definition 43F0.c:439
s32 general_heap_free(void *data)
Definition heap.c:18
void * heap_malloc(s32 size)
Definition heap.c:34
u16 flags
Definition model.h:60
Matrix4f userTransformMtx
Definition model.h:68
Definition model.h:59
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define PM_CC2_MULTIPLY_SHADE
Definition macros.h:308
#define PM_CC_42
Definition macros.h:467
#define BATTLE_ID_BIT
Definition macros.h:144
#define VIRTUAL_TO_PHYSICAL(addr)
Definition macros.h:47
u8 staticNodeIDs[0x7A]
void(* fpRenderCallback)(void *)
AnimatorNode * rootNode
StaticAnimatorNode * staticNodes[0x7A]
AnimatorNode * nodeCache[0x7A]
StaticAnimatorNode ** staticRoot
void * appendGfxArg
void(* appendGfx)(void *)
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Gfx * gMainGfxPos
Definition cam_main.c:15
u16 gMatrixListPos
Definition main_loop.c:45
DisplayContext * gDisplayContext
Definition cam_main.c:16
s16 gCurrentCamID
Definition cam_main.c:13