objects.c (62581B)
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 filler[20]; 27 }; /* sizeof() = 0x18 */ 28 29 struct Unk8017F3CC { 30 /*0x00*/ u8 filler[32]; 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 filler[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 u8 filler[12]; 438 s32 i; 439 s32 sp30; 440 register f32 sp28; 441 442 imin("reset_plane"); 443 444 sp4C = plane->unk40; 445 calc_face_normal(sp4C); 446 plane->unk1C = gd_dot_vec3f(&sp4C->vertices[0]->pos, &sp4C->normal); 447 sp48 = 0.0f; 448 449 sp28 = sp4C->normal.x < 0.0f ? -sp4C->normal.x : sp4C->normal.x; 450 sp44 = sp28; 451 if (sp44 > sp48) { 452 sp30 = 0; 453 sp48 = sp44; 454 } 455 456 sp28 = sp4C->normal.y < 0.0f ? -sp4C->normal.y : sp4C->normal.y; 457 sp44 = sp28; 458 if (sp44 > sp48) { 459 sp30 = 1; 460 sp48 = sp44; 461 } 462 463 sp28 = sp4C->normal.z < 0.0f ? -sp4C->normal.z : sp4C->normal.z; 464 sp44 = sp28; 465 if (sp44 > sp48) { 466 sp30 = 2; 467 } 468 469 switch (sp30) { 470 case 0: 471 plane->unk20 = 1; 472 plane->unk24 = 2; 473 break; 474 case 1: 475 plane->unk20 = 0; 476 plane->unk24 = 2; 477 break; 478 case 2: 479 plane->unk20 = 0; 480 plane->unk24 = 1; 481 break; 482 } 483 484 reset_bounding_box(); 485 486 for (i = 0; i < sp4C->vtxCount; i++) { 487 add_obj_pos_to_bounding_box(&sp4C->vertices[i]->header); 488 } 489 490 plane->boundingBox.minX = gSomeBoundingBox.minX; 491 plane->boundingBox.minY = gSomeBoundingBox.minY; 492 plane->boundingBox.minZ = gSomeBoundingBox.minZ; 493 plane->boundingBox.maxX = gSomeBoundingBox.maxX; 494 plane->boundingBox.maxY = gSomeBoundingBox.maxY; 495 plane->boundingBox.maxZ = gSomeBoundingBox.maxZ; 496 497 if (plane->boundingBox.maxX - plane->boundingBox.minX < 100.0f) { 498 plane->boundingBox.maxX += 50.0f; 499 plane->boundingBox.minX -= 50.0f; 500 } 501 502 plane->boundingBox.maxY += 200.0f; 503 plane->boundingBox.minY -= 200.0f; 504 505 if (plane->boundingBox.maxZ - plane->boundingBox.minZ < 100.0f) { 506 plane->boundingBox.maxZ += 50.0f; 507 plane->boundingBox.minZ -= 50.0f; 508 } 509 imout(); 510 } 511 512 /* @ 22B60C for 0x94; orig name: func_8017CE3C */ 513 struct ObjPlane *make_plane(s32 inZone, struct ObjFace *a1) { 514 UNUSED u8 filler[4]; 515 struct ObjPlane *newPlane = (struct ObjPlane *) make_object(OBJ_TYPE_PLANES); 516 517 gGdPlaneCount++; 518 newPlane->id = gGdPlaneCount; 519 newPlane->unk18 = inZone; 520 newPlane->unk40 = a1; 521 reset_plane(newPlane); 522 523 return newPlane; 524 } 525 526 /* @ 22B6A0 for 0x21C; orig name: func_8017CED0 */ 527 struct ObjCamera *make_camera(s32 flags, struct GdObj *a1) { 528 struct ObjCamera *newCam; 529 struct ObjCamera *oldCameraHead; 530 531 newCam = (struct ObjCamera *) make_object(OBJ_TYPE_CAMERAS); 532 533 gGdCameraCount++; 534 newCam->id = gGdCameraCount; 535 536 oldCameraHead = gGdCameraList; 537 gGdCameraList = newCam; 538 539 if (oldCameraHead != NULL) { 540 newCam->next = oldCameraHead; 541 oldCameraHead->prev = newCam; 542 } 543 544 newCam->flags = flags | 0x10; 545 newCam->unk30 = a1; 546 gd_set_identity_mat4(&newCam->unk64); 547 gd_set_identity_mat4(&newCam->unkA8); 548 549 newCam->unk180.x = 1.0f; 550 newCam->unk180.y = 0.1f; 551 newCam->unk180.z = 1.0f; 552 553 newCam->unk134.x = 4.0f; 554 newCam->unk134.y = 4.0f; 555 newCam->unk134.z = 4.0f; 556 557 newCam->unk178 = 0.0f; 558 newCam->unk17C = 0.25f; 559 560 newCam->zoomLevel = 0; 561 newCam->maxZoomLevel = -1; 562 563 newCam->unkA4 = 0.0f; 564 565 newCam->lookAt.x = newCam->lookAt.y = newCam->lookAt.z = 0.0f; 566 newCam->worldPos.x = newCam->worldPos.y = newCam->worldPos.z = 0.0f; 567 568 return newCam; 569 } 570 571 /* @ 22B8BC for 0xA8; orig. name: func_8017D0EC */ 572 struct ObjMaterial *make_material(UNUSED s32 a0, char *name, s32 id) { 573 struct ObjMaterial *newMtl; 574 575 newMtl = (struct ObjMaterial *) make_object(OBJ_TYPE_MATERIALS); 576 577 if (name != NULL) { 578 gd_strcpy(newMtl->name, name); 579 } else { 580 gd_strcpy(newMtl->name, "NoName"); 581 } 582 583 newMtl->id = id; 584 newMtl->gddlNumber = 0; 585 newMtl->type = 16; 586 587 return newMtl; 588 } 589 590 /* @ 22B964 for 0x114; orig name: func_8017D194 */ 591 struct ObjLight *make_light(s32 flags, char *name, s32 id) { 592 struct ObjLight *newLight; 593 594 newLight = (struct ObjLight *) make_object(OBJ_TYPE_LIGHTS); 595 596 if (name != NULL) { 597 gd_strcpy(newLight->name, name); 598 } else { 599 gd_strcpy(newLight->name, "NoName"); 600 } 601 602 newLight->id = id; 603 newLight->unk30 = 1.0f; 604 newLight->unk4C = 0; 605 newLight->flags = flags | LIGHT_NEW_UNCOUNTED; 606 newLight->unk98 = 0; 607 newLight->unk40 = 0; 608 609 newLight->unk68.x = newLight->unk68.y = newLight->unk68.z = 0; 610 611 return newLight; 612 } 613 614 /* @ 22BA78 for 0x294; orig name: func_8017D2A8*/ 615 struct ObjView *make_view(const char *name, s32 flags, s32 projectionType, s32 ulx, s32 uly, s32 lrx, s32 lry, 616 struct ObjGroup *parts) { 617 struct ObjView *newView = (struct ObjView *) make_object(OBJ_TYPE_VIEWS); 618 619 if (gGdViewsGroup == NULL) { 620 gGdViewsGroup = make_group(0); 621 } 622 623 addto_group(gGdViewsGroup, &newView->header); 624 625 newView->flags = flags | VIEW_UPDATE | VIEW_LIGHT; 626 newView->id = sGdViewInfo.count++; 627 628 if ((newView->components = parts) != NULL) { 629 reset_nets_and_gadgets(parts); 630 } 631 632 newView->unk78 = 0; 633 newView->projectionType = projectionType; 634 635 newView->clipping.x = 30.0f; 636 newView->clipping.y = 5000.0f; 637 newView->clipping.z = 45.0f; 638 639 newView->upperLeft.x = (f32) ulx; 640 newView->upperLeft.y = (f32) uly; 641 642 newView->lowerRight.x = (f32) lrx; 643 newView->lowerRight.y = (f32) lry; 644 645 newView->unk48 = 1.0f; 646 newView->unk4C = 1.0f; 647 648 newView->colour.r = newView->id * 0.1; //? 0.1f, unless the extra precision was wanted for the tenth 649 newView->colour.g = 0.06f; 650 newView->colour.b = 1.0f; 651 652 newView->proc = NULL; 653 newView->unk9C = 0; 654 655 if (name != NULL) { 656 newView->unk1C = setup_view_buffers(name, newView, ulx, uly, lrx, lry); 657 } 658 659 newView->namePtr = name; 660 newView->lights = NULL; 661 662 return newView; 663 } 664 665 /* @ 22BD0C for 0x78; orig name: func_8017D53C */ 666 struct ObjAnimator *make_animator(void) { 667 struct ObjAnimator *newAnim = (struct ObjAnimator *) make_object(OBJ_TYPE_ANIMATORS); 668 newAnim->unk24 = 1.0f; 669 newAnim->frame = 1.0f; 670 671 newAnim->controlFunc = NULL; 672 newAnim->state = 0; 673 674 return newAnim; 675 } 676 677 /* @ 22BD84 for 0x78; orig name: func_8017D5B4 */ 678 struct ObjWeight *make_weight(UNUSED s32 a0, s32 vtxId, struct ObjVertex *vtx /* always NULL */, f32 weight) { 679 struct ObjWeight *newWeight = (struct ObjWeight *) make_object(OBJ_TYPE_WEIGHTS); 680 681 newWeight->vtxId = vtxId; 682 newWeight->weightVal = weight; 683 newWeight->vtx = vtx; // is always NULL here. This vtx field actually gets set in reset_weight_vtx. 684 685 return newWeight; 686 } 687 688 /** 689 * Makes a group, adding all objects from `fromObj` to `toObj` with type `type` 690 * as members. 691 */ 692 struct ObjGroup *make_group_of_type(enum ObjTypeFlag type, struct GdObj *fromObj, struct GdObj *toObj) { 693 struct ObjGroup *newGroup; 694 struct GdObj *curObj; 695 696 newGroup = make_group(0); 697 curObj = fromObj; 698 699 while (curObj != NULL) { 700 if (curObj->type & type) { 701 addto_group(newGroup, curObj); 702 } 703 704 if (curObj == toObj) { 705 break; 706 } 707 708 curObj = curObj->prev; 709 } 710 711 return newGroup; 712 } 713 714 /** 715 * Converts the object's ID to a string and places it in the buffer pointed to by `str`. 716 */ 717 void format_object_id(char *str, struct GdObj *obj) { 718 enum ObjTypeFlag type = obj->type; 719 720 switch (type) { 721 case OBJ_TYPE_BONES: 722 sprintf(str, "b%d ", ((struct ObjBone *) obj)->id); 723 break; 724 case OBJ_TYPE_JOINTS: 725 sprintf(str, "j%d ", ((struct ObjJoint *) obj)->id); 726 break; 727 case OBJ_TYPE_GROUPS: 728 sprintf(str, "g%d ", ((struct ObjGroup *) obj)->id); 729 break; 730 case OBJ_TYPE_PARTICLES: 731 sprintf(str, "p%d ", ((struct ObjParticle *) obj)->id); 732 break; 733 case OBJ_TYPE_NETS: 734 sprintf(str, "net(no id) "); 735 break; 736 case OBJ_TYPE_CAMERAS: 737 sprintf(str, "c%d ", ((struct ObjCamera *) obj)->id); 738 break; 739 case OBJ_TYPE_VERTICES: 740 sprintf(str, "v(no id) "); 741 break; 742 case OBJ_TYPE_PLANES: 743 sprintf(str, "pl%d ", ((struct ObjPlane *) obj)->id); 744 break; 745 default: 746 sprintf(str, "?%x ", type); 747 break; 748 } 749 } 750 751 /* @ 22C094 for 0x210 */ 752 struct ObjGroup *make_group(s32 count, ...) { 753 va_list args; 754 s32 i; 755 UNUSED u8 filler1[4]; 756 struct GdObj *curObj; 757 UNUSED u8 filler2[12]; 758 struct ObjGroup *newGroup; 759 struct ObjGroup *oldGroupListHead; 760 struct GdObj *vargObj; 761 char idStrBuf[0x20]; 762 struct ListNode *curLink; 763 764 newGroup = (struct ObjGroup *) make_object(OBJ_TYPE_GROUPS); 765 newGroup->id = ++gGdGroupCount; 766 newGroup->memberCount = 0; 767 newGroup->firstMember = newGroup->lastMember = NULL; 768 769 printf("Made group no.%d\n", newGroup->id); 770 771 oldGroupListHead = gGdGroupList; 772 gGdGroupList = newGroup; 773 if (oldGroupListHead != NULL) { 774 newGroup->next = oldGroupListHead; 775 oldGroupListHead->prev = newGroup; 776 } 777 778 if (count == 0) { 779 return newGroup; 780 } 781 782 va_start(args, count); 783 curLink = NULL; 784 785 for (i = 0; i < count; i++) { 786 // get the next pointer in the struct. 787 vargObj = va_arg(args, struct GdObj *); 788 789 if (vargObj == NULL) { // one of our pointers was NULL. raise an error. 790 fatal_printf("make_group() NULL group ptr"); 791 } 792 793 curObj = vargObj; 794 newGroup->memberTypes |= curObj->type; 795 addto_group(newGroup, vargObj); 796 } 797 va_end(args); 798 799 curLink = newGroup->firstMember; 800 printf("Made group no.%d from: ", newGroup->id); 801 while (curLink != NULL) { 802 curObj = curLink->obj; 803 format_object_id(idStrBuf, curObj); 804 printf("%s", idStrBuf); 805 printf("\n"); 806 curLink = curLink->next; 807 } 808 809 return newGroup; 810 } 811 812 /** 813 * Adds the object as a member of the group, placing it at the end of the group's list. 814 */ 815 void addto_group(struct ObjGroup *group, struct GdObj *obj) { 816 char strbuf[0x20]; 817 UNUSED u8 filler[8]; 818 819 imin("addto_group"); 820 821 // Add object to the end of group's member list 822 if (group->firstMember == NULL) { 823 group->firstMember = make_link_to_obj(NULL, obj); 824 group->lastMember = group->firstMember; 825 } else { 826 group->lastMember = make_link_to_obj(group->lastMember, obj); 827 } 828 829 group->memberTypes |= obj->type; 830 group->memberCount++; 831 832 printf("Added "); 833 format_object_id(strbuf, obj); 834 printf("%s", strbuf); 835 printf(" to "); 836 format_object_id(strbuf, &group->header); 837 printf("%s", strbuf); 838 printf("\n"); 839 840 imout(); 841 } 842 843 /** 844 * Adds the object as a member of the group, placing it at the beginning of the group's list. 845 */ 846 void addto_groupfirst(struct ObjGroup *group, struct GdObj *obj) { 847 imin("addto_groupfirst"); 848 849 // Add object to the beginning of group's member list 850 if (group->firstMember == NULL) { 851 group->firstMember = make_link_to_obj(NULL, obj); 852 group->lastMember = group->firstMember; 853 } else { 854 struct ListNode *newNode = make_link_to_obj(NULL, obj); 855 group->firstMember->prev = newNode; 856 newNode->next = group->firstMember; 857 group->firstMember = newNode; 858 } 859 860 group->memberTypes |= obj->type; 861 group->memberCount++; 862 863 imout(); 864 } 865 866 /** 867 * Returns TRUE if `obj` is a member of `group`, or FALSE otherwise 868 */ 869 s32 group_contains_obj(struct ObjGroup *group, struct GdObj *obj) { 870 struct ListNode *node = group->firstMember; 871 872 while (node != NULL) { 873 if (node->obj->index == obj->index) { 874 return TRUE; 875 } 876 node = node->next; 877 } 878 879 return FALSE; 880 } 881 882 /** 883 * Unused (not called) - this shows details about all objects in the main object linked list 884 */ 885 void show_details(enum ObjTypeFlag type) { 886 enum ObjTypeFlag curObjType; 887 struct ListNode *curGroupLink; 888 struct ObjGroup *curSubGroup; 889 struct GdObj *curObj; 890 char idStrBuf[0x24]; 891 s32 curGroupTypes; 892 893 gd_printf("\nDetails about: "); 894 switch (type) { 895 case OBJ_TYPE_GROUPS: 896 gd_printf("Groups\n"); 897 break; 898 case OBJ_TYPE_BONES: 899 gd_printf("Bones\n"); 900 break; 901 case OBJ_TYPE_JOINTS: 902 gd_printf("Joints\n"); 903 break; 904 case OBJ_TYPE_PARTICLES: 905 gd_printf("Particles\n"); 906 break; 907 default: 908 gd_printf("Everything?\n"); 909 break; 910 } 911 912 curObj = gGdObjectList; 913 while (curObj != NULL) { 914 curObjType = curObj->type; 915 if (curObjType == type) { 916 format_object_id(idStrBuf, curObj); 917 switch (curObjType) { 918 case OBJ_TYPE_GROUPS: 919 gd_printf("Group %s: ", idStrBuf); 920 curGroupTypes = ((struct ObjGroup *) curObj)->memberTypes; 921 922 if (curGroupTypes & OBJ_TYPE_GROUPS) { 923 gd_printf("groups "); 924 } 925 if (curGroupTypes & OBJ_TYPE_BONES) { 926 gd_printf("bones "); 927 } 928 if (curGroupTypes & OBJ_TYPE_JOINTS) { 929 gd_printf("joints "); 930 } 931 if (curGroupTypes & OBJ_TYPE_PARTICLES) { 932 gd_printf("particles "); 933 } 934 if (curGroupTypes & OBJ_TYPE_CAMERAS) { 935 gd_printf("cameras "); 936 } 937 if (curGroupTypes & OBJ_TYPE_NETS) { 938 gd_printf("nets "); 939 } 940 if (curGroupTypes & OBJ_TYPE_GADGETS) { 941 gd_printf("gadgets "); 942 } 943 if (curGroupTypes & OBJ_TYPE_LABELS) { 944 gd_printf("labels "); 945 } 946 if (curGroupTypes & OBJ_TYPE_FACES) { 947 gd_printf("face "); 948 } 949 if (curGroupTypes & OBJ_TYPE_VERTICES) { 950 gd_printf("vertex "); 951 } 952 953 curGroupLink = ((struct ObjGroup *) curObj)->firstMember; 954 while (curGroupLink != NULL) { 955 format_object_id(idStrBuf, curGroupLink->obj); 956 gd_printf("%s", idStrBuf); 957 curGroupLink = curGroupLink->next; 958 } 959 gd_printf("\n"); 960 break; 961 case OBJ_TYPE_BONES: 962 gd_printf("Bone %s: ", idStrBuf); 963 curSubGroup = ((struct ObjBone *) curObj)->unk10C; 964 curGroupLink = curSubGroup->firstMember; 965 while (curGroupLink != NULL) { 966 format_object_id(idStrBuf, curGroupLink->obj); 967 gd_printf("%s", idStrBuf); 968 curGroupLink = curGroupLink->next; 969 } 970 gd_printf("\n"); 971 break; 972 case OBJ_TYPE_JOINTS: 973 gd_printf("Joint %s: ", idStrBuf); 974 curSubGroup = ((struct ObjJoint *) curObj)->unk1C4; 975 curGroupLink = curSubGroup->firstMember; 976 while (curGroupLink != NULL) { 977 format_object_id(idStrBuf, curGroupLink->obj); 978 gd_printf("%s", idStrBuf); 979 curGroupLink = curGroupLink->next; 980 } 981 gd_printf("\n"); 982 break; 983 default:; 984 } 985 } 986 curObj = curObj->next; 987 } 988 } 989 990 /* @ 22C9B8 for 0x24 */ 991 s32 stub_objects_2(void) { 992 s32 sp4 = 0; 993 return sp4; 994 } 995 996 /** 997 * Unused - called by __main__ 998 */ 999 s32 make_scene(void) { 1000 s32 sp4 = 0; 1001 return sp4; 1002 } 1003 1004 /* @ 22CA00 for 0x88 */ 1005 static void reset_joint_or_net(struct GdObj *obj) { 1006 struct GdObj *localObjPtr = obj; 1007 1008 switch (obj->type) { 1009 case OBJ_TYPE_JOINTS: 1010 reset_joint((struct ObjJoint *) localObjPtr); 1011 break; 1012 case OBJ_TYPE_NETS: 1013 reset_net((struct ObjNet *) localObjPtr); 1014 break; 1015 default:; 1016 } 1017 } 1018 1019 /** 1020 * called when the user clicks the "Reset Positions" item from the 1021 * "Dynamics" menu. 1022 */ 1023 void menu_cb_reset_positions(void) { 1024 apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) reset_joint_or_net, sCurrentMoveGrp); 1025 } 1026 1027 /** 1028 * Unused (not called) - does nothing useful 1029 */ 1030 struct GdObj *func_8017E2F0(struct GdObj *obj, enum ObjTypeFlag type) { 1031 UNUSED u8 filler[4]; 1032 enum ObjTypeFlag curObjType; 1033 struct ListNode *node; 1034 1035 curObjType = obj->type; 1036 1037 switch (curObjType) { 1038 case OBJ_TYPE_GROUPS: 1039 node = ((struct ObjGroup *) obj)->firstMember; 1040 while (node != NULL) { 1041 func_8017E2F0(node->obj, type); 1042 node = node->next; 1043 } 1044 break; 1045 case OBJ_TYPE_BONES: 1046 break; 1047 default:; 1048 } 1049 1050 if (curObjType == type) { 1051 return obj; 1052 } 1053 1054 //! @bug Nothing is returned if a GdObj of `type` is not found 1055 #ifdef AVOID_UB 1056 return NULL; 1057 #endif 1058 } 1059 1060 /** 1061 * Recursively calls `func` on all members of `group` whose type is in the 1062 * `types` bitmask. 1063 * Returns the number of objects this function was called on. 1064 */ 1065 s32 apply_to_obj_types_in_group(s32 types, applyproc_t func, struct ObjGroup *group) { 1066 struct ListNode *curLink; 1067 struct ListNode *nextLink; 1068 struct GdObj *linkedObj; 1069 enum ObjTypeFlag linkedObjType; 1070 applyproc_t objFn; 1071 UNUSED u8 filler[32]; 1072 s32 fnAppliedCount; 1073 1074 fnAppliedCount = 0; 1075 1076 //! @bug When `group` pointer is NULL, garbage is returned, not the 1077 //! count of `fn` calls 1078 if (group == NULL) { 1079 #ifdef AVOID_UB 1080 return fnAppliedCount; 1081 #else 1082 return; 1083 #endif 1084 } 1085 1086 if (group->linkType & 1) { // compressed data, not an Obj 1087 return fnAppliedCount; 1088 } 1089 1090 if (!((group->memberTypes & OBJ_TYPE_GROUPS) | (group->memberTypes & types))) { 1091 return fnAppliedCount; 1092 } 1093 1094 objFn = func; 1095 curLink = group->firstMember; 1096 1097 while (curLink != NULL) { 1098 linkedObj = curLink->obj; 1099 linkedObjType = linkedObj->type; 1100 nextLink = curLink->next; 1101 1102 if (linkedObjType == OBJ_TYPE_GROUPS) { 1103 fnAppliedCount += apply_to_obj_types_in_group(types, func, (struct ObjGroup *) linkedObj); 1104 } 1105 1106 if (linkedObjType & types) { 1107 (*objFn)(linkedObj); 1108 fnAppliedCount++; 1109 } 1110 1111 curLink = nextLink; 1112 } 1113 return fnAppliedCount; 1114 } 1115 1116 /* @ 22CD54 for 0x2B4 */ 1117 void func_8017E584(struct ObjNet *a0, struct GdVec3f *a1, struct GdVec3f *a2) { 1118 struct GdVec3f sp94; 1119 struct GdVec3f sp88; 1120 struct GdVec3f sp7C; 1121 struct GdVec3f sp70; 1122 UNUSED u8 filler1[64]; // unused MyMatrix4x4? f32[4][4] 1123 f32 sp2C; 1124 UNUSED u8 filler2[4]; 1125 struct GdVec3f sp1C; 1126 1127 sp70.x = a2->x; 1128 sp70.y = a2->y; 1129 sp70.z = a2->z; 1130 1131 gd_normalize_vec3f(&sp70); 1132 1133 sp7C.x = a1->x; 1134 sp7C.y = a1->y; 1135 sp7C.z = a1->z; 1136 1137 sp1C.x = a0->centerOfGravity.x; 1138 sp1C.y = a0->centerOfGravity.y; 1139 sp1C.z = a0->centerOfGravity.z; 1140 1141 gd_rotate_and_translate_vec3f(&sp1C, &a0->mat128); 1142 1143 sp7C.x -= sp1C.x; 1144 sp7C.y -= sp1C.y; 1145 sp7C.z -= sp1C.z; 1146 1147 if (gd_normalize_vec3f(&sp7C) == FALSE) { 1148 sp7C.x = -sp70.x; 1149 sp7C.y = -sp70.y; 1150 sp7C.z = -sp70.z; 1151 } 1152 1153 gd_cross_vec3f(&sp70, a1, &sp94); 1154 sp2C = (f32) gd_sqrt_d((sp94.x * sp94.x) + (sp94.z * sp94.z)); 1155 1156 if (sp2C > 1000.0) { //? 1000.0f 1157 sp2C = 1000.0f; 1158 } 1159 1160 sp2C /= 1000.0; //? 1000.0f 1161 sp2C = 1.0 - sp2C; //? 1.0f - sp2C 1162 1163 sp88.x = a2->x * sp2C; 1164 sp88.y = a2->y * sp2C; 1165 sp88.z = a2->z * sp2C; 1166 1167 a0->collDisp.x += sp88.x; 1168 a0->collDisp.y += sp88.y; 1169 a0->collDisp.z += sp88.z; 1170 } 1171 1172 /* @ 22D008 for 0x1B4 */ 1173 void func_8017E838(struct ObjNet *a0, struct GdVec3f *a1, struct GdVec3f *a2) { 1174 UNUSED u8 filler1[12]; 1175 struct GdVec3f sp70; 1176 struct GdVec3f sp64; 1177 UNUSED u8 filler2[64]; 1178 struct GdVec3f sp18; 1179 1180 sp64.x = a1->x; 1181 sp64.y = a1->y; 1182 sp64.z = a1->z; 1183 1184 sp18.x = a0->centerOfGravity.x; 1185 sp18.y = a0->centerOfGravity.y; 1186 sp18.z = a0->centerOfGravity.z; 1187 1188 gd_rotate_and_translate_vec3f(&sp18, &a0->mat128); 1189 1190 sp64.x -= sp18.x; 1191 sp64.y -= sp18.y; 1192 sp64.z -= sp18.z; 1193 1194 sp64.x *= 0.01; //? 0.01f; 1195 sp64.y *= 0.01; //? 0.01f; 1196 sp64.z *= 0.01; //? 0.01f; 1197 1198 gd_cross_vec3f(a2, &sp64, &sp70); 1199 gd_clamp_vec3f(&sp70, 5.0f); 1200 1201 a0->collTorque.x += sp70.x; 1202 a0->collTorque.y += sp70.y; 1203 a0->collTorque.z += sp70.z; 1204 } 1205 1206 /* @ 22D1BC for 0xA8 */ 1207 void func_8017E9EC(struct ObjNet *net) { 1208 struct GdVec3f sp5C; 1209 Mat4f sp1C; 1210 f32 sp18; 1211 1212 sp5C.x = net->torque.x; 1213 sp5C.y = net->torque.y; 1214 sp5C.z = net->torque.z; 1215 1216 gd_normalize_vec3f(&sp5C); 1217 sp18 = gd_vec3f_magnitude(&net->torque); 1218 gd_create_rot_mat_angular(&sp1C, &sp5C, -sp18); 1219 gd_mult_mat4f(&D_801B9DC8, &sp1C, &D_801B9DC8); 1220 } 1221 1222 /** 1223 * Unused (not called) 1224 */ 1225 s32 func_8017EA94(struct GdVec3f *vec, Mat4f matrix) { 1226 if (vec->x >= matrix[2][2] && vec->x <= matrix[3][1] && vec->z >= matrix[3][0] 1227 && vec->z <= matrix[3][3]) { 1228 return 1; 1229 } 1230 1231 return 0; 1232 } 1233 1234 /** 1235 * Unused (not called) 1236 */ 1237 s32 func_8017EB24(struct GdObj *obj1, struct GdObj *obj2) { 1238 struct GdVec3f pos1; 1239 struct GdVec3f pos2; 1240 struct GdBoundingBox *bbox1; 1241 struct GdBoundingBox *bbox2; 1242 struct GdBoundingBox sp18; 1243 1244 set_cur_dynobj(obj1); 1245 d_get_world_pos(&pos1); 1246 bbox1 = d_get_bounding_box(); 1247 1248 set_cur_dynobj(obj2); 1249 d_get_world_pos(&pos2); 1250 bbox2 = d_get_bounding_box(); 1251 1252 // bbox2 is an offset for bbox1? 1253 sp18.minX = bbox1->minX + bbox2->minX; 1254 sp18.minY = bbox1->minY + bbox2->minY; 1255 sp18.minZ = bbox1->minZ + bbox2->minZ; 1256 sp18.maxX = bbox1->maxX + bbox2->maxX; 1257 sp18.maxY = bbox1->maxY + bbox2->maxY; 1258 sp18.maxZ = bbox1->maxZ + bbox2->maxZ; 1259 1260 D_801B9E08.x = pos2.x - pos1.x; 1261 D_801B9E08.y = pos2.y - pos1.y; 1262 D_801B9E08.z = pos2.z - pos1.z; 1263 1264 if (D_801B9E08.x >= sp18.minX) { 1265 if (D_801B9E08.x <= sp18.maxX) { 1266 if (D_801B9E08.z >= sp18.minZ) { 1267 if (D_801B9E08.z <= sp18.maxZ) { 1268 return TRUE; 1269 } 1270 } 1271 } 1272 } 1273 1274 return FALSE; 1275 } 1276 1277 /** 1278 * Unused (not called) 1279 */ 1280 s32 is_obj_xz_in_bounding_box(struct GdObj *obj, struct GdBoundingBox *bbox) { 1281 struct GdVec3f pos; 1282 1283 set_cur_dynobj(obj); 1284 d_get_world_pos(&pos); 1285 1286 if (pos.x >= bbox->minX) { 1287 if (pos.x <= bbox->maxX) { 1288 if (pos.z >= bbox->minZ) { 1289 if (pos.z <= bbox->maxZ) { 1290 return TRUE; 1291 } 1292 } 1293 } 1294 } 1295 1296 return FALSE; 1297 } 1298 1299 /** 1300 * Unused (not called) 1301 */ 1302 s32 is_point_xz_in_bounding_box(struct GdVec3f *point, struct GdBoundingBox *bbox) { 1303 if (point->x >= bbox->minX) { 1304 if (point->x <= bbox->maxX) { 1305 if (point->z >= bbox->minZ) { 1306 if (point->z <= bbox->maxZ) { 1307 return TRUE; 1308 } 1309 } 1310 } 1311 } 1312 1313 return FALSE; 1314 } 1315 1316 /** 1317 * Unused (called by func_801A71CC) - returns TRUE if any of the four corners of 1318 * box1's X-Z plane lie within box2's X-Z plane 1319 */ 1320 s32 gd_plane_point_within(struct GdBoundingBox *box1, struct GdBoundingBox *box2) { 1321 // test if min x and min z of box1 are within box2 1322 if (box1->minX >= box2->minX) { 1323 if (box1->minX <= box2->maxX) { 1324 if (box1->minZ >= box2->minZ) { 1325 if (box1->minZ <= box2->maxZ) { 1326 return TRUE; 1327 } 1328 } 1329 } 1330 } 1331 1332 // test if max x and min z of box1 are within box2 1333 if (box1->maxX >= box2->minX) { 1334 if (box1->maxX <= box2->maxX) { 1335 if (box1->minZ >= box2->minZ) { 1336 if (box1->minZ <= box2->maxZ) { 1337 return TRUE; 1338 } 1339 } 1340 } 1341 } 1342 1343 // test if max x and max z of box1 are within box2 1344 if (box1->maxX >= box2->minX) { 1345 if (box1->maxX <= box2->maxX) { 1346 if (box1->maxZ >= box2->minZ) { 1347 if (box1->maxZ <= box2->maxZ) { 1348 return TRUE; 1349 } 1350 } 1351 } 1352 } 1353 1354 // test if min x and max z of box1 are within box2 1355 if (box1->minX >= box2->minX) { 1356 if (box1->minX <= box2->maxX) { 1357 if (box1->maxZ >= box2->minZ) { 1358 if (box1->maxZ <= box2->maxZ) { 1359 return TRUE; 1360 } 1361 } 1362 } 1363 } 1364 1365 return FALSE; 1366 } 1367 1368 /* @ 22D824 for 0x1BC */ 1369 s32 transform_child_objects_recursive(struct GdObj *obj, struct GdObj *parentObj) { 1370 struct ListNode *curLink; 1371 struct ObjGroup *curGroup; 1372 UNUSED u8 filler1[4]; 1373 Mat4f *parentUnkMtx; 1374 Mat4f *iMtx; 1375 Mat4f *unkMtx; 1376 Mat4f *rotMtx; 1377 Mat4f *rotMtx2; 1378 UNUSED u8 filler2[24]; 1379 struct GdVec3f scale; 1380 1381 if (parentObj != NULL) { 1382 set_cur_dynobj(parentObj); 1383 parentUnkMtx = d_get_matrix_ptr(); 1384 rotMtx = (Mat4f *) d_get_rot_mtx_ptr(); 1385 1386 set_cur_dynobj(obj); 1387 iMtx = d_get_i_mtx_ptr(); 1388 rotMtx2 = (Mat4f *) d_get_rot_mtx_ptr(); 1389 1390 d_get_scale(&scale); 1391 1392 unkMtx = d_get_matrix_ptr(); 1393 gd_mult_mat4f(iMtx, parentUnkMtx, unkMtx); 1394 1395 gd_mult_mat4f(iMtx, rotMtx, rotMtx2); 1396 gd_scale_mat4f_by_vec3f(rotMtx2, &scale); 1397 } else { 1398 set_cur_dynobj(obj); 1399 unkMtx = d_get_matrix_ptr(); 1400 iMtx = d_get_i_mtx_ptr(); 1401 rotMtx = (Mat4f *) d_get_rot_mtx_ptr(); 1402 1403 d_get_scale(&scale); 1404 gd_set_identity_mat4(unkMtx); 1405 gd_copy_mat4f(iMtx, rotMtx); 1406 gd_scale_mat4f_by_vec3f(rotMtx, &scale); 1407 } 1408 1409 // Recursively call this function on attached children 1410 set_cur_dynobj(obj); 1411 curGroup = d_get_att_objgroup(); 1412 if (curGroup != NULL) { 1413 curLink = curGroup->firstMember; 1414 while (curLink != NULL) { 1415 transform_child_objects_recursive(curLink->obj, obj); 1416 curLink = curLink->next; 1417 } 1418 } 1419 return 0; 1420 } 1421 1422 /* @ 22D9E0 for 0x1BC */ 1423 s32 func_8017F210(struct GdObj *a0, struct GdObj *a1) { 1424 struct ListNode *sp6C; 1425 struct ObjGroup *sp68; 1426 UNUSED u8 filler1[4]; 1427 UNUSED Mat4f *sp60; 1428 Mat4f *sp5C; 1429 UNUSED Mat4f *sp58; 1430 Mat4f *sp54; 1431 Mat4f *sp50; 1432 UNUSED u8 filler2[24]; 1433 struct GdVec3f sp2C; 1434 s32 count = 0; 1435 1436 count++; 1437 1438 if (a1 != NULL) { 1439 set_cur_dynobj(a1); 1440 sp60 = d_get_matrix_ptr(); 1441 sp54 = (Mat4f *) d_get_rot_mtx_ptr(); 1442 1443 set_cur_dynobj(a0); 1444 sp5C = d_get_i_mtx_ptr(); 1445 sp50 = (Mat4f *) d_get_rot_mtx_ptr(); 1446 1447 d_get_scale(&sp2C); 1448 gd_mult_mat4f(sp5C, sp54, sp50); 1449 gd_scale_mat4f_by_vec3f(sp50, &sp2C); 1450 } else { 1451 set_cur_dynobj(a0); 1452 sp58 = d_get_matrix_ptr(); 1453 sp5C = d_get_i_mtx_ptr(); 1454 sp54 = (Mat4f *) d_get_rot_mtx_ptr(); 1455 1456 d_get_scale(&sp2C); 1457 gd_copy_mat4f(sp5C, sp54); 1458 gd_scale_mat4f_by_vec3f(sp54, &sp2C); 1459 } 1460 1461 set_cur_dynobj(a0); 1462 sp68 = d_get_att_objgroup(); 1463 1464 if (sp68 != NULL) { 1465 sp6C = sp68->firstMember; 1466 while (sp6C != NULL) { 1467 count += func_8017F210(sp6C->obj, a0); 1468 sp6C = sp6C->next; 1469 } 1470 } 1471 return count; 1472 } 1473 1474 /* @ 22DB9C for 0x38; a0 might be ObjUnk200000* */ 1475 void func_8017F3CC(struct Unk8017F3CC *a0) { 1476 gd_rotate_and_translate_vec3f(&a0->unk20, D_801B9E48); 1477 } 1478 1479 /* @ 22DBD4 for 0x20 */ 1480 void stub_objects_3(UNUSED f32 a0, UNUSED struct GdObj *a1, UNUSED struct GdObj *a2) { 1481 UNUSED u8 filler[48]; 1482 } 1483 1484 /** 1485 * Interpolates between animation transformations `t1` and `t2`, with `dt` as 1486 * the interpolation factor (between 0 and 1). Sets the current dynobj's matrix 1487 * as the result of the transformation. 1488 */ 1489 void interpolate_animation_transform(struct GdAnimTransform *t1, struct GdAnimTransform *t2, f32 dt) { 1490 Mat4f mtx; 1491 1492 gd_set_identity_mat4(&mtx); 1493 1494 if (dt != 0.0f) { 1495 struct GdAnimTransform transform; 1496 1497 // interpolate rotation between t1 and t2 1498 transform.rotate.x = t1->rotate.x + (t2->rotate.x - t1->rotate.x) * dt; 1499 transform.rotate.y = t1->rotate.y + (t2->rotate.y - t1->rotate.y) * dt; 1500 transform.rotate.z = t1->rotate.z + (t2->rotate.z - t1->rotate.z) * dt; 1501 1502 // interpolate position between t1 and t2 1503 transform.pos.x = t1->pos.x + (t2->pos.x - t1->pos.x) * dt; 1504 transform.pos.y = t1->pos.y + (t2->pos.y - t1->pos.y) * dt; 1505 transform.pos.z = t1->pos.z + (t2->pos.z - t1->pos.z) * dt; 1506 1507 // not going to interpolate scale? 1508 1509 gd_scale_mat4f_by_vec3f(&mtx, &t1->scale); 1510 gd_rot_mat_about_vec(&mtx, &transform.rotate); 1511 gd_add_vec3f_to_mat4f_offset(&mtx, &transform.pos); 1512 } else { 1513 d_set_scale(t1->scale.x, t1->scale.y, t1->scale.z); 1514 gd_rot_mat_about_vec(&mtx, &t1->rotate); 1515 gd_add_vec3f_to_mat4f_offset(&mtx, &t1->pos); 1516 } 1517 d_set_i_matrix(&mtx); 1518 } 1519 1520 /* @ 22DD94 for 0x1060; orig name: func_8017F5C4 */ 1521 void move_animator(struct ObjAnimator *animObj) { 1522 struct AnimDataInfo *animData; // array? 1523 Mat4f *mtxArr; 1524 Mat4f localMtx; 1525 struct GdAnimTransform *triPtr; 1526 struct GdAnimTransform currTransform; // transformation for the current keyframe 1527 struct GdAnimTransform nextTransform; // transformation for the next keyframe 1528 s16(*animData9s16)[9]; // GdTriangleH[]? 1529 s16(*animData3s16)[3]; // MyVec3h[]? 1530 s16(*animData6s16)[6]; // GdPlaneH[]? 1531 s16(*animDataCam)[6]; // camera GdPlaneH[]? 1532 struct GdObj *stubObj1 = NULL; // used only for call to stubbed function 1533 struct GdObj *stubObj2 = NULL; // used only for call to stubbed function 1534 UNUSED u8 filler[12]; 1535 UNUSED struct GdVec3f unusedVec; 1536 s32 currKeyFrame; 1537 s32 nextKeyFrame; 1538 f32 dt; 1539 f32 scale = 0.1f; 1540 struct AnimMtxVec *sp28; 1541 register struct ListNode *link; 1542 struct GdObj *linkedObj; 1543 1544 if (animObj->controlFunc != NULL) { 1545 animObj->controlFunc(animObj); 1546 } 1547 1548 if (animObj->animatedPartsGrp == NULL) { 1549 return; // nothing to animate 1550 } 1551 1552 animData = (struct AnimDataInfo *) animObj->animdataGrp->firstMember->obj; 1553 1554 if (animObj->attachedToObj != NULL) { 1555 animObj->frame = ((struct ObjAnimator *) animObj->attachedToObj)->frame 1556 / ((struct ObjAnimator *) animObj->attachedToObj)->unk24; 1557 animData += ((struct ObjAnimator *) animObj->attachedToObj)->animSeqNum; 1558 } 1559 1560 if (animData->type == 0) { 1561 return; 1562 } 1563 1564 unusedVec.x = 4.0f; 1565 unusedVec.y = 1.0f; 1566 unusedVec.z = 1.0f; 1567 1568 if (animObj->frame > (f32) animData->count) { 1569 animObj->frame = 1.0f; 1570 } else if (animObj->frame < 0.0f) { 1571 animObj->frame = (f32) animData->count; 1572 } 1573 1574 currKeyFrame = (s32) animObj->frame; 1575 dt = animObj->frame - (f32) currKeyFrame; 1576 nextKeyFrame = currKeyFrame + 1; 1577 1578 if (nextKeyFrame > animData->count) { 1579 nextKeyFrame = 1; 1580 } 1581 1582 // convert frame numbers to zero-indexed 1583 currKeyFrame--; 1584 nextKeyFrame--; 1585 1586 link = animObj->animatedPartsGrp->firstMember; 1587 while (link != NULL) { 1588 linkedObj = link->obj; 1589 set_cur_dynobj(linkedObj); 1590 switch (animData->type) { 1591 case GD_ANIM_MTX4x4: // data = Mat4f* (f32[4][4]) 1592 mtxArr = (Mat4f *) animData->data; 1593 /* This needs be be un-dereferenced pointer addition to make the registers match */ 1594 d_set_i_matrix(mtxArr + (s32) animObj->frame); 1595 break; 1596 case GD_ANIM_ROT3S: // data = s16(*)[3] - rotation only 1597 animData3s16 = (s16(*)[3]) animData->data; 1598 1599 // keep current object scale 1600 d_get_scale(&currTransform.scale); 1601 nextTransform.scale.x = currTransform.scale.x; 1602 nextTransform.scale.y = currTransform.scale.y; 1603 nextTransform.scale.z = currTransform.scale.z; 1604 1605 // keep current object position 1606 d_get_init_pos(&currTransform.pos); 1607 nextTransform.pos.x = currTransform.pos.x; 1608 nextTransform.pos.y = currTransform.pos.y; 1609 nextTransform.pos.z = currTransform.pos.z; 1610 1611 // use animation rotation 1612 currTransform.rotate.x = (f32) animData3s16[currKeyFrame][0] * scale; 1613 currTransform.rotate.y = (f32) animData3s16[currKeyFrame][1] * scale; 1614 currTransform.rotate.z = (f32) animData3s16[currKeyFrame][2] * scale; 1615 1616 nextTransform.rotate.x = (f32) animData3s16[nextKeyFrame][0] * scale; 1617 nextTransform.rotate.y = (f32) animData3s16[nextKeyFrame][1] * scale; 1618 nextTransform.rotate.z = (f32) animData3s16[nextKeyFrame][2] * scale; 1619 1620 interpolate_animation_transform(&currTransform, &nextTransform, dt); 1621 break; 1622 case GD_ANIM_POS3S: // data = s16(*)[3] - position only 1623 animData3s16 = (s16(*)[3]) animData->data; 1624 1625 // keep current object scale 1626 d_get_scale(&currTransform.scale); 1627 nextTransform.scale.x = currTransform.scale.x; 1628 nextTransform.scale.y = currTransform.scale.y; 1629 nextTransform.scale.z = currTransform.scale.z; 1630 1631 // keep current object rotation 1632 d_get_init_rot(&currTransform.rotate); 1633 nextTransform.rotate.x = currTransform.rotate.x; 1634 nextTransform.rotate.y = currTransform.rotate.y; 1635 nextTransform.rotate.z = currTransform.rotate.z; 1636 1637 // use animation position 1638 currTransform.pos.x = (f32) animData3s16[currKeyFrame][0]; 1639 currTransform.pos.y = (f32) animData3s16[currKeyFrame][1]; 1640 currTransform.pos.z = (f32) animData3s16[currKeyFrame][2]; 1641 1642 nextTransform.pos.x = (f32) animData3s16[nextKeyFrame][0]; 1643 nextTransform.pos.y = (f32) animData3s16[nextKeyFrame][1]; 1644 nextTransform.pos.z = (f32) animData3s16[nextKeyFrame][2]; 1645 1646 interpolate_animation_transform(&currTransform, &nextTransform, dt); 1647 break; 1648 case GD_ANIM_ROT3S_POS3S: // data = s16(*)[6] - rotation and position 1649 animData6s16 = (s16(*)[6]) animData->data; 1650 1651 // keep current object scale 1652 d_get_scale(&currTransform.scale); 1653 nextTransform.scale.x = currTransform.scale.x; 1654 nextTransform.scale.y = currTransform.scale.y; 1655 nextTransform.scale.z = currTransform.scale.z; 1656 1657 // use animation rotation 1658 currTransform.rotate.x = (f32) animData6s16[currKeyFrame][0] * scale; 1659 currTransform.rotate.y = (f32) animData6s16[currKeyFrame][1] * scale; 1660 currTransform.rotate.z = (f32) animData6s16[currKeyFrame][2] * scale; 1661 1662 nextTransform.rotate.x = (f32) animData6s16[nextKeyFrame][0] * scale; 1663 nextTransform.rotate.y = (f32) animData6s16[nextKeyFrame][1] * scale; 1664 nextTransform.rotate.z = (f32) animData6s16[nextKeyFrame][2] * scale; 1665 1666 // use animation position 1667 currTransform.pos.x = (f32) animData6s16[currKeyFrame][3]; 1668 currTransform.pos.y = (f32) animData6s16[currKeyFrame][4]; 1669 currTransform.pos.z = (f32) animData6s16[currKeyFrame][5]; 1670 1671 nextTransform.pos.x = (f32) animData6s16[nextKeyFrame][3]; 1672 nextTransform.pos.y = (f32) animData6s16[nextKeyFrame][4]; 1673 nextTransform.pos.z = (f32) animData6s16[nextKeyFrame][5]; 1674 1675 interpolate_animation_transform(&currTransform, &nextTransform, dt); 1676 break; 1677 case GD_ANIM_SCALE3S_POS3S_ROT3S: // data = s16(*)[9] - scale, position, and rotation 1678 animData9s16 = (s16(*)[9]) animData->data; 1679 1680 currTransform.scale.x = (f32) animData9s16[currKeyFrame][0] * scale; 1681 currTransform.scale.y = (f32) animData9s16[currKeyFrame][1] * scale; 1682 currTransform.scale.z = (f32) animData9s16[currKeyFrame][2] * scale; 1683 1684 currTransform.rotate.x = (f32) animData9s16[currKeyFrame][3] * scale; 1685 currTransform.rotate.y = (f32) animData9s16[currKeyFrame][4] * scale; 1686 currTransform.rotate.z = (f32) animData9s16[currKeyFrame][5] * scale; 1687 1688 currTransform.pos.x = (f32) animData9s16[currKeyFrame][6]; 1689 currTransform.pos.y = (f32) animData9s16[currKeyFrame][7]; 1690 currTransform.pos.z = (f32) animData9s16[currKeyFrame][8]; 1691 1692 nextTransform.scale.x = (f32) animData9s16[nextKeyFrame][0] * scale; 1693 nextTransform.scale.y = (f32) animData9s16[nextKeyFrame][1] * scale; 1694 nextTransform.scale.z = (f32) animData9s16[nextKeyFrame][2] * scale; 1695 1696 nextTransform.rotate.x = (f32) animData9s16[nextKeyFrame][3] * scale; 1697 nextTransform.rotate.y = (f32) animData9s16[nextKeyFrame][4] * scale; 1698 nextTransform.rotate.z = (f32) animData9s16[nextKeyFrame][5] * scale; 1699 1700 nextTransform.pos.x = (f32) animData9s16[nextKeyFrame][6]; 1701 nextTransform.pos.y = (f32) animData9s16[nextKeyFrame][7]; 1702 nextTransform.pos.z = (f32) animData9s16[nextKeyFrame][8]; 1703 1704 interpolate_animation_transform(&currTransform, &nextTransform, dt); 1705 break; 1706 case GD_ANIM_CAMERA_EYE3S_LOOKAT3S: // s16(*)[6]? 1707 if (linkedObj->type == OBJ_TYPE_CAMERAS) { 1708 animDataCam = animData->data; 1709 1710 // eye position 1711 currTransform.pos.x = (f32) animDataCam[currKeyFrame][0]; 1712 currTransform.pos.y = (f32) animDataCam[currKeyFrame][1]; 1713 currTransform.pos.z = (f32) animDataCam[currKeyFrame][2]; 1714 1715 // lookat position 1716 nextTransform.pos.x = (f32) animDataCam[currKeyFrame][3]; 1717 nextTransform.pos.y = (f32) animDataCam[currKeyFrame][4]; 1718 nextTransform.pos.z = (f32) animDataCam[currKeyFrame][5]; 1719 1720 ((struct ObjCamera *) linkedObj)->worldPos.x = currTransform.pos.x; 1721 ((struct ObjCamera *) linkedObj)->worldPos.y = currTransform.pos.y; 1722 ((struct ObjCamera *) linkedObj)->worldPos.z = currTransform.pos.z; 1723 1724 ((struct ObjCamera *) linkedObj)->lookAt.x = nextTransform.pos.x; 1725 ((struct ObjCamera *) linkedObj)->lookAt.y = nextTransform.pos.y; 1726 ((struct ObjCamera *) linkedObj)->lookAt.z = nextTransform.pos.z; 1727 } 1728 break; 1729 case GD_ANIM_SCALE3F_ROT3F_POS3F: // scale, rotation, and position (as floats) 1730 triPtr = (struct GdAnimTransform *) animData->data; 1731 interpolate_animation_transform(&triPtr[currKeyFrame], &triPtr[nextKeyFrame], dt); 1732 break; 1733 case GD_ANIM_MTX4x4F_SCALE3F: // AnimMtxVec[] 1734 sp28 = &((struct AnimMtxVec *) animData->data)[currKeyFrame]; 1735 d_set_i_matrix(&sp28->matrix); 1736 d_set_scale(sp28->vec.x, sp28->vec.y, sp28->vec.z); 1737 break; 1738 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? 1739 triPtr = (struct GdAnimTransform *) animData->data; 1740 gd_set_identity_mat4(&localMtx); 1741 gd_scale_mat4f_by_vec3f(&localMtx, &triPtr->scale); 1742 gd_rot_mat_about_vec(&localMtx, &triPtr->rotate); 1743 gd_add_vec3f_to_mat4f_offset(&localMtx, &triPtr->pos); 1744 d_set_i_matrix(&localMtx); 1745 break; 1746 case GD_ANIM_STUB: 1747 if (stubObj1 == NULL) { 1748 stubObj1 = linkedObj; 1749 } else { 1750 if (stubObj2 == NULL) { 1751 stubObj2 = linkedObj; 1752 stub_objects_3(animObj->frame, stubObj1, stubObj2); 1753 } else { 1754 fatal_printf("Too many objects to morph"); 1755 } 1756 } 1757 break; 1758 default: 1759 fatal_printf("move_animator(): Unkown animation data type"); 1760 } 1761 link = link->next; 1762 } 1763 } 1764 1765 /* @ 22EDF4 for 0x300; orig name: func_80180624 */ 1766 void drag_picked_object(struct GdObj *inputObj) { 1767 UNUSED u8 filler1[12]; 1768 struct GdVec3f displacement; 1769 struct GdVec3f spC4; 1770 struct GdControl *ctrl; 1771 Mat4f sp80; 1772 Mat4f sp40; 1773 UNUSED u8 filler2[12]; 1774 struct GdObj *obj; 1775 UNUSED u8 filler3[4]; 1776 f32 dispMag; 1777 1778 ctrl = &gGdCtrl; 1779 1780 if (gViewUpdateCamera == NULL) { 1781 return; 1782 } 1783 1784 dispMag = gd_vec3f_magnitude(&gViewUpdateCamera->unk40); 1785 dispMag /= 1000.0f; 1786 1787 displacement.x = ((f32)(ctrl->csrX - ctrl->dragStartX)) * dispMag; 1788 displacement.y = ((f32) - (ctrl->csrY - ctrl->dragStartY)) * dispMag; 1789 displacement.z = 0.0f; 1790 1791 gd_inverse_mat4f(&gViewUpdateCamera->unkE8, &sp40); 1792 gd_mat4f_mult_vec3f(&displacement, &sp40); 1793 1794 obj = inputObj; 1795 if ((inputObj->drawFlags & OBJ_PICKED) && gGdCtrl.dragging) { 1796 gd_play_sfx(GD_SFX_PINCH_FACE); 1797 // Note: this second sfx won't play, as it is "overwritten" by the first 1798 if (ABS(ctrl->stickDeltaX) + ABS(ctrl->stickDeltaY) >= 11) { 1799 gd_play_sfx(GD_SFX_PINCH_FACE_2); 1800 } 1801 1802 switch (inputObj->type) { 1803 case OBJ_TYPE_JOINTS: 1804 ((struct ObjJoint *) obj)->mat128[3][0] += displacement.x; 1805 ((struct ObjJoint *) obj)->mat128[3][1] += displacement.y; 1806 ((struct ObjJoint *) obj)->mat128[3][2] += displacement.z; 1807 break; 1808 case OBJ_TYPE_GADGETS: 1809 break; 1810 case OBJ_TYPE_NETS: 1811 gd_inverse_mat4f(&((struct ObjNet *) obj)->mat128, &sp80); 1812 spC4.x = displacement.x; 1813 spC4.y = displacement.y; 1814 spC4.z = displacement.z; 1815 1816 gd_mat4f_mult_vec3f(&spC4, &sp80); 1817 ((struct ObjNet *) obj)->matE8[3][0] += displacement.x; 1818 ((struct ObjNet *) obj)->matE8[3][1] += displacement.y; 1819 ((struct ObjNet *) obj)->matE8[3][2] += displacement.z; 1820 break; 1821 case OBJ_TYPE_PARTICLES: 1822 break; 1823 default:; 1824 } 1825 } 1826 } 1827 1828 /* @ 22F0F4 for 0x50; orig name: func_80180924*/ 1829 void move_animators(struct ObjGroup *group) { 1830 restart_timer("move_animators"); 1831 apply_to_obj_types_in_group(OBJ_TYPE_ANIMATORS, (applyproc_t) move_animator, group); 1832 split_timer("move_animators"); 1833 } 1834 1835 /* @ 22F144 for 0x3C; orig name: func_80180974 */ 1836 void find_and_drag_picked_object(struct ObjGroup *group) { 1837 apply_to_obj_types_in_group(OBJ_TYPE_ALL, (applyproc_t) drag_picked_object, group); 1838 } 1839 1840 /* @ 22F180 for 0x624; orig name: func_801809B0 */ 1841 void move_camera(struct ObjCamera *cam) { 1842 struct GdObj *spEC; 1843 struct GdVec3f spE0; 1844 struct GdVec3f spD4; 1845 struct GdVec3f spC8; 1846 UNUSED u8 filler1[12]; 1847 struct GdVec3f spB0; 1848 Mat4f sp70; 1849 UNUSED u8 filler2[64]; 1850 Mat4f *sp2C; 1851 struct GdControl *ctrl; 1852 1853 ctrl = &gGdCtrl; 1854 if (!(cam->flags & 0x10)) { 1855 return; 1856 } 1857 1858 spE0.x = spE0.y = spE0.z = 0.0f; 1859 spB0.x = spB0.y = spB0.z = 0.0f; 1860 1861 if ((spEC = cam->unk30) != NULL) { 1862 set_cur_dynobj(spEC); 1863 d_get_world_pos(&spE0); 1864 d_get_matrix(&sp70); 1865 1866 spC8.x = sp70[2][0] - cam->unk58; 1867 spC8.z = sp70[2][2] - cam->unk60; 1868 1869 cam->unk58 += spC8.x * cam->unk180.y; 1870 cam->unk60 += spC8.z * cam->unk180.y; 1871 1872 cam->unkA8[2][0] = cam->unk58; 1873 cam->unkA8[2][1] = 0.0f; 1874 cam->unkA8[2][2] = cam->unk60; 1875 1876 cam->unkA8[0][0] = cam->unkA8[2][2]; 1877 cam->unkA8[0][1] = 0.0f; 1878 cam->unkA8[0][2] = -cam->unkA8[2][0]; 1879 1880 cam->unkA8[1][0] = 0.0f; 1881 cam->unkA8[1][1] = 1.0f; 1882 cam->unkA8[1][2] = 0.0f; 1883 1884 // setting the unkA8 matrix above is pointless, if we're just going to overwrite it with the identity matrix. 1885 gd_set_identity_mat4(&cam->unkA8); 1886 } else { 1887 gd_set_identity_mat4(&cam->unkA8); 1888 } 1889 1890 sp2C = &cam->unk64; 1891 if ((cam->flags & CAMERA_FLAG_CONTROLLABLE) != 0) { 1892 if (ctrl->btnB != FALSE && ctrl->prevFrame->btnB == FALSE) { // new B press 1893 cam->zoomLevel++; 1894 if (cam->zoomLevel > cam->maxZoomLevel) { 1895 cam->zoomLevel = 0; 1896 } 1897 1898 switch (cam->zoomLevel) { 1899 case 0: 1900 gd_play_sfx(GD_SFX_CAM_ZOOM_IN); 1901 break; 1902 case 1: 1903 case 2: 1904 gd_play_sfx(GD_SFX_CAM_ZOOM_OUT); 1905 break; 1906 } 1907 } 1908 1909 if (ctrl->cleft) { 1910 cam->unk128.y += cam->unk134.y; 1911 } 1912 1913 if (ctrl->cright) { 1914 cam->unk128.y -= cam->unk134.y; 1915 } 1916 1917 if (ctrl->cup) { 1918 cam->unk128.x += cam->unk134.x; 1919 } 1920 1921 if (ctrl->cdown) { 1922 cam->unk128.x -= cam->unk134.x; 1923 } 1924 1925 cam->unk128.x = gd_clamp_f32(cam->unk128.x, 80.0f); 1926 1927 cam->unk4C.x = cam->zoomPositions[cam->zoomLevel].x; 1928 cam->unk4C.y = cam->zoomPositions[cam->zoomLevel].y; 1929 cam->unk4C.z = cam->zoomPositions[cam->zoomLevel].z; 1930 1931 gd_rot_2d_vec(cam->unk128.x, &cam->unk4C.y, &cam->unk4C.z); 1932 gd_rot_2d_vec(-cam->unk128.y, &cam->unk4C.x, &cam->unk4C.z); 1933 1934 cam->unk40.x += (cam->unk4C.x - cam->unk40.x) * cam->unk17C; 1935 cam->unk40.y += (cam->unk4C.y - cam->unk40.y) * cam->unk17C; 1936 cam->unk40.z += (cam->unk4C.z - cam->unk40.z) * cam->unk17C; 1937 } else { 1938 gd_set_identity_mat4(sp2C); 1939 } 1940 1941 spD4.x = cam->unk40.x; 1942 spD4.y = cam->unk40.y; 1943 spD4.z = cam->unk40.z; 1944 1945 spD4.x += spB0.x; 1946 spD4.y += spB0.y; 1947 spD4.z += spB0.z; 1948 1949 gd_mult_mat4f(sp2C, &cam->unkA8, &cam->unkA8); 1950 gd_mat4f_mult_vec3f(&spD4, &cam->unkA8); 1951 1952 cam->worldPos.x = spD4.x; 1953 cam->worldPos.y = spD4.y; 1954 cam->worldPos.z = spD4.z; 1955 1956 cam->worldPos.x += spE0.x; 1957 cam->worldPos.y += spE0.y; 1958 cam->worldPos.z += spE0.z; 1959 } 1960 1961 /* @ 22F7A4 for 0x38; orig name: func_80180FD4 */ 1962 void move_cameras_in_grp(struct ObjGroup *group) { 1963 apply_to_obj_types_in_group(OBJ_TYPE_CAMERAS, (applyproc_t) move_camera, group); 1964 } 1965 1966 /* @ 22F7DC for 0x36C*/ 1967 void func_8018100C(struct ObjLight *light) { 1968 Mat4f mtx; 1969 UNUSED u8 filler[12]; 1970 1971 if (light->unk40 == 3) { 1972 if (light->unk30 > 0.0) { //? 0.0f 1973 light->unk30 -= 0.2; //? 0.2f 1974 } 1975 1976 if (light->unk30 < 0.0f) { 1977 light->unk30 = 0.0f; 1978 } 1979 1980 if ((light->unk3C & 0x1) != 0) { 1981 light->unk30 = 1.0f; 1982 } 1983 1984 light->unk3C &= ~1; 1985 } 1986 // if (1)? 1987 return; 1988 // unreachable 1989 light->position.x += light->unk80.x; 1990 light->position.y += light->unk80.y; 1991 light->position.z += light->unk80.z; 1992 1993 // should be position.x for second comparison? 1994 if (light->position.x > 500.0f || light->position.y < -500.0f) { 1995 light->unk80.x = -light->unk80.x; 1996 } 1997 1998 if (light->position.y > 500.0f || light->position.y < -500.0f) { 1999 light->unk80.y = -light->unk80.y; 2000 } 2001 2002 if (light->position.z > 500.0f || light->position.z < -500.0f) { 2003 light->unk80.z = -light->unk80.z; 2004 } 2005 2006 return; 2007 // more unreachable 2008 D_801A81C0 += 1.0; //? 1.0f 2009 D_801A81C4 += 0.6; //? 0.6f 2010 2011 gd_set_identity_mat4(&mtx); 2012 gd_absrot_mat4(&mtx, GD_Y_AXIS, light->unk68.y); 2013 gd_absrot_mat4(&mtx, GD_X_AXIS, light->unk68.x); 2014 gd_absrot_mat4(&mtx, GD_Z_AXIS, light->unk68.z); 2015 gd_mat4f_mult_vec3f(&light->unk8C, &mtx); 2016 2017 light->position.x = light->unk8C.x; 2018 light->position.y = light->unk8C.y; 2019 light->position.z = light->unk8C.z; 2020 return; 2021 // even more unreachable 2022 gd_mat4f_mult_vec3f(&light->unk80, &mtx); 2023 imout(); // this call would cause an issue if it was reachable 2024 } 2025 2026 /* @ 22FB48 for 0x38; orig name: func_80181378 */ 2027 void move_lights_in_grp(struct ObjGroup *group) { 2028 apply_to_obj_types_in_group(OBJ_TYPE_LIGHTS, (applyproc_t) func_8018100C, group); 2029 } 2030 2031 /* @ 22FB80 for 0xAC; orig name: func_801813B0 */ 2032 void move_group_members(void) { 2033 s32 i; 2034 2035 if (gGdMoveScene != 0) { 2036 reset_gadgets_in_grp(sCurrentMoveGrp); 2037 move_lights_in_grp(sCurrentMoveGrp); 2038 move_particles_in_grp(sCurrentMoveGrp); 2039 move_animators(sCurrentMoveGrp); 2040 2041 for (i = 0; i <= 0; i++) { 2042 move_nets(sCurrentMoveGrp); 2043 } 2044 2045 move_cameras_in_grp(sCurrentMoveGrp); 2046 } 2047 } 2048 2049 /* @ 22FC2C for 0x98; orig name: func_8018145C */ 2050 void proc_view_movement(struct ObjView *view) { 2051 imin("movement"); 2052 sCurrentMoveCamera = view->activeCam; 2053 sCurrentMoveView = view; 2054 if ((sCurrentMoveGrp = view->components) != NULL) { 2055 move_group_members(); 2056 } 2057 if ((sCurrentMoveGrp = view->lights) != NULL) { 2058 move_group_members(); 2059 } 2060 imout(); 2061 } 2062 2063 /* @ 22FCC4 for 0x44; orig name: func_801814F4 */ 2064 void reset_nets_and_gadgets(struct ObjGroup *group) { 2065 func_80193848(group); 2066 apply_to_obj_types_in_group(OBJ_TYPE_GADGETS, (applyproc_t) reset_gadget, group); 2067 } 2068 2069 /* @ 22FD08 for 0x9C; orig name: func_80181538*/ 2070 void null_obj_lists(void) { 2071 D_801B9E44 = 0; 2072 gGdObjCount = 0; 2073 gGdGroupCount = 0; 2074 gGdPlaneCount = 0; 2075 gGdCameraCount = 0; 2076 sGdViewInfo.count = 0; 2077 2078 gGdCameraList = NULL; 2079 D_801B9E50 = NULL; 2080 gGdBoneList = NULL; 2081 gGdJointList = NULL; 2082 gGdGroupList = NULL; 2083 D_801B9E80 = NULL; 2084 gGdObjectList = NULL; 2085 gGdViewsGroup = NULL; 2086 2087 reset_net_count(); 2088 reset_joint_counts(); 2089 }