Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/goddard/objects.c
7858 views
1
#include <PR/ultratypes.h>
2
#include <stdarg.h>
3
#include <stdio.h>
4
5
#include "objects.h"
6
7
#include "debug_utils.h"
8
#include "draw_objects.h"
9
#include "dynlist_proc.h"
10
#include "gd_macros.h"
11
#include "gd_main.h"
12
#include "gd_math.h"
13
#include "gd_types.h"
14
#include "joints.h"
15
#include "macros.h"
16
#include "old_menu.h"
17
#include "particles.h"
18
#include "renderer.h"
19
#include "sfx.h"
20
#include "shape_helper.h"
21
#include "skin.h"
22
23
// structs
24
struct Unk801B9E68 {
25
/* 0x00 */ s32 count;
26
/* 0x04 */ u8 pad[0x14];
27
}; /* sizeof() = 0x18 */
28
29
struct Unk8017F3CC {
30
/*0x00*/ u8 pad[0x20];
31
/*0x20*/ struct GdVec3f unk20;
32
};
33
34
// data
35
f32 D_801A81C0 = 0.0f;
36
f32 D_801A81C4 = 0.0f;
37
38
// bss
39
struct GdBoundingBox gSomeBoundingBox;
40
struct ObjCamera *sCurrentMoveCamera; // @ 801B9DB8
41
struct ObjView *sCurrentMoveView; // @ 801B9DBC
42
struct DebugCounters gGdCounter; // @ 801B9DC0
43
Mat4f D_801B9DC8;
44
struct GdVec3f D_801B9E08;
45
struct ObjGroup *sCurrentMoveGrp; // @ 801B9E14
46
struct GdVec3f D_801B9E18;
47
struct GdVec3f D_801B9E28;
48
f32 D_801B9E34;
49
Mat4f *D_801B9E38;
50
struct ObjParticle *D_801B9E3C;
51
s32 D_801B9E40;
52
s32 D_801B9E44;
53
Mat4f *D_801B9E48;
54
struct ObjCamera *gGdCameraList; // @ 801B9E4C
55
void *D_801B9E50;
56
struct ObjGroup *gGdGroupList; // @ 801B9E54
57
s32 gGdObjCount; // @ 801B9E58
58
s32 gGdGroupCount; // @ 801B9E5C
59
s32 gGdPlaneCount; // @ 801B9E60
60
s32 gGdCameraCount; // @ 801B9E64
61
struct Unk801B9E68 sGdViewInfo; // @ 801B9E68
62
void *D_801B9E80;
63
struct ObjJoint *gGdJointList; // @ 801B9E84
64
struct ObjBone *gGdBoneList; // @ 801B9E88
65
struct GdObj *gGdObjectList; // head of linked list containing every single GdObj that was created
66
struct ObjGroup *gGdViewsGroup; // @ 801B9E90
67
68
/* @ 22A480 for 0x70 */
69
void reset_bounding_box(void) { /* Initialize Plane? */
70
gSomeBoundingBox.minX = 10000000.0f;
71
gSomeBoundingBox.minY = 10000000.0f;
72
gSomeBoundingBox.minZ = 10000000.0f;
73
74
gSomeBoundingBox.maxX = -10000000.0f;
75
gSomeBoundingBox.maxY = -10000000.0f;
76
gSomeBoundingBox.maxZ = -10000000.0f;
77
}
78
79
void add_obj_pos_to_bounding_box(struct GdObj *obj) {
80
struct GdVec3f pos;
81
82
set_cur_dynobj(obj);
83
d_get_world_pos(&pos);
84
85
if (pos.x < gSomeBoundingBox.minX) {
86
gSomeBoundingBox.minX = pos.x;
87
}
88
89
if (pos.y < gSomeBoundingBox.minY) {
90
gSomeBoundingBox.minY = pos.y;
91
}
92
93
if (pos.z < gSomeBoundingBox.minZ) {
94
gSomeBoundingBox.minZ = pos.z;
95
}
96
97
if (pos.x > gSomeBoundingBox.maxX) {
98
gSomeBoundingBox.maxX = pos.x;
99
}
100
101
if (pos.y > gSomeBoundingBox.maxY) {
102
gSomeBoundingBox.maxY = pos.y;
103
}
104
105
if (pos.z > gSomeBoundingBox.maxZ) {
106
gSomeBoundingBox.maxZ = pos.z;
107
}
108
}
109
110
/* @ 22A630 for 0x70 */
111
void get_some_bounding_box(struct GdBoundingBox *a0) {
112
a0->minX = gSomeBoundingBox.minX;
113
a0->minY = gSomeBoundingBox.minY;
114
a0->minZ = gSomeBoundingBox.minZ;
115
116
a0->maxX = gSomeBoundingBox.maxX;
117
a0->maxY = gSomeBoundingBox.maxY;
118
a0->maxZ = gSomeBoundingBox.maxZ;
119
}
120
121
/* @ 22A6A0 for 0x24 */
122
void stub_objects_1(UNUSED struct ObjGroup *a0, UNUSED struct GdObj *a1) {
123
UNUSED u8 sp00[8];
124
/* Debug stub? */
125
return;
126
}
127
128
/**
129
* Returns a string containing the name of the the object type
130
*/
131
static const char *get_obj_name_str(enum ObjTypeFlag objFlag) {
132
const char *objName;
133
switch (objFlag) {
134
case OBJ_TYPE_JOINTS:
135
objName = "joints";
136
break;
137
case OBJ_TYPE_BONES:
138
objName = "bones";
139
break;
140
case OBJ_TYPE_GROUPS:
141
objName = "groups";
142
break;
143
case OBJ_TYPE_PARTICLES:
144
objName = "particles";
145
break;
146
case OBJ_TYPE_SHAPES:
147
objName = "shapes";
148
break;
149
case OBJ_TYPE_NETS:
150
objName = "nets";
151
break;
152
case OBJ_TYPE_PLANES:
153
objName = "planes";
154
break;
155
case OBJ_TYPE_VERTICES:
156
objName = "vertices";
157
break;
158
case OBJ_TYPE_CAMERAS:
159
objName = "cameras";
160
break;
161
case OBJ_TYPE_FACES:
162
objName = "faces";
163
break;
164
case OBJ_TYPE_MATERIALS:
165
objName = "materials";
166
break;
167
case OBJ_TYPE_LIGHTS:
168
objName = "lights";
169
break;
170
case OBJ_TYPE_WEIGHTS:
171
objName = "weights";
172
break;
173
case OBJ_TYPE_GADGETS:
174
objName = "gadgets";
175
break;
176
case OBJ_TYPE_VIEWS:
177
objName = "views";
178
break;
179
case OBJ_TYPE_LABELS:
180
objName = "labels";
181
break;
182
case OBJ_TYPE_ANIMATORS:
183
objName = "animators";
184
break;
185
case OBJ_TYPE_VALPTRS:
186
objName = "valptrs";
187
break;
188
case OBJ_TYPE_ZONES:
189
objName = "zones";
190
break;
191
default:
192
objName = "unkown";
193
break;
194
}
195
return objName;
196
}
197
198
/**
199
* Creates an object of the specified type
200
*/
201
struct GdObj *make_object(enum ObjTypeFlag objType) {
202
struct GdObj *newObj;
203
struct GdObj *objListOldHead;
204
s32 objSize;
205
s32 i;
206
drawmethod_t objDrawFn;
207
const char *typeName;
208
u8 *newObjBytes;
209
s32 objPermanence = 0x10;
210
211
imin("make_object");
212
213
switch (objType) {
214
case OBJ_TYPE_JOINTS:
215
objSize = sizeof(struct ObjJoint);
216
objDrawFn = (drawmethod_t) draw_joint;
217
break;
218
case OBJ_TYPE_BONES:
219
objSize = sizeof(struct ObjBone);
220
objDrawFn = (drawmethod_t) draw_bone;
221
break;
222
case OBJ_TYPE_GROUPS:
223
objSize = sizeof(struct ObjGroup);
224
objDrawFn = (drawmethod_t) draw_group;
225
break;
226
case OBJ_TYPE_PARTICLES:
227
objSize = sizeof(struct ObjParticle);
228
objDrawFn = (drawmethod_t) draw_particle;
229
break;
230
case OBJ_TYPE_SHAPES:
231
objSize = sizeof(struct ObjShape);
232
// Shapes get drawn by their parent object instead of automatically.
233
objDrawFn = (drawmethod_t) draw_nothing;
234
break;
235
case OBJ_TYPE_UNK200000:
236
objSize = sizeof(struct ObjUnk200000);
237
objDrawFn = (drawmethod_t) draw_nothing;
238
break;
239
case OBJ_TYPE_NETS:
240
objSize = sizeof(struct ObjNet);
241
objDrawFn = (drawmethod_t) draw_net;
242
break;
243
case OBJ_TYPE_PLANES:
244
objSize = sizeof(struct ObjPlane);
245
objDrawFn = (drawmethod_t) draw_plane;
246
break;
247
case OBJ_TYPE_VERTICES:
248
objSize = sizeof(struct ObjVertex);
249
objDrawFn = (drawmethod_t) draw_nothing;
250
break;
251
case OBJ_TYPE_CAMERAS:
252
objSize = sizeof(struct ObjCamera);
253
objDrawFn = (drawmethod_t) draw_camera;
254
break;
255
case OBJ_TYPE_FACES:
256
objSize = sizeof(struct ObjFace);
257
objDrawFn = (drawmethod_t) draw_face;
258
objPermanence = 1;
259
break;
260
case OBJ_TYPE_MATERIALS:
261
objSize = sizeof(struct ObjMaterial);
262
objDrawFn = (drawmethod_t) draw_material;
263
break;
264
case OBJ_TYPE_LIGHTS:
265
objSize = sizeof(struct ObjLight);
266
objDrawFn = (drawmethod_t) draw_light;
267
break;
268
case OBJ_TYPE_WEIGHTS:
269
objSize = sizeof(struct ObjWeight);
270
objDrawFn = (drawmethod_t) draw_nothing;
271
break;
272
case OBJ_TYPE_GADGETS:
273
objSize = sizeof(struct ObjGadget);
274
objDrawFn = (drawmethod_t) draw_gadget;
275
break;
276
case OBJ_TYPE_VIEWS:
277
objSize = sizeof(struct ObjView);
278
objDrawFn = (drawmethod_t) draw_nothing;
279
break;
280
case OBJ_TYPE_LABELS:
281
objSize = sizeof(struct ObjLabel);
282
objDrawFn = (drawmethod_t) draw_label;
283
break;
284
case OBJ_TYPE_ANIMATORS:
285
objSize = sizeof(struct ObjAnimator);
286
objDrawFn = (drawmethod_t) draw_nothing;
287
break;
288
case OBJ_TYPE_VALPTRS:
289
objSize = sizeof(struct ObjValPtr);
290
objDrawFn = (drawmethod_t) draw_nothing;
291
break;
292
case OBJ_TYPE_ZONES:
293
objSize = sizeof(struct ObjZone);
294
objDrawFn = (drawmethod_t) draw_nothing;
295
break;
296
default:
297
fatal_print("make_object() : Unkown object!");
298
}
299
300
typeName = get_obj_name_str(objType);
301
302
// Allocate memory for the object
303
start_memtracker(typeName);
304
newObj = gd_malloc(objSize, objPermanence);
305
if (newObj == NULL) {
306
fatal_printf("Cant allocate object '%s' memory!", typeName);
307
}
308
stop_memtracker(typeName);
309
310
// Zero out the object
311
newObjBytes = (u8 *) newObj;
312
for (i = 0; i < objSize; i++) {
313
newObjBytes[i] = 0;
314
}
315
316
// Add the new object to the beginning of gGdObjectList
317
gGdObjCount++;
318
objListOldHead = gGdObjectList;
319
gGdObjectList = newObj;
320
newObj->prev = NULL;
321
if (objListOldHead != NULL) {
322
newObj->next = objListOldHead;
323
objListOldHead->prev = newObj;
324
}
325
326
// Fill in required fields
327
newObj->index = gGdObjCount;
328
newObj->type = objType;
329
newObj->objDrawFn = objDrawFn;
330
newObj->drawFlags = 0;
331
332
imout();
333
return newObj;
334
}
335
336
/* @ 22AEA0 for 0xD0; orig name: func_8017C6D0 */
337
struct ObjZone *make_zone(struct ObjGroup *a0, struct GdBoundingBox *bbox, struct ObjGroup *a2) {
338
struct ObjZone *newZone = (struct ObjZone *) make_object(OBJ_TYPE_ZONES);
339
340
newZone->boundingBox.minX = bbox->minX;
341
newZone->boundingBox.minY = bbox->minY;
342
newZone->boundingBox.minZ = bbox->minZ;
343
newZone->boundingBox.maxX = bbox->maxX;
344
newZone->boundingBox.maxY = bbox->maxY;
345
newZone->boundingBox.maxZ = bbox->maxZ;
346
// pointers? prev, next?
347
newZone->unk2C = a2;
348
newZone->unk30 = a0;
349
350
//! @bug Created `ObjZone` is not returned
351
#ifdef AVOID_UB
352
return newZone;
353
#endif
354
}
355
356
/* @ 22AF70 for 0x60 */
357
struct ObjUnk200000 *func_8017C7A0(struct ObjVertex *a0, struct ObjFace *a1) {
358
struct ObjUnk200000 *unk = (struct ObjUnk200000 *) make_object(OBJ_TYPE_UNK200000);
359
360
unk->unk30 = a0;
361
unk->unk34 = a1;
362
363
return unk;
364
}
365
366
/**
367
* Creates a ListNode for the object. Adds the new node after `prevNode` if `prevNode` is not NULL.
368
*/
369
struct ListNode *make_link_to_obj(struct ListNode *prevNode, struct GdObj *obj) {
370
struct ListNode *newNode;
371
372
// Allocate link node
373
start_memtracker("links");
374
newNode = gd_malloc_perm(sizeof(struct ListNode));
375
if (newNode == NULL) {
376
fatal_print("Cant allocate link memory!");
377
}
378
stop_memtracker("links");
379
380
// Append to `prevNode` if not NULL
381
if (prevNode != NULL) {
382
prevNode->next = newNode;
383
}
384
385
newNode->prev = prevNode;
386
newNode->next = NULL;
387
newNode->obj = obj;
388
389
return newNode;
390
}
391
392
/*
393
* Creates a VtxLink for the vertex. Adds the new node after `prevNode` if `prevNode` is not NULL.
394
*/
395
struct VtxLink *make_vtx_link(struct VtxLink *prevNode, Vtx *data) {
396
struct VtxLink *newNode;
397
398
newNode = gd_malloc_perm(sizeof(struct VtxLink));
399
if (newNode == NULL) {
400
fatal_print("Cant allocate link memory!");
401
}
402
403
// Append to `prevNode` if not NULL
404
if (prevNode != NULL) {
405
prevNode->next = newNode;
406
}
407
408
newNode->prev = prevNode;
409
newNode->next = NULL;
410
newNode->data = data;
411
412
// WTF? Not sure what this is supposed to check
413
if (((uintptr_t)(newNode)) == 0x3F800000) {
414
fatal_printf("bad3\n");
415
}
416
417
return newNode;
418
}
419
420
/* @ 22B154 for 0x88; orig name: func8017C984 */
421
struct ObjValPtr *make_valptr(struct GdObj *obj, s32 flag, enum ValPtrType type, size_t offset) {
422
struct ObjValPtr *sp1C = (struct ObjValPtr *) make_object(OBJ_TYPE_VALPTRS);
423
424
sp1C->obj = obj;
425
sp1C->flag = flag;
426
sp1C->offset = offset;
427
sp1C->datatype = type;
428
429
return sp1C;
430
}
431
432
/* @ 22B1DC for 0x430 */
433
void reset_plane(struct ObjPlane *plane) {
434
struct ObjFace *sp4C;
435
f32 sp48;
436
f32 sp44;
437
UNUSED u32 sp40;
438
UNUSED u32 sp3C;
439
UNUSED u32 sp38;
440
s32 i;
441
s32 sp30;
442
register f32 sp28;
443
444
imin("reset_plane");
445
446
sp4C = plane->unk40;
447
calc_face_normal(sp4C);
448
plane->unk1C = gd_dot_vec3f(&sp4C->vertices[0]->pos, &sp4C->normal);
449
sp48 = 0.0f;
450
451
sp28 = sp4C->normal.x < 0.0f ? -sp4C->normal.x : sp4C->normal.x;
452
sp44 = sp28;
453
if (sp44 > sp48) {
454
sp30 = 0;
455
sp48 = sp44;
456
}
457
458
sp28 = sp4C->normal.y < 0.0f ? -sp4C->normal.y : sp4C->normal.y;
459
sp44 = sp28;
460
if (sp44 > sp48) {
461
sp30 = 1;
462
sp48 = sp44;
463
}
464
465
sp28 = sp4C->normal.z < 0.0f ? -sp4C->normal.z : sp4C->normal.z;
466
sp44 = sp28;
467
if (sp44 > sp48) {
468
sp30 = 2;
469
}
470
471
switch (sp30) {
472
case 0:
473
plane->unk20 = 1;
474
plane->unk24 = 2;
475
break;
476
case 1:
477
plane->unk20 = 0;
478
plane->unk24 = 2;
479
break;
480
case 2:
481
plane->unk20 = 0;
482
plane->unk24 = 1;
483
break;
484
}
485
486
reset_bounding_box();
487
488
for (i = 0; i < sp4C->vtxCount; i++) {
489
add_obj_pos_to_bounding_box(&sp4C->vertices[i]->header);
490
}
491
492
plane->boundingBox.minX = gSomeBoundingBox.minX;
493
plane->boundingBox.minY = gSomeBoundingBox.minY;
494
plane->boundingBox.minZ = gSomeBoundingBox.minZ;
495
plane->boundingBox.maxX = gSomeBoundingBox.maxX;
496
plane->boundingBox.maxY = gSomeBoundingBox.maxY;
497
plane->boundingBox.maxZ = gSomeBoundingBox.maxZ;
498
499
if (plane->boundingBox.maxX - plane->boundingBox.minX < 100.0f) {
500
plane->boundingBox.maxX += 50.0f;
501
plane->boundingBox.minX -= 50.0f;
502
}
503
504
plane->boundingBox.maxY += 200.0f;
505
plane->boundingBox.minY -= 200.0f;
506
507
if (plane->boundingBox.maxZ - plane->boundingBox.minZ < 100.0f) {
508
plane->boundingBox.maxZ += 50.0f;
509
plane->boundingBox.minZ -= 50.0f;
510
}
511
imout();
512
}
513
514
/* @ 22B60C for 0x94; orig name: func_8017CE3C */
515
struct ObjPlane *make_plane(s32 inZone, struct ObjFace *a1) {
516
UNUSED u32 pad1C;
517
struct ObjPlane *newPlane = (struct ObjPlane *) make_object(OBJ_TYPE_PLANES);
518
519
gGdPlaneCount++;
520
newPlane->id = gGdPlaneCount;
521
newPlane->unk18 = inZone;
522
newPlane->unk40 = a1;
523
reset_plane(newPlane);
524
525
return newPlane;
526
}
527
528
/* @ 22B6A0 for 0x21C; orig name: func_8017CED0 */
529
struct ObjCamera *make_camera(s32 flags, struct GdObj *a1) {
530
struct ObjCamera *newCam;
531
struct ObjCamera *oldCameraHead;
532
533
newCam = (struct ObjCamera *) make_object(OBJ_TYPE_CAMERAS);
534
535
gGdCameraCount++;
536
newCam->id = gGdCameraCount;
537
538
oldCameraHead = gGdCameraList;
539
gGdCameraList = newCam;
540
541
if (oldCameraHead != NULL) {
542
newCam->next = oldCameraHead;
543
oldCameraHead->prev = newCam;
544
}
545
546
newCam->flags = flags | 0x10;
547
newCam->unk30 = a1;
548
gd_set_identity_mat4(&newCam->unk64);
549
gd_set_identity_mat4(&newCam->unkA8);
550
551
newCam->unk180.x = 1.0f;
552
newCam->unk180.y = 0.1f;
553
newCam->unk180.z = 1.0f;
554
555
newCam->unk134.x = 4.0f;
556
newCam->unk134.y = 4.0f;
557
newCam->unk134.z = 4.0f;
558
559
newCam->unk178 = 0.0f;
560
newCam->unk17C = 0.25f;
561
562
newCam->zoomLevel = 0;
563
newCam->maxZoomLevel = -1;
564
565
newCam->unkA4 = 0.0f;
566
567
newCam->lookAt.x = newCam->lookAt.y = newCam->lookAt.z = 0.0f;
568
newCam->worldPos.x = newCam->worldPos.y = newCam->worldPos.z = 0.0f;
569
570
return newCam;
571
}
572
573
/* @ 22B8BC for 0xA8; orig. name: func_8017D0EC */
574
struct ObjMaterial *make_material(UNUSED s32 a0, char *name, s32 id) {
575
struct ObjMaterial *newMtl;
576
577
newMtl = (struct ObjMaterial *) make_object(OBJ_TYPE_MATERIALS);
578
579
if (name != NULL) {
580
gd_strcpy(newMtl->name, name);
581
} else {
582
gd_strcpy(newMtl->name, "NoName");
583
}
584
585
newMtl->id = id;
586
newMtl->gddlNumber = 0;
587
newMtl->type = 16;
588
589
return newMtl;
590
}
591
592
/* @ 22B964 for 0x114; orig name: func_8017D194 */
593
struct ObjLight *make_light(s32 flags, char *name, s32 id) {
594
struct ObjLight *newLight;
595
596
newLight = (struct ObjLight *) make_object(OBJ_TYPE_LIGHTS);
597
598
if (name != NULL) {
599
gd_strcpy(newLight->name, name);
600
} else {
601
gd_strcpy(newLight->name, "NoName");
602
}
603
604
newLight->id = id;
605
newLight->unk30 = 1.0f;
606
newLight->unk4C = 0;
607
newLight->flags = flags | LIGHT_NEW_UNCOUNTED;
608
newLight->unk98 = 0;
609
newLight->unk40 = 0;
610
611
newLight->unk68.x = newLight->unk68.y = newLight->unk68.z = 0;
612
613
return newLight;
614
}
615
616
/* @ 22BA78 for 0x294; orig name: func_8017D2A8*/
617
struct ObjView *make_view(const char *name, s32 flags, s32 projectionType, s32 ulx, s32 uly, s32 lrx, s32 lry,
618
struct ObjGroup *parts) {
619
struct ObjView *newView = (struct ObjView *) make_object(OBJ_TYPE_VIEWS);
620
621
if (gGdViewsGroup == NULL) {
622
gGdViewsGroup = make_group(0);
623
}
624
625
addto_group(gGdViewsGroup, &newView->header);
626
627
newView->flags = flags | VIEW_UPDATE | VIEW_LIGHT;
628
newView->id = sGdViewInfo.count++;
629
630
if ((newView->components = parts) != NULL) {
631
reset_nets_and_gadgets(parts);
632
}
633
634
newView->unk78 = 0;
635
newView->projectionType = projectionType;
636
637
newView->clipping.x = 30.0f;
638
newView->clipping.y = 5000.0f;
639
newView->clipping.z = 45.0f;
640
641
newView->upperLeft.x = (f32) ulx;
642
newView->upperLeft.y = (f32) uly;
643
644
newView->lowerRight.x = (f32) lrx;
645
newView->lowerRight.y = (f32) lry;
646
647
newView->unk48 = 1.0f;
648
newView->unk4C = 1.0f;
649
650
newView->colour.r = newView->id * 0.1; //? 0.1f, unless the extra precision was wanted for the tenth
651
newView->colour.g = 0.06f;
652
newView->colour.b = 1.0f;
653
654
newView->proc = NULL;
655
newView->unk9C = 0;
656
657
if (name != NULL) {
658
newView->unk1C = setup_view_buffers(name, newView, ulx, uly, lrx, lry);
659
}
660
661
newView->namePtr = name;
662
newView->lights = NULL;
663
664
return newView;
665
}
666
667
/* @ 22BD0C for 0x78; orig name: func_8017D53C */
668
struct ObjAnimator *make_animator(void) {
669
struct ObjAnimator *newAnim = (struct ObjAnimator *) make_object(OBJ_TYPE_ANIMATORS);
670
newAnim->unk24 = 1.0f;
671
newAnim->frame = 1.0f;
672
673
newAnim->controlFunc = NULL;
674
newAnim->state = 0;
675
676
return newAnim;
677
}
678
679
/* @ 22BD84 for 0x78; orig name: func_8017D5B4 */
680
struct ObjWeight *make_weight(UNUSED s32 a0, s32 vtxId, struct ObjVertex *vtx /* always NULL */, f32 weight) {
681
struct ObjWeight *newWeight = (struct ObjWeight *) make_object(OBJ_TYPE_WEIGHTS);
682
683
newWeight->vtxId = vtxId;
684
newWeight->weightVal = weight;
685
newWeight->vtx = vtx; // is always NULL here. This vtx field actually gets set in reset_weight_vtx.
686
687
return newWeight;
688
}
689
690
/**
691
* Makes a group, adding all objects from `fromObj` to `toObj` with type `type`
692
* as members.
693
*/
694
struct ObjGroup *make_group_of_type(enum ObjTypeFlag type, struct GdObj *fromObj, struct GdObj *toObj) {
695
struct ObjGroup *newGroup;
696
struct GdObj *curObj;
697
698
newGroup = make_group(0);
699
curObj = fromObj;
700
701
while (curObj != NULL) {
702
if (curObj->type & type) {
703
addto_group(newGroup, curObj);
704
}
705
706
if (curObj == toObj) {
707
break;
708
}
709
710
curObj = curObj->prev;
711
}
712
713
return newGroup;
714
}
715
716
/**
717
* Converts the object's ID to a string and places it in the buffer pointed to by `str`.
718
*/
719
void format_object_id(char *str, struct GdObj *obj) {
720
enum ObjTypeFlag type = obj->type;
721
722
switch (type) {
723
case OBJ_TYPE_BONES:
724
sprintf(str, "b%d ", ((struct ObjBone *) obj)->id);
725
break;
726
case OBJ_TYPE_JOINTS:
727
sprintf(str, "j%d ", ((struct ObjJoint *) obj)->id);
728
break;
729
case OBJ_TYPE_GROUPS:
730
sprintf(str, "g%d ", ((struct ObjGroup *) obj)->id);
731
break;
732
case OBJ_TYPE_PARTICLES:
733
sprintf(str, "p%d ", ((struct ObjParticle *) obj)->id);
734
break;
735
case OBJ_TYPE_NETS:
736
sprintf(str, "net(no id) ");
737
break;
738
case OBJ_TYPE_CAMERAS:
739
sprintf(str, "c%d ", ((struct ObjCamera *) obj)->id);
740
break;
741
case OBJ_TYPE_VERTICES:
742
sprintf(str, "v(no id) ");
743
break;
744
case OBJ_TYPE_PLANES:
745
sprintf(str, "pl%d ", ((struct ObjPlane *) obj)->id);
746
break;
747
default:
748
sprintf(str, "?%x ", type);
749
break;
750
}
751
}
752
753
/* @ 22C094 for 0x210 */
754
struct ObjGroup *make_group(s32 count, ...) {
755
va_list args;
756
s32 i;
757
UNUSED u32 sp5C;
758
struct GdObj *curObj;
759
UNUSED u32 sp54;
760
UNUSED u32 sp50;
761
UNUSED u32 sp4C;
762
struct ObjGroup *newGroup;
763
struct ObjGroup *oldGroupListHead;
764
struct GdObj *vargObj;
765
char idStrBuf[0x20];
766
struct ListNode *curLink;
767
768
newGroup = (struct ObjGroup *) make_object(OBJ_TYPE_GROUPS);
769
newGroup->id = ++gGdGroupCount;
770
newGroup->memberCount = 0;
771
newGroup->firstMember = newGroup->lastMember = NULL;
772
773
printf("Made group no.%d\n", newGroup->id);
774
775
oldGroupListHead = gGdGroupList;
776
gGdGroupList = newGroup;
777
if (oldGroupListHead != NULL) {
778
newGroup->next = oldGroupListHead;
779
oldGroupListHead->prev = newGroup;
780
}
781
782
if (count == 0) {
783
return newGroup;
784
}
785
786
va_start(args, count);
787
curLink = NULL;
788
789
for (i = 0; i < count; i++) {
790
// get the next pointer in the struct.
791
vargObj = va_arg(args, struct GdObj *);
792
793
if (vargObj == NULL) { // one of our pointers was NULL. raise an error.
794
fatal_printf("make_group() NULL group ptr");
795
}
796
797
curObj = vargObj;
798
newGroup->memberTypes |= curObj->type;
799
addto_group(newGroup, vargObj);
800
}
801
va_end(args);
802
803
curLink = newGroup->firstMember;
804
printf("Made group no.%d from: ", newGroup->id);
805
while (curLink != NULL) {
806
curObj = curLink->obj;
807
format_object_id(idStrBuf, curObj);
808
printf("%s", idStrBuf);
809
printf("\n");
810
curLink = curLink->next;
811
}
812
813
return newGroup;
814
}
815
816
/**
817
* Adds the object as a member of the group, placing it at the end of the group's list.
818
*/
819
void addto_group(struct ObjGroup *group, struct GdObj *obj) {
820
char strbuf[0x20];
821
UNUSED u8 pad[0x8];
822
823
imin("addto_group");
824
825
// Add object to the end of group's member list
826
if (group->firstMember == NULL) {
827
group->firstMember = make_link_to_obj(NULL, obj);
828
group->lastMember = group->firstMember;
829
} else {
830
group->lastMember = make_link_to_obj(group->lastMember, obj);
831
}
832
833
group->memberTypes |= obj->type;
834
group->memberCount++;
835
836
printf("Added ");
837
format_object_id(strbuf, obj);
838
printf("%s", strbuf);
839
printf(" to ");
840
format_object_id(strbuf, &group->header);
841
printf("%s", strbuf);
842
printf("\n");
843
844
imout();
845
}
846
847
/**
848
* Adds the object as a member of the group, placing it at the beginning of the group's list.
849
*/
850
void addto_groupfirst(struct ObjGroup *group, struct GdObj *obj) {
851
imin("addto_groupfirst");
852
853
// Add object to the beginning of group's member list
854
if (group->firstMember == NULL) {
855
group->firstMember = make_link_to_obj(NULL, obj);
856
group->lastMember = group->firstMember;
857
} else {
858
struct ListNode *newNode = make_link_to_obj(NULL, obj);
859
group->firstMember->prev = newNode;
860
newNode->next = group->firstMember;
861
group->firstMember = newNode;
862
}
863
864
group->memberTypes |= obj->type;
865
group->memberCount++;
866
867
imout();
868
}
869
870
/**
871
* Returns TRUE if `obj` is a member of `group`, or FALSE otherwise
872
*/
873
s32 group_contains_obj(struct ObjGroup *group, struct GdObj *obj) {
874
struct ListNode *node = group->firstMember;
875
876
while (node != NULL) {
877
if (node->obj->index == obj->index)
878
return TRUE;
879
node = node->next;
880
}
881
882
return FALSE;
883
}
884
885
/**
886
* Unused (not called) - this shows details about all objects in the main object linked list
887
*/
888
void show_details(enum ObjTypeFlag type) {
889
enum ObjTypeFlag curObjType;
890
struct ListNode *curGroupLink;
891
struct ObjGroup *curSubGroup;
892
struct GdObj *curObj;
893
char idStrBuf[0x24];
894
s32 curGroupTypes;
895
896
gd_printf("\nDetails about: ");
897
switch (type) {
898
case OBJ_TYPE_GROUPS:
899
gd_printf("Groups\n");
900
break;
901
case OBJ_TYPE_BONES:
902
gd_printf("Bones\n");
903
break;
904
case OBJ_TYPE_JOINTS:
905
gd_printf("Joints\n");
906
break;
907
case OBJ_TYPE_PARTICLES:
908
gd_printf("Particles\n");
909
break;
910
default:
911
gd_printf("Everything?\n");
912
break;
913
}
914
915
curObj = gGdObjectList;
916
while (curObj != NULL) {
917
curObjType = curObj->type;
918
if (curObjType == type) {
919
format_object_id(idStrBuf, curObj);
920
switch (curObjType) {
921
case OBJ_TYPE_GROUPS:
922
gd_printf("Group %s: ", idStrBuf);
923
curGroupTypes = ((struct ObjGroup *) curObj)->memberTypes;
924
925
if (curGroupTypes & OBJ_TYPE_GROUPS) {
926
gd_printf("groups ");
927
}
928
if (curGroupTypes & OBJ_TYPE_BONES) {
929
gd_printf("bones ");
930
}
931
if (curGroupTypes & OBJ_TYPE_JOINTS) {
932
gd_printf("joints ");
933
}
934
if (curGroupTypes & OBJ_TYPE_PARTICLES) {
935
gd_printf("particles ");
936
}
937
if (curGroupTypes & OBJ_TYPE_CAMERAS) {
938
gd_printf("cameras ");
939
}
940
if (curGroupTypes & OBJ_TYPE_NETS) {
941
gd_printf("nets ");
942
}
943
if (curGroupTypes & OBJ_TYPE_GADGETS) {
944
gd_printf("gadgets ");
945
}
946
if (curGroupTypes & OBJ_TYPE_LABELS) {
947
gd_printf("labels ");
948
}
949
if (curGroupTypes & OBJ_TYPE_FACES) {
950
gd_printf("face ");
951
}
952
if (curGroupTypes & OBJ_TYPE_VERTICES) {
953
gd_printf("vertex ");
954
}
955
956
curGroupLink = ((struct ObjGroup *) curObj)->firstMember;
957
while (curGroupLink != NULL) {
958
format_object_id(idStrBuf, curGroupLink->obj);
959
gd_printf("%s", idStrBuf);
960
curGroupLink = curGroupLink->next;
961
}
962
gd_printf("\n");
963
break;
964
case OBJ_TYPE_BONES:
965
gd_printf("Bone %s: ", idStrBuf);
966
curSubGroup = ((struct ObjBone *) curObj)->unk10C;
967
curGroupLink = curSubGroup->firstMember;
968
while (curGroupLink != NULL) {
969
format_object_id(idStrBuf, curGroupLink->obj);
970
gd_printf("%s", idStrBuf);
971
curGroupLink = curGroupLink->next;
972
}
973
gd_printf("\n");
974
break;
975
case OBJ_TYPE_JOINTS:
976
gd_printf("Joint %s: ", idStrBuf);
977
curSubGroup = ((struct ObjJoint *) curObj)->unk1C4;
978
curGroupLink = curSubGroup->firstMember;
979
while (curGroupLink != NULL) {
980
format_object_id(idStrBuf, curGroupLink->obj);
981
gd_printf("%s", idStrBuf);
982
curGroupLink = curGroupLink->next;
983
}
984
gd_printf("\n");
985
break;
986
default:;
987
}
988
}
989
curObj = curObj->next;
990
}
991
}
992
993
/* @ 22C9B8 for 0x24 */
994
s32 stub_objects_2(void) {
995
s32 sp4 = 0;
996
return sp4;
997
}
998
999
/**
1000
* Unused - called by __main__
1001
*/
1002
s32 make_scene(void) {
1003
s32 sp4 = 0;
1004
return sp4;
1005
}
1006
1007
/* @ 22CA00 for 0x88 */
1008
static void reset_joint_or_net(struct GdObj *obj) {
1009
struct GdObj *localObjPtr = obj;
1010
1011
switch (obj->type) {
1012
case OBJ_TYPE_JOINTS:
1013
reset_joint((struct ObjJoint *) localObjPtr);
1014
break;
1015
case OBJ_TYPE_NETS:
1016
reset_net((struct ObjNet *) localObjPtr);
1017
break;
1018
default:;
1019
}
1020
}
1021
1022
/**
1023
* called when the user clicks the "Reset Positions" item from the
1024
* "Dynamics" menu.
1025
*/
1026
void menu_cb_reset_positions(void) {
1027
apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) reset_joint_or_net, sCurrentMoveGrp);
1028
}
1029
1030
/**
1031
* Unused (not called) - does nothing useful
1032
*/
1033
struct GdObj *func_8017E2F0(struct GdObj *obj, enum ObjTypeFlag type) {
1034
UNUSED u32 sp2C;
1035
enum ObjTypeFlag curObjType;
1036
struct ListNode *node;
1037
1038
curObjType = obj->type;
1039
1040
switch (curObjType) {
1041
case OBJ_TYPE_GROUPS:
1042
node = ((struct ObjGroup *) obj)->firstMember;
1043
while (node != NULL) {
1044
func_8017E2F0(node->obj, type);
1045
node = node->next;
1046
}
1047
break;
1048
case OBJ_TYPE_BONES:
1049
break;
1050
default:;
1051
}
1052
1053
if (curObjType == type) {
1054
return obj;
1055
}
1056
1057
//! @bug Nothing is returned if a GdObj of `type` is not found
1058
#ifdef AVOID_UB
1059
return NULL;
1060
#endif
1061
}
1062
1063
/**
1064
* Recursively calls `func` on all members of `group` whose type is in the
1065
* `types` bitmask.
1066
* Returns the number of objects this function was called on.
1067
*/
1068
s32 apply_to_obj_types_in_group(s32 types, applyproc_t func, struct ObjGroup *group) {
1069
struct ListNode *curLink;
1070
struct ListNode *nextLink;
1071
struct GdObj *linkedObj;
1072
enum ObjTypeFlag linkedObjType;
1073
applyproc_t objFn;
1074
UNUSED u8 pad2C[0x20];
1075
s32 fnAppliedCount;
1076
1077
fnAppliedCount = 0;
1078
1079
//! @bug When `group` pointer is NULL, garbage is returned, not the
1080
//! count of `fn` calls
1081
if (group == NULL) {
1082
#ifdef AVOID_UB
1083
return fnAppliedCount;
1084
#else
1085
return;
1086
#endif
1087
}
1088
1089
if (group->linkType & 1) { // compressed data, not an Obj
1090
return fnAppliedCount;
1091
}
1092
1093
if (!((group->memberTypes & OBJ_TYPE_GROUPS) | (group->memberTypes & types))) {
1094
return fnAppliedCount;
1095
}
1096
1097
objFn = func;
1098
curLink = group->firstMember;
1099
1100
while (curLink != NULL) {
1101
linkedObj = curLink->obj;
1102
linkedObjType = linkedObj->type;
1103
nextLink = curLink->next;
1104
1105
if (linkedObjType == OBJ_TYPE_GROUPS) {
1106
fnAppliedCount += apply_to_obj_types_in_group(types, func, (struct ObjGroup *) linkedObj);
1107
}
1108
1109
if (linkedObjType & types) {
1110
(*objFn)(linkedObj);
1111
fnAppliedCount++;
1112
}
1113
1114
curLink = nextLink;
1115
}
1116
return fnAppliedCount;
1117
}
1118
1119
/* @ 22CD54 for 0x2B4 */
1120
void func_8017E584(struct ObjNet *a0, struct GdVec3f *a1, struct GdVec3f *a2) {
1121
struct GdVec3f sp94;
1122
struct GdVec3f sp88;
1123
struct GdVec3f sp7C;
1124
struct GdVec3f sp70;
1125
UNUSED u8 pad30[0x40]; // unused MyMatrix4x4? f32[4][4]
1126
f32 sp2C;
1127
UNUSED u32 sp28;
1128
struct GdVec3f sp1C;
1129
1130
sp70.x = a2->x;
1131
sp70.y = a2->y;
1132
sp70.z = a2->z;
1133
1134
gd_normalize_vec3f(&sp70);
1135
1136
sp7C.x = a1->x;
1137
sp7C.y = a1->y;
1138
sp7C.z = a1->z;
1139
1140
sp1C.x = a0->centerOfGravity.x;
1141
sp1C.y = a0->centerOfGravity.y;
1142
sp1C.z = a0->centerOfGravity.z;
1143
1144
gd_rotate_and_translate_vec3f(&sp1C, &a0->mat128);
1145
1146
sp7C.x -= sp1C.x;
1147
sp7C.y -= sp1C.y;
1148
sp7C.z -= sp1C.z;
1149
1150
if (gd_normalize_vec3f(&sp7C) == FALSE) {
1151
sp7C.x = -sp70.x;
1152
sp7C.y = -sp70.y;
1153
sp7C.z = -sp70.z;
1154
}
1155
1156
gd_cross_vec3f(&sp70, a1, &sp94);
1157
sp2C = (f32) gd_sqrt_d((sp94.x * sp94.x) + (sp94.z * sp94.z));
1158
1159
if (sp2C > 1000.0) { //? 1000.0f
1160
sp2C = 1000.0f;
1161
}
1162
1163
sp2C /= 1000.0; //? 1000.0f
1164
sp2C = 1.0 - sp2C; //? 1.0f - sp2C
1165
1166
sp88.x = a2->x * sp2C;
1167
sp88.y = a2->y * sp2C;
1168
sp88.z = a2->z * sp2C;
1169
1170
a0->collDisp.x += sp88.x;
1171
a0->collDisp.y += sp88.y;
1172
a0->collDisp.z += sp88.z;
1173
}
1174
1175
/* @ 22D008 for 0x1B4 */
1176
void func_8017E838(struct ObjNet *a0, struct GdVec3f *a1, struct GdVec3f *a2) {
1177
UNUSED u32 sp84;
1178
UNUSED u32 sp80;
1179
UNUSED u32 sp7C;
1180
struct GdVec3f sp70;
1181
struct GdVec3f sp64;
1182
UNUSED u8 pad24[0x40];
1183
struct GdVec3f sp18;
1184
1185
sp64.x = a1->x;
1186
sp64.y = a1->y;
1187
sp64.z = a1->z;
1188
1189
sp18.x = a0->centerOfGravity.x;
1190
sp18.y = a0->centerOfGravity.y;
1191
sp18.z = a0->centerOfGravity.z;
1192
1193
gd_rotate_and_translate_vec3f(&sp18, &a0->mat128);
1194
1195
sp64.x -= sp18.x;
1196
sp64.y -= sp18.y;
1197
sp64.z -= sp18.z;
1198
1199
sp64.x *= 0.01; //? 0.01f;
1200
sp64.y *= 0.01; //? 0.01f;
1201
sp64.z *= 0.01; //? 0.01f;
1202
1203
gd_cross_vec3f(a2, &sp64, &sp70);
1204
gd_clamp_vec3f(&sp70, 5.0f);
1205
1206
a0->collTorque.x += sp70.x;
1207
a0->collTorque.y += sp70.y;
1208
a0->collTorque.z += sp70.z;
1209
}
1210
1211
/* @ 22D1BC for 0xA8 */
1212
void func_8017E9EC(struct ObjNet *net) {
1213
struct GdVec3f sp5C;
1214
Mat4f sp1C;
1215
f32 sp18;
1216
1217
sp5C.x = net->torque.x;
1218
sp5C.y = net->torque.y;
1219
sp5C.z = net->torque.z;
1220
1221
gd_normalize_vec3f(&sp5C);
1222
sp18 = gd_vec3f_magnitude(&net->torque);
1223
gd_create_rot_mat_angular(&sp1C, &sp5C, -sp18);
1224
gd_mult_mat4f(&D_801B9DC8, &sp1C, &D_801B9DC8);
1225
}
1226
1227
/**
1228
* Unused (not called)
1229
*/
1230
s32 func_8017EA94(struct GdVec3f *vec, Mat4f matrix) {
1231
if (vec->x >= matrix[2][2] && vec->x <= matrix[3][1] && vec->z >= matrix[3][0]
1232
&& vec->z <= matrix[3][3]) {
1233
return 1;
1234
}
1235
1236
return 0;
1237
}
1238
1239
/**
1240
* Unused (not called)
1241
*/
1242
s32 func_8017EB24(struct GdObj *obj1, struct GdObj *obj2) {
1243
struct GdVec3f pos1;
1244
struct GdVec3f pos2;
1245
struct GdBoundingBox *bbox1;
1246
struct GdBoundingBox *bbox2;
1247
struct GdBoundingBox sp18;
1248
1249
set_cur_dynobj(obj1);
1250
d_get_world_pos(&pos1);
1251
bbox1 = d_get_bounding_box();
1252
1253
set_cur_dynobj(obj2);
1254
d_get_world_pos(&pos2);
1255
bbox2 = d_get_bounding_box();
1256
1257
// bbox2 is an offset for bbox1?
1258
sp18.minX = bbox1->minX + bbox2->minX;
1259
sp18.minY = bbox1->minY + bbox2->minY;
1260
sp18.minZ = bbox1->minZ + bbox2->minZ;
1261
sp18.maxX = bbox1->maxX + bbox2->maxX;
1262
sp18.maxY = bbox1->maxY + bbox2->maxY;
1263
sp18.maxZ = bbox1->maxZ + bbox2->maxZ;
1264
1265
D_801B9E08.x = pos2.x - pos1.x;
1266
D_801B9E08.y = pos2.y - pos1.y;
1267
D_801B9E08.z = pos2.z - pos1.z;
1268
1269
if (D_801B9E08.x >= sp18.minX) {
1270
if (D_801B9E08.x <= sp18.maxX) {
1271
if (D_801B9E08.z >= sp18.minZ) {
1272
if (D_801B9E08.z <= sp18.maxZ) {
1273
return TRUE;
1274
}
1275
}
1276
}
1277
}
1278
1279
return FALSE;
1280
}
1281
1282
/**
1283
* Unused (not called)
1284
*/
1285
s32 is_obj_xz_in_bounding_box(struct GdObj *obj, struct GdBoundingBox *bbox) {
1286
struct GdVec3f pos;
1287
1288
set_cur_dynobj(obj);
1289
d_get_world_pos(&pos);
1290
1291
if (pos.x >= bbox->minX) {
1292
if (pos.x <= bbox->maxX) {
1293
if (pos.z >= bbox->minZ) {
1294
if (pos.z <= bbox->maxZ) {
1295
return TRUE;
1296
}
1297
}
1298
}
1299
}
1300
1301
return FALSE;
1302
}
1303
1304
/**
1305
* Unused (not called)
1306
*/
1307
s32 is_point_xz_in_bounding_box(struct GdVec3f *point, struct GdBoundingBox *bbox) {
1308
if (point->x >= bbox->minX) {
1309
if (point->x <= bbox->maxX) {
1310
if (point->z >= bbox->minZ) {
1311
if (point->z <= bbox->maxZ) {
1312
return TRUE;
1313
}
1314
}
1315
}
1316
}
1317
1318
return FALSE;
1319
}
1320
1321
/**
1322
* Unused (called by func_801A71CC) - returns TRUE if any of the four corners of
1323
* box1's X-Z plane lie within box2's X-Z plane
1324
*/
1325
s32 gd_plane_point_within(struct GdBoundingBox *box1, struct GdBoundingBox *box2) {
1326
// test if min x and min z of box1 are within box2
1327
if (box1->minX >= box2->minX) {
1328
if (box1->minX <= box2->maxX) {
1329
if (box1->minZ >= box2->minZ) {
1330
if (box1->minZ <= box2->maxZ) {
1331
return TRUE;
1332
}
1333
}
1334
}
1335
}
1336
1337
// test if max x and min z of box1 are within box2
1338
if (box1->maxX >= box2->minX) {
1339
if (box1->maxX <= box2->maxX) {
1340
if (box1->minZ >= box2->minZ) {
1341
if (box1->minZ <= box2->maxZ) {
1342
return TRUE;
1343
}
1344
}
1345
}
1346
}
1347
1348
// test if max x and max z of box1 are within box2
1349
if (box1->maxX >= box2->minX) {
1350
if (box1->maxX <= box2->maxX) {
1351
if (box1->maxZ >= box2->minZ) {
1352
if (box1->maxZ <= box2->maxZ) {
1353
return TRUE;
1354
}
1355
}
1356
}
1357
}
1358
1359
// test if min x and max z of box1 are within box2
1360
if (box1->minX >= box2->minX) {
1361
if (box1->minX <= box2->maxX) {
1362
if (box1->maxZ >= box2->minZ) {
1363
if (box1->maxZ <= box2->maxZ) {
1364
return TRUE;
1365
}
1366
}
1367
}
1368
}
1369
1370
return FALSE;
1371
}
1372
1373
/* @ 22D824 for 0x1BC */
1374
s32 transform_child_objects_recursive(struct GdObj *obj, struct GdObj *parentObj) {
1375
struct ListNode *curLink;
1376
struct ObjGroup *curGroup;
1377
UNUSED u32 sp54;
1378
Mat4f *parentUnkMtx;
1379
Mat4f *iMtx;
1380
Mat4f *unkMtx;
1381
Mat4f *rotMtx;
1382
Mat4f *rotMtx2;
1383
UNUSED u8 pad20[0x18];
1384
struct GdVec3f scale;
1385
1386
if (parentObj != NULL) {
1387
set_cur_dynobj(parentObj);
1388
parentUnkMtx = d_get_matrix_ptr();
1389
rotMtx = (Mat4f *) d_get_rot_mtx_ptr();
1390
1391
set_cur_dynobj(obj);
1392
iMtx = d_get_i_mtx_ptr();
1393
rotMtx2 = (Mat4f *) d_get_rot_mtx_ptr();
1394
1395
d_get_scale(&scale);
1396
1397
unkMtx = d_get_matrix_ptr();
1398
gd_mult_mat4f(iMtx, parentUnkMtx, unkMtx);
1399
1400
gd_mult_mat4f(iMtx, rotMtx, rotMtx2);
1401
gd_scale_mat4f_by_vec3f(rotMtx2, &scale);
1402
} else {
1403
set_cur_dynobj(obj);
1404
unkMtx = d_get_matrix_ptr();
1405
iMtx = d_get_i_mtx_ptr();
1406
rotMtx = (Mat4f *) d_get_rot_mtx_ptr();
1407
1408
d_get_scale(&scale);
1409
gd_set_identity_mat4(unkMtx);
1410
gd_copy_mat4f(iMtx, rotMtx);
1411
gd_scale_mat4f_by_vec3f(rotMtx, &scale);
1412
}
1413
1414
// Recursively call this function on attached children
1415
set_cur_dynobj(obj);
1416
curGroup = d_get_att_objgroup();
1417
if (curGroup != NULL) {
1418
curLink = curGroup->firstMember;
1419
while (curLink != NULL) {
1420
transform_child_objects_recursive(curLink->obj, obj);
1421
curLink = curLink->next;
1422
}
1423
}
1424
return 0;
1425
}
1426
1427
/* @ 22D9E0 for 0x1BC */
1428
s32 func_8017F210(struct GdObj *a0, struct GdObj *a1) {
1429
struct ListNode *sp6C;
1430
struct ObjGroup *sp68;
1431
UNUSED u32 sp64;
1432
UNUSED Mat4f *sp60;
1433
Mat4f *sp5C;
1434
UNUSED Mat4f *sp58;
1435
Mat4f *sp54;
1436
Mat4f *sp50;
1437
UNUSED u8 pad38[0x18];
1438
struct GdVec3f sp2C;
1439
s32 count = 0;
1440
1441
count++;
1442
1443
if (a1 != NULL) {
1444
set_cur_dynobj(a1);
1445
sp60 = d_get_matrix_ptr();
1446
sp54 = (Mat4f *) d_get_rot_mtx_ptr();
1447
1448
set_cur_dynobj(a0);
1449
sp5C = d_get_i_mtx_ptr();
1450
sp50 = (Mat4f *) d_get_rot_mtx_ptr();
1451
1452
d_get_scale(&sp2C);
1453
gd_mult_mat4f(sp5C, sp54, sp50);
1454
gd_scale_mat4f_by_vec3f(sp50, &sp2C);
1455
} else {
1456
set_cur_dynobj(a0);
1457
sp58 = d_get_matrix_ptr();
1458
sp5C = d_get_i_mtx_ptr();
1459
sp54 = (Mat4f *) d_get_rot_mtx_ptr();
1460
1461
d_get_scale(&sp2C);
1462
gd_copy_mat4f(sp5C, sp54);
1463
gd_scale_mat4f_by_vec3f(sp54, &sp2C);
1464
}
1465
1466
set_cur_dynobj(a0);
1467
sp68 = d_get_att_objgroup();
1468
1469
if (sp68 != NULL) {
1470
sp6C = sp68->firstMember;
1471
while (sp6C != NULL) {
1472
count += func_8017F210(sp6C->obj, a0);
1473
sp6C = sp6C->next;
1474
}
1475
}
1476
return count;
1477
}
1478
1479
/* @ 22DB9C for 0x38; a0 might be ObjUnk200000* */
1480
void func_8017F3CC(struct Unk8017F3CC *a0) {
1481
gd_rotate_and_translate_vec3f(&a0->unk20, D_801B9E48);
1482
}
1483
1484
/* @ 22DBD4 for 0x20 */
1485
void stub_objects_3(UNUSED f32 a0, UNUSED struct GdObj *a1, UNUSED struct GdObj *a2) {
1486
UNUSED u8 pad[0x30];
1487
}
1488
1489
/**
1490
* Interpolates between animation transformations `t1` and `t2`, with `dt` as
1491
* the interpolation factor (between 0 and 1). Sets the current dynobj's matrix
1492
* as the result of the transformation.
1493
*/
1494
void interpolate_animation_transform(struct GdAnimTransform *t1, struct GdAnimTransform *t2, f32 dt) {
1495
Mat4f mtx;
1496
1497
gd_set_identity_mat4(&mtx);
1498
1499
if (dt != 0.0f) {
1500
struct GdAnimTransform transform;
1501
1502
// interpolate rotation between t1 and t2
1503
transform.rotate.x = t1->rotate.x + (t2->rotate.x - t1->rotate.x) * dt;
1504
transform.rotate.y = t1->rotate.y + (t2->rotate.y - t1->rotate.y) * dt;
1505
transform.rotate.z = t1->rotate.z + (t2->rotate.z - t1->rotate.z) * dt;
1506
1507
// interpolate position between t1 and t2
1508
transform.pos.x = t1->pos.x + (t2->pos.x - t1->pos.x) * dt;
1509
transform.pos.y = t1->pos.y + (t2->pos.y - t1->pos.y) * dt;
1510
transform.pos.z = t1->pos.z + (t2->pos.z - t1->pos.z) * dt;
1511
1512
// not going to interpolate scale?
1513
1514
gd_scale_mat4f_by_vec3f(&mtx, &t1->scale);
1515
gd_rot_mat_about_vec(&mtx, &transform.rotate);
1516
gd_add_vec3f_to_mat4f_offset(&mtx, &transform.pos);
1517
} else {
1518
d_set_scale(t1->scale.x, t1->scale.y, t1->scale.z);
1519
gd_rot_mat_about_vec(&mtx, &t1->rotate);
1520
gd_add_vec3f_to_mat4f_offset(&mtx, &t1->pos);
1521
}
1522
d_set_i_matrix(&mtx);
1523
}
1524
1525
/* @ 22DD94 for 0x1060; orig name: func_8017F5C4 */
1526
void move_animator(struct ObjAnimator *animObj) {
1527
struct AnimDataInfo *animData; // array?
1528
Mat4f *mtxArr;
1529
Mat4f localMtx;
1530
struct GdAnimTransform *triPtr;
1531
struct GdAnimTransform currTransform; // transformation for the current keyframe
1532
struct GdAnimTransform nextTransform; // transformation for the next keyframe
1533
s16(*animData9s16)[9]; // GdTriangleH[]?
1534
s16(*animData3s16)[3]; // MyVec3h[]?
1535
s16(*animData6s16)[6]; // GdPlaneH[]?
1536
s16(*animDataCam)[6]; // camera GdPlaneH[]?
1537
struct GdObj *stubObj1 = NULL; // used only for call to stubbed function
1538
struct GdObj *stubObj2 = NULL; // used only for call to stubbed function
1539
UNUSED s32 sp50;
1540
UNUSED s32 sp4C;
1541
UNUSED s32 sp48;
1542
UNUSED struct GdVec3f unusedVec;
1543
s32 currKeyFrame;
1544
s32 nextKeyFrame;
1545
f32 dt;
1546
f32 scale = 0.1f;
1547
struct AnimMtxVec *sp28;
1548
register struct ListNode *link;
1549
struct GdObj *linkedObj;
1550
1551
if (animObj->controlFunc != NULL) {
1552
animObj->controlFunc(animObj);
1553
}
1554
1555
if (animObj->animatedPartsGrp == NULL) {
1556
return; // nothing to animate
1557
}
1558
1559
animData = (struct AnimDataInfo *) animObj->animdataGrp->firstMember->obj;
1560
1561
if (animObj->attachedToObj != NULL) {
1562
animObj->frame = ((struct ObjAnimator *) animObj->attachedToObj)->frame
1563
/ ((struct ObjAnimator *) animObj->attachedToObj)->unk24;
1564
animData += ((struct ObjAnimator *) animObj->attachedToObj)->animSeqNum;
1565
}
1566
1567
if (animData->type == 0) {
1568
return;
1569
}
1570
1571
unusedVec.x = 4.0f;
1572
unusedVec.y = 1.0f;
1573
unusedVec.z = 1.0f;
1574
1575
if (animObj->frame > (f32) animData->count) {
1576
animObj->frame = 1.0f;
1577
} else if (animObj->frame < 0.0f) {
1578
animObj->frame = (f32) animData->count;
1579
}
1580
1581
currKeyFrame = (s32) animObj->frame;
1582
dt = animObj->frame - (f32) currKeyFrame;
1583
nextKeyFrame = currKeyFrame + 1;
1584
1585
if (nextKeyFrame > animData->count) {
1586
nextKeyFrame = 1;
1587
}
1588
1589
// convert frame numbers to zero-indexed
1590
currKeyFrame--;
1591
nextKeyFrame--;
1592
1593
link = animObj->animatedPartsGrp->firstMember;
1594
while (link != NULL) {
1595
linkedObj = link->obj;
1596
set_cur_dynobj(linkedObj);
1597
switch (animData->type) {
1598
case GD_ANIM_MTX4x4: // data = Mat4f* (f32[4][4])
1599
mtxArr = (Mat4f *) animData->data;
1600
/* This needs be be un-dereferenced pointer addition to make the registers match */
1601
d_set_i_matrix(mtxArr + (s32) animObj->frame);
1602
break;
1603
case GD_ANIM_ROT3S: // data = s16(*)[3] - rotation only
1604
animData3s16 = (s16(*)[3]) animData->data;
1605
1606
// keep current object scale
1607
d_get_scale(&currTransform.scale);
1608
nextTransform.scale.x = currTransform.scale.x;
1609
nextTransform.scale.y = currTransform.scale.y;
1610
nextTransform.scale.z = currTransform.scale.z;
1611
1612
// keep current object position
1613
d_get_init_pos(&currTransform.pos);
1614
nextTransform.pos.x = currTransform.pos.x;
1615
nextTransform.pos.y = currTransform.pos.y;
1616
nextTransform.pos.z = currTransform.pos.z;
1617
1618
// use animation rotation
1619
currTransform.rotate.x = (f32) animData3s16[currKeyFrame][0] * scale;
1620
currTransform.rotate.y = (f32) animData3s16[currKeyFrame][1] * scale;
1621
currTransform.rotate.z = (f32) animData3s16[currKeyFrame][2] * scale;
1622
1623
nextTransform.rotate.x = (f32) animData3s16[nextKeyFrame][0] * scale;
1624
nextTransform.rotate.y = (f32) animData3s16[nextKeyFrame][1] * scale;
1625
nextTransform.rotate.z = (f32) animData3s16[nextKeyFrame][2] * scale;
1626
1627
interpolate_animation_transform(&currTransform, &nextTransform, dt);
1628
break;
1629
case GD_ANIM_POS3S: // data = s16(*)[3] - position only
1630
animData3s16 = (s16(*)[3]) animData->data;
1631
1632
// keep current object scale
1633
d_get_scale(&currTransform.scale);
1634
nextTransform.scale.x = currTransform.scale.x;
1635
nextTransform.scale.y = currTransform.scale.y;
1636
nextTransform.scale.z = currTransform.scale.z;
1637
1638
// keep current object rotation
1639
d_get_init_rot(&currTransform.rotate);
1640
nextTransform.rotate.x = currTransform.rotate.x;
1641
nextTransform.rotate.y = currTransform.rotate.y;
1642
nextTransform.rotate.z = currTransform.rotate.z;
1643
1644
// use animation position
1645
currTransform.pos.x = (f32) animData3s16[currKeyFrame][0];
1646
currTransform.pos.y = (f32) animData3s16[currKeyFrame][1];
1647
currTransform.pos.z = (f32) animData3s16[currKeyFrame][2];
1648
1649
nextTransform.pos.x = (f32) animData3s16[nextKeyFrame][0];
1650
nextTransform.pos.y = (f32) animData3s16[nextKeyFrame][1];
1651
nextTransform.pos.z = (f32) animData3s16[nextKeyFrame][2];
1652
1653
interpolate_animation_transform(&currTransform, &nextTransform, dt);
1654
break;
1655
case GD_ANIM_ROT3S_POS3S: // data = s16(*)[6] - rotation and position
1656
animData6s16 = (s16(*)[6]) animData->data;
1657
1658
// keep current object scale
1659
d_get_scale(&currTransform.scale);
1660
nextTransform.scale.x = currTransform.scale.x;
1661
nextTransform.scale.y = currTransform.scale.y;
1662
nextTransform.scale.z = currTransform.scale.z;
1663
1664
// use animation rotation
1665
currTransform.rotate.x = (f32) animData6s16[currKeyFrame][0] * scale;
1666
currTransform.rotate.y = (f32) animData6s16[currKeyFrame][1] * scale;
1667
currTransform.rotate.z = (f32) animData6s16[currKeyFrame][2] * scale;
1668
1669
nextTransform.rotate.x = (f32) animData6s16[nextKeyFrame][0] * scale;
1670
nextTransform.rotate.y = (f32) animData6s16[nextKeyFrame][1] * scale;
1671
nextTransform.rotate.z = (f32) animData6s16[nextKeyFrame][2] * scale;
1672
1673
// use animation position
1674
currTransform.pos.x = (f32) animData6s16[currKeyFrame][3];
1675
currTransform.pos.y = (f32) animData6s16[currKeyFrame][4];
1676
currTransform.pos.z = (f32) animData6s16[currKeyFrame][5];
1677
1678
nextTransform.pos.x = (f32) animData6s16[nextKeyFrame][3];
1679
nextTransform.pos.y = (f32) animData6s16[nextKeyFrame][4];
1680
nextTransform.pos.z = (f32) animData6s16[nextKeyFrame][5];
1681
1682
interpolate_animation_transform(&currTransform, &nextTransform, dt);
1683
break;
1684
case GD_ANIM_SCALE3S_POS3S_ROT3S: // data = s16(*)[9] - scale, position, and rotation
1685
animData9s16 = (s16(*)[9]) animData->data;
1686
1687
currTransform.scale.x = (f32) animData9s16[currKeyFrame][0] * scale;
1688
currTransform.scale.y = (f32) animData9s16[currKeyFrame][1] * scale;
1689
currTransform.scale.z = (f32) animData9s16[currKeyFrame][2] * scale;
1690
1691
currTransform.rotate.x = (f32) animData9s16[currKeyFrame][3] * scale;
1692
currTransform.rotate.y = (f32) animData9s16[currKeyFrame][4] * scale;
1693
currTransform.rotate.z = (f32) animData9s16[currKeyFrame][5] * scale;
1694
1695
currTransform.pos.x = (f32) animData9s16[currKeyFrame][6];
1696
currTransform.pos.y = (f32) animData9s16[currKeyFrame][7];
1697
currTransform.pos.z = (f32) animData9s16[currKeyFrame][8];
1698
1699
nextTransform.scale.x = (f32) animData9s16[nextKeyFrame][0] * scale;
1700
nextTransform.scale.y = (f32) animData9s16[nextKeyFrame][1] * scale;
1701
nextTransform.scale.z = (f32) animData9s16[nextKeyFrame][2] * scale;
1702
1703
nextTransform.rotate.x = (f32) animData9s16[nextKeyFrame][3] * scale;
1704
nextTransform.rotate.y = (f32) animData9s16[nextKeyFrame][4] * scale;
1705
nextTransform.rotate.z = (f32) animData9s16[nextKeyFrame][5] * scale;
1706
1707
nextTransform.pos.x = (f32) animData9s16[nextKeyFrame][6];
1708
nextTransform.pos.y = (f32) animData9s16[nextKeyFrame][7];
1709
nextTransform.pos.z = (f32) animData9s16[nextKeyFrame][8];
1710
1711
interpolate_animation_transform(&currTransform, &nextTransform, dt);
1712
break;
1713
case GD_ANIM_CAMERA_EYE3S_LOOKAT3S: // s16(*)[6]?
1714
if (linkedObj->type == OBJ_TYPE_CAMERAS) {
1715
animDataCam = animData->data;
1716
1717
// eye position
1718
currTransform.pos.x = (f32) animDataCam[currKeyFrame][0];
1719
currTransform.pos.y = (f32) animDataCam[currKeyFrame][1];
1720
currTransform.pos.z = (f32) animDataCam[currKeyFrame][2];
1721
1722
// lookat position
1723
nextTransform.pos.x = (f32) animDataCam[currKeyFrame][3];
1724
nextTransform.pos.y = (f32) animDataCam[currKeyFrame][4];
1725
nextTransform.pos.z = (f32) animDataCam[currKeyFrame][5];
1726
1727
((struct ObjCamera *) linkedObj)->worldPos.x = currTransform.pos.x;
1728
((struct ObjCamera *) linkedObj)->worldPos.y = currTransform.pos.y;
1729
((struct ObjCamera *) linkedObj)->worldPos.z = currTransform.pos.z;
1730
1731
((struct ObjCamera *) linkedObj)->lookAt.x = nextTransform.pos.x;
1732
((struct ObjCamera *) linkedObj)->lookAt.y = nextTransform.pos.y;
1733
((struct ObjCamera *) linkedObj)->lookAt.z = nextTransform.pos.z;
1734
}
1735
break;
1736
case GD_ANIM_SCALE3F_ROT3F_POS3F: // scale, rotation, and position (as floats)
1737
triPtr = (struct GdAnimTransform *) animData->data;
1738
interpolate_animation_transform(&triPtr[currKeyFrame], &triPtr[nextKeyFrame], dt);
1739
break;
1740
case GD_ANIM_MTX4x4F_SCALE3F: // AnimMtxVec[]
1741
sp28 = &((struct AnimMtxVec *) animData->data)[currKeyFrame];
1742
d_set_i_matrix(&sp28->matrix);
1743
d_set_scale(sp28->vec.x, sp28->vec.y, sp28->vec.z);
1744
break;
1745
case GD_ANIM_SCALE3F_ROT3F_POS3F_2: // similar to GD_ANIM_SCALE3F_ROT3F_POS3F, but no interpolation? what matrix does d_set_i_matrix set?
1746
triPtr = (struct GdAnimTransform *) animData->data;
1747
gd_set_identity_mat4(&localMtx);
1748
gd_scale_mat4f_by_vec3f(&localMtx, &triPtr->scale);
1749
gd_rot_mat_about_vec(&localMtx, &triPtr->rotate);
1750
gd_add_vec3f_to_mat4f_offset(&localMtx, &triPtr->pos);
1751
d_set_i_matrix(&localMtx);
1752
break;
1753
case GD_ANIM_STUB:
1754
if (stubObj1 == NULL) {
1755
stubObj1 = linkedObj;
1756
} else {
1757
if (stubObj2 == NULL) {
1758
stubObj2 = linkedObj;
1759
stub_objects_3(animObj->frame, stubObj1, stubObj2);
1760
} else {
1761
fatal_printf("Too many objects to morph");
1762
}
1763
}
1764
break;
1765
default:
1766
fatal_printf("move_animator(): Unkown animation data type");
1767
}
1768
link = link->next;
1769
}
1770
}
1771
1772
/* @ 22EDF4 for 0x300; orig name: func_80180624 */
1773
void drag_picked_object(struct GdObj *inputObj) {
1774
UNUSED u32 spE4;
1775
UNUSED u32 spE0;
1776
UNUSED u32 spDC;
1777
struct GdVec3f displacement;
1778
struct GdVec3f spC4;
1779
struct GdControl *ctrl;
1780
Mat4f sp80;
1781
Mat4f sp40;
1782
UNUSED u32 pad34[3];
1783
struct GdObj *obj;
1784
UNUSED u32 pad2C;
1785
f32 dispMag;
1786
1787
ctrl = &gGdCtrl;
1788
1789
if (gViewUpdateCamera == NULL) {
1790
return;
1791
}
1792
1793
dispMag = gd_vec3f_magnitude(&gViewUpdateCamera->unk40);
1794
dispMag /= 1000.0f;
1795
1796
displacement.x = ((f32)(ctrl->csrX - ctrl->dragStartX)) * dispMag;
1797
displacement.y = ((f32) - (ctrl->csrY - ctrl->dragStartY)) * dispMag;
1798
displacement.z = 0.0f;
1799
1800
gd_inverse_mat4f(&gViewUpdateCamera->unkE8, &sp40);
1801
gd_mat4f_mult_vec3f(&displacement, &sp40);
1802
1803
obj = inputObj;
1804
if ((inputObj->drawFlags & OBJ_PICKED) && gGdCtrl.dragging) {
1805
gd_play_sfx(GD_SFX_PINCH_FACE);
1806
// Note: this second sfx won't play, as it is "overwritten" by the first
1807
if (ABS(ctrl->stickDeltaX) + ABS(ctrl->stickDeltaY) >= 11) {
1808
gd_play_sfx(GD_SFX_PINCH_FACE_2);
1809
}
1810
1811
switch (inputObj->type) {
1812
case OBJ_TYPE_JOINTS:
1813
((struct ObjJoint *) obj)->mat128[3][0] += displacement.x;
1814
((struct ObjJoint *) obj)->mat128[3][1] += displacement.y;
1815
((struct ObjJoint *) obj)->mat128[3][2] += displacement.z;
1816
break;
1817
case OBJ_TYPE_GADGETS:
1818
break;
1819
case OBJ_TYPE_NETS:
1820
gd_inverse_mat4f(&((struct ObjNet *) obj)->mat128, &sp80);
1821
spC4.x = displacement.x;
1822
spC4.y = displacement.y;
1823
spC4.z = displacement.z;
1824
1825
gd_mat4f_mult_vec3f(&spC4, &sp80);
1826
((struct ObjNet *) obj)->matE8[3][0] += displacement.x;
1827
((struct ObjNet *) obj)->matE8[3][1] += displacement.y;
1828
((struct ObjNet *) obj)->matE8[3][2] += displacement.z;
1829
break;
1830
case OBJ_TYPE_PARTICLES:
1831
break;
1832
default:;
1833
}
1834
}
1835
}
1836
1837
/* @ 22F0F4 for 0x50; orig name: func_80180924*/
1838
void move_animators(struct ObjGroup *group) {
1839
restart_timer("move_animators");
1840
apply_to_obj_types_in_group(OBJ_TYPE_ANIMATORS, (applyproc_t) move_animator, group);
1841
split_timer("move_animators");
1842
}
1843
1844
/* @ 22F144 for 0x3C; orig name: func_80180974 */
1845
void find_and_drag_picked_object(struct ObjGroup *group) {
1846
apply_to_obj_types_in_group(OBJ_TYPE_ALL, (applyproc_t) drag_picked_object, group);
1847
}
1848
1849
/* @ 22F180 for 0x624; orig name: func_801809B0 */
1850
void move_camera(struct ObjCamera *cam) {
1851
struct GdObj *spEC;
1852
struct GdVec3f spE0;
1853
struct GdVec3f spD4;
1854
struct GdVec3f spC8;
1855
UNUSED u8 padBC[0xC8 - 0xBC];
1856
struct GdVec3f spB0;
1857
Mat4f sp70;
1858
UNUSED u8 pad30[0x70 - 0x30];
1859
Mat4f *sp2C;
1860
struct GdControl *ctrl;
1861
1862
ctrl = &gGdCtrl;
1863
if (!(cam->flags & 0x10)) {
1864
return;
1865
}
1866
1867
spE0.x = spE0.y = spE0.z = 0.0f;
1868
spB0.x = spB0.y = spB0.z = 0.0f;
1869
1870
if ((spEC = cam->unk30) != NULL) {
1871
set_cur_dynobj(spEC);
1872
d_get_world_pos(&spE0);
1873
d_get_matrix(&sp70);
1874
1875
spC8.x = sp70[2][0] - cam->unk58;
1876
spC8.z = sp70[2][2] - cam->unk60;
1877
1878
cam->unk58 += spC8.x * cam->unk180.y;
1879
cam->unk60 += spC8.z * cam->unk180.y;
1880
1881
cam->unkA8[2][0] = cam->unk58;
1882
cam->unkA8[2][1] = 0.0f;
1883
cam->unkA8[2][2] = cam->unk60;
1884
1885
cam->unkA8[0][0] = cam->unkA8[2][2];
1886
cam->unkA8[0][1] = 0.0f;
1887
cam->unkA8[0][2] = -cam->unkA8[2][0];
1888
1889
cam->unkA8[1][0] = 0.0f;
1890
cam->unkA8[1][1] = 1.0f;
1891
cam->unkA8[1][2] = 0.0f;
1892
1893
// setting the unkA8 matrix above is pointless, if we're just going to overwrite it with the identity matrix.
1894
gd_set_identity_mat4(&cam->unkA8);
1895
} else {
1896
gd_set_identity_mat4(&cam->unkA8);
1897
}
1898
1899
sp2C = &cam->unk64;
1900
if ((cam->flags & CAMERA_FLAG_CONTROLLABLE) != 0) {
1901
if (ctrl->btnB != FALSE && ctrl->prevFrame->btnB == FALSE) { // new B press
1902
cam->zoomLevel++;
1903
if (cam->zoomLevel > cam->maxZoomLevel) {
1904
cam->zoomLevel = 0;
1905
}
1906
1907
switch (cam->zoomLevel) {
1908
case 0:
1909
gd_play_sfx(GD_SFX_CAM_ZOOM_IN);
1910
break;
1911
case 1:
1912
case 2:
1913
gd_play_sfx(GD_SFX_CAM_ZOOM_OUT);
1914
break;
1915
}
1916
}
1917
1918
if (ctrl->cleft) {
1919
cam->unk128.y += cam->unk134.y;
1920
}
1921
1922
if (ctrl->cright) {
1923
cam->unk128.y -= cam->unk134.y;
1924
}
1925
1926
if (ctrl->cup) {
1927
cam->unk128.x += cam->unk134.x;
1928
}
1929
1930
if (ctrl->cdown) {
1931
cam->unk128.x -= cam->unk134.x;
1932
}
1933
1934
cam->unk128.x = gd_clamp_f32(cam->unk128.x, 80.0f);
1935
1936
cam->unk4C.x = cam->zoomPositions[cam->zoomLevel].x;
1937
cam->unk4C.y = cam->zoomPositions[cam->zoomLevel].y;
1938
cam->unk4C.z = cam->zoomPositions[cam->zoomLevel].z;
1939
1940
gd_rot_2d_vec(cam->unk128.x, &cam->unk4C.y, &cam->unk4C.z);
1941
gd_rot_2d_vec(-cam->unk128.y, &cam->unk4C.x, &cam->unk4C.z);
1942
1943
cam->unk40.x += (cam->unk4C.x - cam->unk40.x) * cam->unk17C;
1944
cam->unk40.y += (cam->unk4C.y - cam->unk40.y) * cam->unk17C;
1945
cam->unk40.z += (cam->unk4C.z - cam->unk40.z) * cam->unk17C;
1946
} else {
1947
gd_set_identity_mat4(sp2C);
1948
}
1949
1950
spD4.x = cam->unk40.x;
1951
spD4.y = cam->unk40.y;
1952
spD4.z = cam->unk40.z;
1953
1954
spD4.x += spB0.x;
1955
spD4.y += spB0.y;
1956
spD4.z += spB0.z;
1957
1958
gd_mult_mat4f(sp2C, &cam->unkA8, &cam->unkA8);
1959
gd_mat4f_mult_vec3f(&spD4, &cam->unkA8);
1960
1961
cam->worldPos.x = spD4.x;
1962
cam->worldPos.y = spD4.y;
1963
cam->worldPos.z = spD4.z;
1964
1965
cam->worldPos.x += spE0.x;
1966
cam->worldPos.y += spE0.y;
1967
cam->worldPos.z += spE0.z;
1968
}
1969
1970
/* @ 22F7A4 for 0x38; orig name: func_80180FD4 */
1971
void move_cameras_in_grp(struct ObjGroup *group) {
1972
apply_to_obj_types_in_group(OBJ_TYPE_CAMERAS, (applyproc_t) move_camera, group);
1973
}
1974
1975
/* @ 22F7DC for 0x36C*/
1976
void func_8018100C(struct ObjLight *light) {
1977
Mat4f mtx;
1978
UNUSED u32 pad1C[3];
1979
1980
if (light->unk40 == 3) {
1981
if (light->unk30 > 0.0) { //? 0.0f
1982
light->unk30 -= 0.2; //? 0.2f
1983
}
1984
1985
if (light->unk30 < 0.0f) {
1986
light->unk30 = 0.0f;
1987
}
1988
1989
if ((light->unk3C & 0x1) != 0) {
1990
light->unk30 = 1.0f;
1991
}
1992
1993
light->unk3C &= ~1;
1994
}
1995
// if (1)?
1996
return;
1997
// unreachable
1998
light->position.x += light->unk80.x;
1999
light->position.y += light->unk80.y;
2000
light->position.z += light->unk80.z;
2001
2002
// should be position.x for second comparison?
2003
if (light->position.x > 500.0f || light->position.y < -500.0f) {
2004
light->unk80.x = -light->unk80.x;
2005
}
2006
2007
if (light->position.y > 500.0f || light->position.y < -500.0f) {
2008
light->unk80.y = -light->unk80.y;
2009
}
2010
2011
if (light->position.z > 500.0f || light->position.z < -500.0f) {
2012
light->unk80.z = -light->unk80.z;
2013
}
2014
2015
return;
2016
// more unreachable
2017
D_801A81C0 += 1.0; //? 1.0f
2018
D_801A81C4 += 0.6; //? 0.6f
2019
2020
gd_set_identity_mat4(&mtx);
2021
gd_absrot_mat4(&mtx, GD_Y_AXIS, light->unk68.y);
2022
gd_absrot_mat4(&mtx, GD_X_AXIS, light->unk68.x);
2023
gd_absrot_mat4(&mtx, GD_Z_AXIS, light->unk68.z);
2024
gd_mat4f_mult_vec3f(&light->unk8C, &mtx);
2025
2026
light->position.x = light->unk8C.x;
2027
light->position.y = light->unk8C.y;
2028
light->position.z = light->unk8C.z;
2029
return;
2030
// even more unreachable
2031
gd_mat4f_mult_vec3f(&light->unk80, &mtx);
2032
imout(); // this call would cause an issue if it was reachable
2033
}
2034
2035
/* @ 22FB48 for 0x38; orig name: func_80181378 */
2036
void move_lights_in_grp(struct ObjGroup *group) {
2037
apply_to_obj_types_in_group(OBJ_TYPE_LIGHTS, (applyproc_t) func_8018100C, group);
2038
}
2039
2040
/* @ 22FB80 for 0xAC; orig name: func_801813B0 */
2041
void move_group_members(void) {
2042
s32 i;
2043
2044
if (gGdMoveScene != 0) {
2045
reset_gadgets_in_grp(sCurrentMoveGrp);
2046
move_lights_in_grp(sCurrentMoveGrp);
2047
move_particles_in_grp(sCurrentMoveGrp);
2048
move_animators(sCurrentMoveGrp);
2049
2050
for (i = 0; i <= 0; i++) {
2051
move_nets(sCurrentMoveGrp);
2052
}
2053
2054
move_cameras_in_grp(sCurrentMoveGrp);
2055
}
2056
}
2057
2058
/* @ 22FC2C for 0x98; orig name: func_8018145C */
2059
void proc_view_movement(struct ObjView *view) {
2060
imin("movement");
2061
sCurrentMoveCamera = view->activeCam;
2062
sCurrentMoveView = view;
2063
if ((sCurrentMoveGrp = view->components) != NULL) {
2064
move_group_members();
2065
}
2066
if ((sCurrentMoveGrp = view->lights) != NULL) {
2067
move_group_members();
2068
}
2069
imout();
2070
}
2071
2072
/* @ 22FCC4 for 0x44; orig name: func_801814F4 */
2073
void reset_nets_and_gadgets(struct ObjGroup *group) {
2074
func_80193848(group);
2075
apply_to_obj_types_in_group(OBJ_TYPE_GADGETS, (applyproc_t) reset_gadget, group);
2076
}
2077
2078
/* @ 22FD08 for 0x9C; orig name: func_80181538*/
2079
void null_obj_lists(void) {
2080
D_801B9E44 = 0;
2081
gGdObjCount = 0;
2082
gGdGroupCount = 0;
2083
gGdPlaneCount = 0;
2084
gGdCameraCount = 0;
2085
sGdViewInfo.count = 0;
2086
2087
gGdCameraList = NULL;
2088
D_801B9E50 = NULL;
2089
gGdBoneList = NULL;
2090
gGdJointList = NULL;
2091
gGdGroupList = NULL;
2092
D_801B9E80 = NULL;
2093
gGdObjectList = NULL;
2094
gGdViewsGroup = NULL;
2095
2096
reset_net_count();
2097
reset_joint_counts();
2098
}
2099
2100