Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/goddard/joints.c
7858 views
1
#include <PR/ultratypes.h>
2
3
#if defined(VERSION_EU) || defined(VERSION_SH)
4
#include "prevent_bss_reordering.h"
5
#endif
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 "objects.h"
17
#include "renderer.h"
18
#include "sfx.h"
19
#include "skin.h"
20
#include "skin_movement.h"
21
22
#include "./game/settings.h"
23
#include "./game/game_init.h"
24
25
// data
26
static s32 D_801A82D0 = 0;
27
static struct ObjBone *gGdTempBone = NULL; // @ 801A82D4
28
29
// bss
30
s32 sResetWeightVtxNum; // WTF? why is this not in skin_movement.c?
31
32
static Mat4f *D_801BA964;
33
static struct GdVec3f D_801BA968;
34
static s32 sJointCount; // @ 801BA974
35
static s32 sJointNotF1Count; // @ 801BA978
36
static s32 sBoneCount; // @ 801BA97C
37
static s32 sJointArrLen; // @ 801BA980
38
static struct ObjJoint *sJointArr[10]; // @ 801BA988
39
static struct GdVec3f sJointArrVecs[10]; // @ 801BA9B0
40
static s32 sJointArr2Len; // @ 801BAA28
41
static struct ObjJoint *sJointArr2[10]; // @ 801BAA30
42
static struct GdVec3f sJointArr2Vecs[10]; // @ 801BAA58
43
static struct GdVec3f D_801BAAD0;
44
static struct GdVec3f D_801BAAE0;
45
46
// forward declarations
47
void set_joint_vecs(struct ObjJoint *, f32, f32, f32);
48
49
/**
50
* Controls movement of grabbable joints
51
*/
52
void grabbable_joint_update_func(struct ObjJoint *self) {
53
UNUSED u8 pad78[0xC8 - 0x78];
54
Mat4f *attObjMtx;
55
UNUSED u8 pad70[4];
56
struct GdVec3f offset; // difference between current position and initial position
57
UNUSED u8 pad50[0x10];
58
register struct ListNode *att;
59
UNUSED u8 pad48[0x8];
60
struct GdObj *attobj;
61
62
// The joint acts somewhat like a spring in that the further it is moved
63
// from its original position, the more resistance it has to moving further
64
65
offset.x = self->mat128[3][0] - self->initPos.x;
66
offset.y = self->mat128[3][1] - self->initPos.y;
67
offset.z = self->mat128[3][2] - self->initPos.z;
68
69
if (self->header.drawFlags & OBJ_PICKED) {
70
self->velocity.x = offset.x * -0.25;
71
self->velocity.y = offset.y * -0.25;
72
self->velocity.z = offset.z * -0.25;
73
74
self->flags |= 0x2000;
75
; // needed to match
76
} else {
77
if (gGdCtrl.trgR == FALSE) // R trigger is released
78
{
79
// Set velocity so that the joint approaches its initial position
80
self->velocity.x -= offset.x * 0.5; //? 0.5f
81
self->velocity.y -= offset.y * 0.5; //? 0.5f
82
self->velocity.z -= offset.z * 0.5; //? 0.5f
83
84
// Decay the velocity
85
self->velocity.x *= 0.8; //? 0.8f
86
self->velocity.y *= 0.8; //? 0.8f
87
self->velocity.z *= 0.8; //? 0.8f
88
89
// If the joint's velocity has decayed enough and it is very close
90
// to its original position, stop its movement altogether
91
if (ABS(self->velocity.x) + ABS(self->velocity.y) + ABS(self->velocity.z) < 1.0)
92
{
93
if (ABS(offset.x) + ABS(offset.y) + ABS(offset.z) < 1.0)
94
{
95
self->velocity.x = self->velocity.y = self->velocity.z = 0.0f;
96
self->mat128[3][0] -= offset.x;
97
self->mat128[3][1] -= offset.y;
98
self->mat128[3][2] -= offset.z;
99
}
100
}
101
102
if (self->flags & 0x2000) {
103
gd_play_sfx(GD_SFX_LET_GO_FACE);
104
}
105
106
self->flags &= ~0x2000;
107
; // necessary?
108
} else {
109
// freeze position of joint
110
self->velocity.x = self->velocity.y = self->velocity.z = 0.0f;
111
}
112
}
113
114
// update position
115
self->mat128[3][0] += self->velocity.x;
116
self->mat128[3][1] += self->velocity.y;
117
self->mat128[3][2] += self->velocity.z;
118
119
if (self->header.drawFlags & OBJ_PICKED
120
&& (!configMouseCam || (ABS(gPlayer1Controller->controllerData->stick2_x) < 0.1 && ABS(gPlayer1Controller->controllerData->stick2_y) < 0.1))) {
121
gGdCtrl.csrX -= (gGdCtrl.csrX - gGdCtrl.dragStartX) * 0.2;
122
gGdCtrl.csrY -= (gGdCtrl.csrY - gGdCtrl.dragStartY) * 0.2;
123
}
124
125
// update position of attached objects
126
offset.x = self->mat128[3][0] - self->initPos.x;
127
offset.y = self->mat128[3][1] - self->initPos.y;
128
offset.z = self->mat128[3][2] - self->initPos.z;
129
for (att = self->attachedObjsGrp->firstMember; att != NULL; att = att->next) {
130
attobj = att->obj;
131
set_cur_dynobj(attobj);
132
attObjMtx = d_get_matrix_ptr();
133
gd_add_vec3f_to_mat4f_offset(attObjMtx, &offset);
134
}
135
}
136
137
/**
138
* Update function for Mario's eye joints, which makes them follow the cursor
139
*/
140
void eye_joint_update_func(struct ObjJoint *self) {
141
Mat4f *sp5C;
142
struct GdVec3f sp50;
143
struct GdVec3f sp44;
144
UNUSED u8 pad2c[0x18];
145
register struct ListNode *att;
146
struct GdObj *attobj;
147
148
if (sCurrentMoveCamera == NULL) {
149
return;
150
}
151
152
if (self->rootAnimator != NULL) {
153
if (self->rootAnimator->state != 7) {
154
return;
155
}
156
}
157
158
set_cur_dynobj((struct GdObj *)self);
159
sp5C = d_get_rot_mtx_ptr();
160
sp44.x = (*sp5C)[3][0];
161
sp44.y = (*sp5C)[3][1];
162
sp44.z = (*sp5C)[3][2];
163
world_pos_to_screen_coords(&sp44, sCurrentMoveCamera, sCurrentMoveView);
164
165
sp50.x = gGdCtrl.csrX - sp44.x;
166
sp50.y = -(gGdCtrl.csrY - sp44.y);
167
sp50.z = 0.0f;
168
169
sp50.x *= 2.0; //?2.0f
170
sp50.y *= 2.0; //?2.0f
171
sp50.z *= 2.0; //?2.0f
172
if (gd_vec3f_magnitude(&sp50) > 30.0f) {
173
gd_normalize_vec3f(&sp50);
174
sp50.x *= 30.0f;
175
sp50.y *= 30.0f;
176
sp50.z *= 30.0f;
177
}
178
179
for (att = self->attachedObjsGrp->firstMember; att != NULL; att = att->next) {
180
attobj = att->obj;
181
set_cur_dynobj(attobj);
182
sp5C = d_get_rot_mtx_ptr();
183
gd_add_vec3f_to_mat4f_offset(sp5C, &sp50);
184
}
185
}
186
187
/* 23D62C -> 23D748; not called */
188
void func_8018EE5C(struct ObjJoint *j1, struct ObjJoint *j2, struct ObjJoint *j3) {
189
struct GdVec3f vec;
190
struct ObjJoint *curj;
191
192
if (j3 == NULL) {
193
return;
194
}
195
196
vec.z = j3->worldPos.x;
197
vec.y = j3->worldPos.y;
198
vec.x = j3->worldPos.z;
199
200
curj = j1;
201
while (curj != NULL) {
202
set_joint_vecs(curj, curj->worldPos.x + vec.z, curj->worldPos.y + vec.y, curj->worldPos.z + vec.x);
203
if (curj == j2) {
204
break;
205
}
206
curj = curj->prevjoint;
207
}
208
}
209
210
/* 23D748 -> 23D818; orig name: func_8018EF78 */
211
void set_joint_vecs(struct ObjJoint *j, f32 x, f32 y, f32 z) {
212
j->worldPos.x = x;
213
j->worldPos.y = y;
214
j->worldPos.z = z;
215
216
j->unk30.x = x;
217
j->unk30.y = y;
218
j->unk30.z = z;
219
220
j->unk3C.x = x;
221
j->unk3C.y = y;
222
j->unk3C.z = z;
223
224
j->initPos.x = x;
225
j->initPos.y = y;
226
j->initPos.z = z;
227
228
j->mat128[3][0] = x;
229
j->mat128[3][1] = y;
230
j->mat128[3][2] = z;
231
}
232
233
/* 23D818 -> 23DA18 */
234
struct ObjJoint *make_joint(s32 flags, f32 x, f32 y, f32 z) {
235
struct ObjJoint *j; // sp24
236
struct ObjJoint *oldhead;
237
UNUSED u32 pad1C;
238
239
j = (struct ObjJoint *) make_object(OBJ_TYPE_JOINTS);
240
sJointCount++;
241
oldhead = gGdJointList;
242
gGdJointList = j;
243
244
if (oldhead != NULL) {
245
j->nextjoint = oldhead;
246
oldhead->prevjoint = j;
247
}
248
gd_set_identity_mat4(&j->matE8);
249
gd_set_identity_mat4(&j->mat128);
250
set_joint_vecs(j, x, y, z);
251
j->type = 0;
252
j->id = sJointCount;
253
j->flags = flags;
254
255
if (!(j->flags & 0x1)) {
256
sJointNotF1Count++;
257
}
258
259
if (j->flags & 0x1) {
260
j->colourNum = COLOUR_RED;
261
} else {
262
j->colourNum = COLOUR_PINK;
263
}
264
265
j->unk1C4 = NULL;
266
j->shapePtr = NULL;
267
j->scale.x = 1.0f;
268
j->scale.y = 1.0f;
269
j->scale.z = 1.0f;
270
j->friction.x = 0.0f;
271
j->friction.y = 0.0f;
272
j->friction.z = 0.0f;
273
j->updateFunc = NULL;
274
275
return j;
276
}
277
278
/**
279
* Creates a joint that can be grabbed by the cursor. When moved, this joint
280
* drags the joints in its unk1F8 group along with it. The `shape` does not
281
* actually get rendered due to the joint's OBJ_INVISIBLE flag being set.
282
*/
283
struct ObjJoint *make_grabber_joint(struct ObjShape *shape, s32 flags, f32 x, f32 y, f32 z) {
284
struct ObjJoint *j;
285
286
j = make_joint(0, x, y, z);
287
j->shapePtr = shape;
288
j->type = 5;
289
j->flags |= flags;
290
j->colourNum = COLOUR_PINK;
291
j->header.drawFlags |= OBJ_IS_GRABBALE;
292
j->header.drawFlags |= OBJ_INVISIBLE;
293
j->updateFunc = grabbable_joint_update_func;
294
j->rootAnimator = NULL;
295
296
return j;
297
}
298
299
/* 23DAF8 -> 23DC9C */
300
void func_8018F328(struct ObjBone *b) {
301
struct ObjJoint *joint1;
302
struct ObjJoint *joint2;
303
struct ObjGroup *grp; // sp1C
304
struct ListNode *link; // sp18
305
306
grp = b->unk10C;
307
link = grp->firstMember;
308
joint1 = (struct ObjJoint *) link->obj;
309
link = link->next;
310
joint2 = (struct ObjJoint *) link->obj;
311
312
// bone position is average of two connecting joints
313
b->worldPos.x = (joint1->worldPos.x + joint2->worldPos.x) / 2.0; //?2.0f
314
b->worldPos.y = (joint1->worldPos.y + joint2->worldPos.y) / 2.0; //?2.0f
315
b->worldPos.z = (joint1->worldPos.z + joint2->worldPos.z) / 2.0; //?2.0f
316
317
b->unk58.x = joint2->worldPos.x - joint1->worldPos.x;
318
b->unk58.y = joint2->worldPos.y - joint1->worldPos.y;
319
b->unk58.z = joint2->worldPos.z - joint1->worldPos.z;
320
321
gd_normalize_vec3f(&b->unk58);
322
gd_create_origin_lookat(&b->matB0, &b->unk58, 0); //? 0.0f
323
}
324
325
/* 23DC9C -> 23DCF0 */
326
void func_8018F4CC(struct ObjJoint *j) {
327
if (j->flags & 0x1000) {
328
j->unkB4.x = D_801BA968.x;
329
j->unkB4.y = D_801BA968.y;
330
j->unkB4.z = D_801BA968.z;
331
}
332
}
333
334
/* 23DCF0 -> 23E06C */
335
void func_8018F520(struct ObjBone *b) {
336
struct ObjJoint *joint1;
337
struct ObjJoint *joint2;
338
UNUSED u32 pad[3];
339
struct GdVec3f sp90;
340
struct GdVec3f sp84;
341
struct GdVec3f sp78;
342
struct GdVec3f sp6C;
343
f32 sp68;
344
f32 sp64;
345
struct ObjGroup *grp; // sp60
346
struct ListNode *link;
347
Mat4f mtx; // sp1C
348
349
grp = b->unk10C;
350
link = grp->firstMember;
351
joint1 = (struct ObjJoint *) link->obj;
352
link = link->next;
353
joint2 = (struct ObjJoint *) link->obj;
354
355
// bone position is average of two connecting joints
356
b->worldPos.x = (joint1->worldPos.x + joint2->worldPos.x) / 2.0; //? 2.0f;
357
b->worldPos.y = (joint1->worldPos.y + joint2->worldPos.y) / 2.0; //? 2.0f;
358
b->worldPos.z = (joint1->worldPos.z + joint2->worldPos.z) / 2.0; //? 2.0f;
359
360
sp90.x = b->unk58.x;
361
sp90.y = b->unk58.y;
362
sp90.z = b->unk58.z;
363
364
sp6C.x = sp90.x;
365
sp6C.y = sp90.y;
366
sp6C.z = sp90.z;
367
368
sp6C.x -= b->unk64.x;
369
sp6C.y -= b->unk64.y;
370
sp6C.z -= b->unk64.z;
371
b->unk64.x = sp90.x;
372
b->unk64.y = sp90.y;
373
b->unk64.z = sp90.z;
374
375
sp68 = 5.4 / b->unkF8; //? 5.4f
376
sp6C.x *= sp68;
377
sp6C.y *= sp68;
378
sp6C.z *= sp68;
379
sp90.x *= sp68;
380
sp90.y *= sp68;
381
sp90.z *= sp68;
382
383
gd_cross_vec3f(&sp90, &sp6C, &sp78);
384
sp84.x = sp78.x;
385
sp84.y = sp78.y;
386
sp84.z = sp78.z;
387
388
gd_normalize_vec3f(&sp84);
389
sp64 = gd_vec3f_magnitude(&sp78);
390
gd_create_rot_mat_angular(&mtx, &sp84, sp64);
391
gd_mult_mat4f(&b->mat70, &mtx, &b->mat70);
392
D_801BA968.x = b->mat70[2][0];
393
D_801BA968.y = b->mat70[2][1];
394
D_801BA968.z = b->mat70[2][2];
395
D_801BA964 = &b->mat70;
396
397
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_8018F4CC, b->unk10C);
398
}
399
400
/* 23E06C -> 23E238 */
401
void func_8018F89C(struct ObjBone *b) {
402
struct ObjJoint *spAC;
403
struct ObjJoint *spA8;
404
UNUSED u8 pad64[0x44];
405
struct ObjGroup *grp; // sp60
406
struct ListNode *link; // sp5c
407
Mat4f mtx; // sp1c
408
409
grp = b->unk10C;
410
link = grp->firstMember;
411
spAC = (struct ObjJoint *) link->obj;
412
link = link->next;
413
spA8 = (struct ObjJoint *) link->obj;
414
415
b->worldPos.x = (spAC->worldPos.x + spA8->worldPos.x) / 2.0; //? 2.0f;
416
b->worldPos.y = (spAC->worldPos.y + spA8->worldPos.y) / 2.0; //? 2.0f;
417
b->worldPos.z = (spAC->worldPos.z + spA8->worldPos.z) / 2.0; //? 2.0f;
418
419
gd_mult_mat4f(&b->matB0, &gGdSkinNet->mat128, &mtx);
420
gd_copy_mat4f(&mtx, &b->mat70);
421
422
D_801BA968.x = -b->mat70[2][0];
423
D_801BA968.y = -b->mat70[2][1];
424
D_801BA968.z = -b->mat70[2][2];
425
D_801BA964 = &b->mat70;
426
427
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_8018F4CC, b->unk10C);
428
}
429
430
/* 23E238 -> 23E298 */
431
void func_8018FA68(struct ObjBone *b) {
432
if (b->unk104 & (0x8 | 0x2)) {
433
func_8018F89C(b);
434
} else {
435
func_8018F520(b);
436
}
437
}
438
439
/* 23E298 -> 23E328; orig name: func_8018FAC8 */
440
s32 set_skin_weight(struct ObjJoint *j, s32 id, struct ObjVertex *vtx /* always NULL */, f32 weight) {
441
struct ObjWeight *w;
442
443
if (j->weightGrp == NULL) {
444
j->weightGrp = make_group(0);
445
}
446
w = make_weight(0, id, vtx, weight);
447
addto_group(j->weightGrp, &w->header);
448
449
return TRUE;
450
}
451
452
/* 23E328 -> 23E474 */
453
void func_8018FB58(struct ObjBone *b) {
454
struct GdVec3f vec; // sp2c
455
struct ObjJoint *j1; // sp28
456
struct ObjJoint *j2;
457
struct ListNode *link;
458
struct ObjGroup *grp;
459
460
grp = b->unk10C;
461
link = grp->firstMember;
462
j1 = (struct ObjJoint *) link->obj;
463
link = link->next;
464
j2 = (struct ObjJoint *) link->obj;
465
466
vec.x = j1->worldPos.x - j2->worldPos.x;
467
vec.y = j1->worldPos.y - j2->worldPos.y;
468
vec.z = j1->worldPos.z - j2->worldPos.z;
469
470
b->unkF8 = gd_sqrt_d((vec.x * vec.x) + (vec.y * vec.y) + (vec.z * vec.z));
471
b->unkF4 = b->unkF8;
472
b->unkFC = b->unkF8;
473
func_8018F328(b);
474
}
475
476
/* 23E474 -> 23E56C */
477
void add_joint2bone(struct ObjBone *b, struct ObjJoint *j) {
478
if (j->header.type != OBJ_TYPE_JOINTS) {
479
fatal_printf("add_joint2bone(): Can only add Joints to Bones");
480
}
481
482
if (b->unk10C == NULL) {
483
b->unk10C = make_group(0);
484
}
485
addto_group(b->unk10C, &j->header);
486
487
if (j->unk1C4 == NULL) {
488
j->unk1C4 = make_group(0);
489
}
490
addto_group(j->unk1C4, &b->header);
491
492
if (b->unk10C->memberCount == 2) {
493
func_8018FB58(b);
494
}
495
}
496
497
/* 23E56C -> 23E6E4 */
498
struct ObjBone *make_bone(s32 a0, struct ObjJoint *j1, struct ObjJoint *j2, UNUSED s32 a3) {
499
struct ObjBone *b; // sp34
500
struct ObjBone *oldhead;
501
UNUSED u32 pad1C[5];
502
503
b = (struct ObjBone *) make_object(OBJ_TYPE_BONES);
504
sBoneCount++;
505
b->id = sBoneCount;
506
oldhead = gGdBoneList;
507
gGdBoneList = b;
508
509
if (oldhead != NULL) {
510
b->next = oldhead;
511
oldhead->prev = b;
512
}
513
b->unk10C = NULL;
514
b->colourNum = 0;
515
b->unk104 = a0;
516
b->shapePtr = NULL;
517
gd_set_identity_mat4(&b->mat70);
518
b->spring = 0.8f;
519
b->unk114 = 0.9f;
520
b->unkF8 = 100.0f;
521
522
if (j1 != NULL && j2 != NULL) {
523
add_joint2bone(b, j1);
524
add_joint2bone(b, j2);
525
}
526
527
printf("Made bone %d\n", b->id);
528
return b;
529
}
530
531
/* 23E6E4 -> 23E6F8; not called */
532
void stub_joints_1(UNUSED u32 a0) {
533
}
534
535
/* 23E6F8 -> 23E758; not called */
536
void func_8018FF28(struct ObjJoint *a0, struct ObjJoint *a1) {
537
if (a1->flags & 0x1) {
538
a0->unk84.x -= a1->unk84.x;
539
a0->unk84.y -= a1->unk84.y;
540
a0->unk84.z -= a1->unk84.z;
541
}
542
}
543
544
/**
545
* Unused (not called) - possibly was used to print indent levels inside
546
* recursive functions
547
*/
548
void print_some_spaces(s32 size) {
549
s32 i;
550
551
for (i = 0; i < size - 1; i++) {
552
gd_printf(" ");
553
}
554
}
555
556
/* 23E7B8 -> 23E938 */
557
s32 func_8018FFE8(struct ObjBone **a0, struct ObjJoint **a1, struct ObjJoint *a2, struct ObjJoint *a3) {
558
struct ObjBone *b; // 1C
559
struct ObjJoint *sp18;
560
s32 sp14 = 0;
561
struct ObjGroup *bonegrp; // 10
562
struct ObjGroup *grp; // 0c
563
struct ListNode *bonelink; // 08
564
struct ListNode *link; // 04
565
566
grp = a3->unk1C4;
567
568
if (grp == NULL) {
569
return 0;
570
}
571
link = grp->firstMember;
572
if (link == NULL) {
573
return 0;
574
}
575
576
while (link != NULL) {
577
if ((b = (struct ObjBone *) link->obj) != NULL) {
578
bonegrp = b->unk10C;
579
bonelink = bonegrp->firstMember;
580
581
while (bonelink != NULL) {
582
sp18 = (struct ObjJoint *) bonelink->obj;
583
584
if (sp18 != a3 && sp18 != a2) {
585
a1[sp14] = sp18;
586
a0[sp14] = b;
587
sp14++;
588
}
589
590
bonelink = bonelink->next;
591
}
592
}
593
link = link->next;
594
}
595
596
return sp14;
597
}
598
599
/* 23E938 -> 23EBB8 */
600
void func_80190168(struct ObjBone *b, UNUSED struct ObjJoint *a1, UNUSED struct ObjJoint *a2,
601
struct GdVec3f *a3) {
602
struct GdVec3f sp7C;
603
UNUSED u8 pad64[0x7c - 0x64];
604
f32 sp60;
605
f32 sp5C;
606
f32 sp58;
607
UNUSED u8 pad1C[0x58 - 0x1C];
608
609
return;
610
611
b->unk58.x = sp7C.x;
612
b->unk58.y = sp7C.y;
613
b->unk58.z = sp7C.z;
614
615
if (b->unk104 & 0x8) {
616
sp58 = gd_vec3f_magnitude(&sp7C);
617
if (sp58 == 0.0f) {
618
sp58 = 1.0f;
619
}
620
sp60 = (b->unkF8 / sp58) * b->spring;
621
}
622
623
if (b->unk104 & 0x4) {
624
if (sp60 > (sp58 = gd_vec3f_magnitude(&sp7C))) {
625
sp5C = b->spring;
626
a3->x *= sp5C;
627
a3->y *= sp5C;
628
a3->z *= sp5C;
629
} else {
630
a3->x = 0.0f;
631
a3->y = 0.0f;
632
a3->z = 0.0f;
633
}
634
}
635
636
if (b->unk104 & 0x2) {
637
if (sp60 < (sp58 = gd_vec3f_magnitude(&sp7C))) {
638
sp5C = b->spring;
639
a3->x *= sp5C;
640
a3->y *= sp5C;
641
a3->z *= sp5C;
642
} else {
643
a3->x = 0.0f;
644
a3->y = 0.0f;
645
a3->z = 0.0f;
646
}
647
}
648
}
649
650
/* 23EBB8 -> 23ED44 */
651
void func_801903E8(struct ObjJoint *j, struct GdVec3f *a1, f32 x, f32 y, f32 z) {
652
f32 sp14;
653
struct GdVec3f sp8;
654
655
if (j->flags & 0x1 || (j->flags & 0x1000) == 0) {
656
j->unk3C.x += x;
657
j->unk3C.y += y;
658
j->unk3C.z += z;
659
a1->x = a1->y = a1->z = 0.0f;
660
;
661
662
} else {
663
sp14 = (j->unkB4.x * x) + (j->unkB4.y * y) + (j->unkB4.z * z);
664
sp8.x = j->unkB4.x * sp14;
665
sp8.y = j->unkB4.y * sp14;
666
sp8.z = j->unkB4.z * sp14;
667
668
j->unk3C.x += sp8.x;
669
j->unk3C.y += sp8.y;
670
j->unk3C.z += sp8.z;
671
672
a1->x = x - sp8.x;
673
a1->y = y - sp8.y;
674
a1->z = z - sp8.z;
675
}
676
}
677
678
/* 23EBB8 -> 23F184 */
679
void func_80190574(s32 a0, struct ObjJoint *a1, struct ObjJoint *a2, f32 x, f32 y, f32 z) // sp278
680
{
681
struct ObjJoint *sp274; // = a2?
682
struct ObjJoint *sp270; // mid-point of stack array?
683
struct ObjJoint *sp26C; // jointstackarr[i]? curjoint?
684
UNUSED u32 pad268;
685
UNUSED u32 sp264 = 0;
686
UNUSED u32 sp258[3]; // unused vec?
687
struct GdVec3f sp24C;
688
struct GdVec3f sp240;
689
UNUSED u32 pad238[2];
690
s32 sp234; // i?
691
s32 sp230;
692
s32 sp22C = 1;
693
UNUSED u32 pad228;
694
s32 sp224;
695
s32 sp220;
696
struct ObjJoint *sp120[0x40];
697
struct ObjBone *sp20[0x40];
698
699
for (sp230 = 1; sp230 < a0; sp230 *= 2) {
700
sp22C = sp22C * 2 + 1;
701
}
702
703
if (a0 & 0x8000) {
704
fatal_print("Too many nestings!\n");
705
}
706
707
printf("\n");
708
printf("NIDmask: %d / ", a0);
709
710
a2->unk1C0 |= a0;
711
sp224 = func_8018FFE8(sp20, sp120, a1, a2);
712
func_801903E8(a2, &sp240, x, y, z);
713
for (sp234 = 0; sp234 < sp224; sp234++) {
714
if (a1 != NULL) {
715
printf("branch %d from j%d-j%d(%d): ", sp234, a2->id, a1->id, sp224);
716
} else {
717
printf("branch %d from j%d(%d): ", sp234, a2->id, sp224);
718
}
719
720
sp274 = a2;
721
sp26C = sp120[sp234];
722
func_80190168(sp20[sp234], sp274, sp26C, &sp24C);
723
do {
724
sp220 = func_8018FFE8(&sp20[0x20], &sp120[0x20], sp274, sp26C);
725
sp270 = sp120[0x20];
726
if (sp26C->unk1C0 & sp22C) {
727
break;
728
}
729
730
if (sp220 < 2) {
731
if (sp26C->flags & 0x1) {
732
sJointArrLen++;
733
sJointArr[sJointArrLen] = sp274;
734
sJointArrVecs[sJointArrLen].x = -sp24C.x;
735
sJointArrVecs[sJointArrLen].y = -sp24C.y;
736
sJointArrVecs[sJointArrLen].z = -sp24C.z;
737
738
sp26C->unk90.x += sp24C.x;
739
sp26C->unk90.y += sp24C.y;
740
sp26C->unk90.z += sp24C.z;
741
742
sp26C->unk90.x += sp240.x;
743
sp26C->unk90.y += sp240.y;
744
sp26C->unk90.z += sp240.z;
745
746
sp240.x = sp240.y = sp240.z = 0.0f;
747
break;
748
} else {
749
sp24C.x += sp240.x;
750
sp24C.y += sp240.y;
751
sp24C.z += sp240.z;
752
753
func_801903E8(sp26C, &sp240, sp24C.x, sp24C.y, sp24C.z);
754
}
755
756
if (sp220 == 1) {
757
func_80190168(sp20[0x20], sp26C, sp270, &sp24C);
758
}
759
}
760
761
if (sp220 > 1) {
762
func_80190574(a0 * 2, sp274, sp26C, sp24C.x, sp24C.y, sp24C.z);
763
break;
764
}
765
766
sp274 = sp26C;
767
sp26C = sp270;
768
} while (sp220);
769
printf("Exit");
770
// probably sp274(sp26C) because it would make sense to print
771
// the iterations of both of these loops.
772
printf(" %d(%d)", sp274->id, sp26C->id);
773
printf("R ");
774
printf("\n");
775
}
776
777
printf("\n\n");
778
}
779
780
/* 23F184 -> 23F1F0 */
781
void func_801909B4(void) {
782
struct ObjJoint *node;
783
784
D_801A82D0 = 0;
785
node = gGdJointList;
786
while (node != NULL) {
787
node->unk1C0 = 0;
788
node = node->nextjoint;
789
}
790
}
791
792
/* 23F1F0 -> 23F324; not called */
793
void func_80190A20(void) {
794
struct ObjJoint *j; // sp3c
795
UNUSED u32 pad38;
796
struct GdVec3f vec; // sp2C
797
struct ObjGroup *grp;
798
struct ListNode *link;
799
struct ObjBone *b;
800
801
j = gGdJointList;
802
while (j != NULL) {
803
if (j->flags & 0x40) {
804
grp = j->unk1C4;
805
link = grp->firstMember;
806
b = (struct ObjBone *) link->obj;
807
808
vec.z = b->unk40.x * 100.0f;
809
vec.y = b->unk40.y * 100.0f;
810
vec.x = b->unk40.z * 100.0f;
811
func_80190574(1, NULL, j, vec.z, vec.y, vec.x);
812
}
813
814
j = j->nextjoint;
815
}
816
}
817
818
/* 23F324 -> 23F638 */
819
void func_80190B54(struct ObjJoint *a0, struct ObjJoint *a1, struct GdVec3f *a2) // b0
820
{
821
struct GdVec3f spA4;
822
UNUSED struct GdVec3f pad98;
823
struct GdVec3f sp8C;
824
struct GdVec3f sp80;
825
f32 sp7C;
826
f32 sp78;
827
Mat4f sp38;
828
UNUSED u8 pad1C[0x1C];
829
830
if (a1 != NULL) {
831
spA4.x = a1->unk3C.x;
832
spA4.y = a1->unk3C.y;
833
spA4.z = a1->unk3C.z;
834
835
spA4.x -= a0->unk3C.x;
836
spA4.y -= a0->unk3C.y;
837
spA4.z -= a0->unk3C.z;
838
839
sp8C.x = spA4.x;
840
sp8C.y = spA4.y;
841
sp8C.z = spA4.z;
842
gd_normalize_vec3f(&sp8C);
843
844
sp7C = a1->unk228;
845
846
D_801BAAE0.x = spA4.x - (sp8C.x * sp7C);
847
D_801BAAE0.y = spA4.y - (sp8C.y * sp7C);
848
D_801BAAE0.z = spA4.z - (sp8C.z * sp7C);
849
850
sp78 = 5.4 / sp7C; //? 5.4f
851
D_801BAAD0.x *= sp78;
852
D_801BAAD0.y *= sp78;
853
D_801BAAD0.z *= sp78;
854
855
spA4.x *= sp78;
856
spA4.y *= sp78;
857
spA4.z *= sp78;
858
859
gd_cross_vec3f(&spA4, &D_801BAAD0, &sp80);
860
sp78 = gd_vec3f_magnitude(&sp80);
861
gd_normalize_vec3f(&sp80);
862
gd_create_rot_mat_angular(&sp38, &sp80, sp78);
863
gd_mult_mat4f(&a0->matE8, &sp38, &a0->matE8);
864
865
} else {
866
D_801BAAE0.x = a2->x;
867
D_801BAAE0.y = a2->y;
868
D_801BAAE0.z = a2->z;
869
}
870
871
a0->unk3C.x += D_801BAAE0.x;
872
a0->unk3C.y += D_801BAAE0.y;
873
a0->unk3C.z += D_801BAAE0.z;
874
875
D_801BAAD0.x = D_801BAAE0.x;
876
D_801BAAD0.y = D_801BAAE0.y;
877
D_801BAAD0.z = D_801BAAE0.z;
878
}
879
880
/* 23F638 -> 23F70C; not called */
881
void func_80190E68(struct GdObj *obj, f32 x, f32 y, f32 z) {
882
struct ObjJoint *sp44;
883
struct GdObj *sp40;
884
struct GdVec3f vec;
885
UNUSED u32 pad1C[6];
886
887
vec.x = x;
888
vec.y = y;
889
vec.z = z;
890
891
sp44 = NULL;
892
sp40 = obj;
893
while (sp40 != NULL) {
894
if (sp40->type != OBJ_TYPE_JOINTS) {
895
break;
896
}
897
898
func_80190B54(((struct ObjJoint *) sp40), sp44, &vec);
899
sp44 = ((struct ObjJoint *) sp40);
900
sp40 = ((struct ObjJoint *) sp40)->attachedToObj;
901
}
902
}
903
904
/* 23F70C -> 23F978 */
905
f32 func_80190F3C(struct ObjJoint *a0, f32 a1, f32 a2, f32 a3) {
906
struct ObjJoint *curj;
907
s32 i;
908
struct GdVec3f sp24;
909
910
sp24.x = a0->unk3C.x;
911
sp24.y = a0->unk3C.y;
912
sp24.z = a0->unk3C.z;
913
914
func_801909B4();
915
sJointArrLen = 0;
916
func_80190574(1, NULL, a0, a1, a2, a3);
917
918
for (i = 1; i <= sJointArrLen; i++) {
919
sJointArr2[i] = sJointArr[i];
920
sJointArr2Vecs[i].x = sJointArrVecs[i].x;
921
sJointArr2Vecs[i].y = sJointArrVecs[i].y;
922
sJointArr2Vecs[i].z = sJointArrVecs[i].z;
923
}
924
printf("Num return joints (pass 1): %d\n", i);
925
926
sJointArr2Len = sJointArrLen;
927
sJointArrLen = 0;
928
929
for (i = 1; i <= sJointArr2Len; i++) {
930
func_801909B4();
931
curj = sJointArr2[i];
932
func_80190574(1, NULL, curj, sJointArr2Vecs[i].x, sJointArr2Vecs[i].y, sJointArr2Vecs[i].z);
933
}
934
printf("Num return joints (pass 2): %d\n", i);
935
936
sp24.x -= a0->unk3C.x;
937
sp24.y -= a0->unk3C.y;
938
sp24.z -= a0->unk3C.z;
939
940
return gd_vec3f_magnitude(&sp24);
941
}
942
943
/* 23F978 -> 23F9F0 */
944
void func_801911A8(struct ObjJoint *j) {
945
j->unkCC.x = j->shapeOffset.x;
946
j->unkCC.y = j->shapeOffset.y;
947
j->unkCC.z = j->shapeOffset.z;
948
949
gd_rotate_and_translate_vec3f(&j->unkCC, &gGdSkinNet->mat128);
950
}
951
952
/* 23F9F0 -> 23FB90 */
953
void func_80191220(struct ObjJoint *j) {
954
j->unk48.x = j->initPos.x; // storing "attached offset"?
955
j->unk48.y = j->initPos.y;
956
j->unk48.z = j->initPos.z;
957
958
gd_mat4f_mult_vec3f(&j->unk48, &gGdSkinNet->mat128);
959
j->unk3C.x = j->unk48.x;
960
j->unk3C.y = j->unk48.y;
961
j->unk3C.z = j->unk48.z;
962
j->worldPos.x = gGdSkinNet->worldPos.x;
963
j->worldPos.y = gGdSkinNet->worldPos.y;
964
j->worldPos.z = gGdSkinNet->worldPos.z;
965
966
j->worldPos.x += j->unk3C.x;
967
j->worldPos.y += j->unk3C.y;
968
j->worldPos.z += j->unk3C.z;
969
j->unk1A8.x = j->unk1A8.y = j->unk1A8.z = 0.0f;
970
gGdCounter.ctr0++;
971
}
972
973
/* 23FB90 -> 23FBC0 */
974
void func_801913C0(struct ObjJoint *j) {
975
UNUSED u32 pad[4];
976
func_80181894(j);
977
}
978
979
/* 23FBC0 -> 23FCC8 */
980
void func_801913F0(struct ObjJoint *j) {
981
// hmm...
982
j->velocity.x = j->worldPos.x;
983
j->velocity.y = j->worldPos.y;
984
j->velocity.z = j->worldPos.z;
985
986
j->velocity.x -= j->unk30.x;
987
j->velocity.y -= j->unk30.y;
988
j->velocity.z -= j->unk30.z;
989
990
j->unk30.x = j->worldPos.x;
991
j->unk30.y = j->worldPos.y;
992
j->unk30.z = j->worldPos.z;
993
994
gd_copy_mat4f(&gGdSkinNet->mat128, &j->matE8);
995
}
996
997
/* 23FCC8 -> 23FCDC */
998
void stub_joints_2(UNUSED struct ObjJoint *j) {
999
}
1000
1001
/* 23FCDC -> 23FDD4; not called */
1002
void func_8019150C(Mat4f *a0, struct GdVec3f *a1) {
1003
struct GdVec3f sp1C;
1004
1005
sp1C.x = (*a0)[3][0] / 10.0; //? 10.0f
1006
sp1C.y = (*a0)[3][1] / 10.0; //? 10.0f
1007
sp1C.z = (*a0)[3][2] / 10.0; //? 10.0f
1008
1009
a1->x += sp1C.x;
1010
a1->y += sp1C.y;
1011
a1->z += sp1C.z;
1012
gd_mat4f_mult_vec3f(a1, a0);
1013
}
1014
1015
/* 23FDD4 -> 23FFF4 */
1016
void reset_joint(struct ObjJoint *j) {
1017
j->worldPos.x = j->initPos.x;
1018
j->worldPos.y = j->initPos.y;
1019
j->worldPos.z = j->initPos.z;
1020
1021
j->unk30.x = j->initPos.x;
1022
j->unk30.y = j->initPos.y;
1023
j->unk30.z = j->initPos.z;
1024
1025
j->unk3C.x = j->initPos.x;
1026
j->unk3C.y = j->initPos.y;
1027
j->unk3C.z = j->initPos.z;
1028
1029
j->velocity.x = j->velocity.y = j->velocity.z = 0.0f;
1030
j->unk84.x = j->unk84.y = j->unk84.z = 0.0f;
1031
j->unk90.x = j->unk90.y = j->unk90.z = 0.0f;
1032
j->unk1A8.x = j->unk1A8.y = j->unk1A8.z = 0.0f;
1033
1034
gd_set_identity_mat4(&j->mat168);
1035
gd_scale_mat4f_by_vec3f(&j->mat168, (struct GdVec3f *) &j->scale);
1036
gd_rot_mat_about_vec(&j->mat168, (struct GdVec3f *) &j->unk6C);
1037
gd_add_vec3f_to_mat4f_offset(&j->mat168, &j->attachOffset);
1038
gd_copy_mat4f(&j->mat168, &j->matE8);
1039
1040
gd_set_identity_mat4(&j->mat128);
1041
gd_add_vec3f_to_mat4f_offset(&j->mat128, &j->initPos);
1042
}
1043
1044
/* 23FFF4 -> 2400C4 */
1045
void func_80191824(struct ObjJoint *j) {
1046
UNUSED struct ObjNet *sp14;
1047
UNUSED u32 pad00[4];
1048
1049
sp14 = gGdSkinNet->unk1F0;
1050
if (j->flags & 0x1) {
1051
j->worldPos.x = gGdSkinNet->worldPos.x;
1052
j->worldPos.y = gGdSkinNet->worldPos.y;
1053
j->worldPos.z = gGdSkinNet->worldPos.z;
1054
1055
j->unk3C.x = gGdSkinNet->worldPos.x;
1056
j->unk3C.y = gGdSkinNet->worldPos.y;
1057
j->unk3C.z = gGdSkinNet->worldPos.z;
1058
}
1059
}
1060
1061
/* 2400C4 -> 2401EC; not called */
1062
void func_801918F4(struct ObjJoint *j) {
1063
f32 sp4;
1064
1065
j->velocity.x = j->unk3C.x;
1066
j->velocity.y = j->unk3C.y;
1067
j->velocity.z = j->unk3C.z;
1068
1069
j->velocity.x -= j->unk30.x;
1070
j->velocity.y -= j->unk30.y;
1071
j->velocity.z -= j->unk30.z;
1072
1073
j->unk30.x = j->unk3C.x;
1074
j->unk30.y = j->unk3C.y;
1075
j->unk30.z = j->unk3C.z;
1076
1077
sp4 = -4.0f;
1078
1079
if (!(j->flags & 0x41)) {
1080
j->velocity.y += sp4 * 0.2; //? 0.2f
1081
1082
j->unk3C.x += j->velocity.x;
1083
j->unk3C.y += j->velocity.y;
1084
j->unk3C.z += j->velocity.z;
1085
}
1086
}
1087
1088
/* 2401EC -> 2403C8; not called */
1089
void func_80191A1C(struct ObjBone *a0) {
1090
f32 sp3C;
1091
f32 sp38 = 0.0f;
1092
struct GdObj *argjoint;
1093
struct GdObj *tempjoint;
1094
struct GdVec3f sp24;
1095
struct GdVec3f sp18;
1096
1097
if (gGdTempBone == NULL) {
1098
gGdTempBone = a0;
1099
}
1100
sp3C = gd_dot_vec3f(&gGdTempBone->unk40, &a0->unk40);
1101
a0->unk118 = sp3C;
1102
1103
if ((sp3C -= sp38) < 0.0f) {
1104
tempjoint = gGdTempBone->unk10C->firstMember->obj;
1105
argjoint = a0->unk10C->firstMember->next->obj;
1106
set_cur_dynobj(argjoint);
1107
d_get_rel_pos(&sp24);
1108
set_cur_dynobj(tempjoint);
1109
d_get_rel_pos(&sp18);
1110
1111
sp24.x -= sp18.x;
1112
sp24.y -= sp18.y;
1113
sp24.z -= sp18.z;
1114
gd_normalize_vec3f(&sp24);
1115
1116
sp3C = -sp3C * 50.0; //? 50.0f
1117
if (!(((struct ObjJoint *) argjoint)->flags & 0x1)) {
1118
func_80190F3C((struct ObjJoint *) argjoint, sp24.x * sp3C, sp24.y * sp3C, sp24.z * sp3C);
1119
}
1120
}
1121
gGdTempBone = a0;
1122
}
1123
1124
/* 2403C8 -> 240530 */
1125
void func_80191BF8(struct ObjJoint *j) {
1126
f32 sp1C;
1127
f32 sp18 = -2.0f;
1128
1129
if (!(j->flags & 0x1)) {
1130
j->unk3C.y += sp18;
1131
}
1132
1133
if ((sp1C = j->unk3C.y - (D_801A8058 + 30.0f)) < 0.0f && j->velocity.y < 0.0f) {
1134
sp1C += j->velocity.y;
1135
sp1C *= 0.8; //? 0.8f
1136
func_80190F3C(j, -j->velocity.x * 0.7, -sp1C, -j->velocity.z * 0.7);
1137
}
1138
1139
func_80190F3C(j, 0.0f, 0.0f, 0.0f);
1140
}
1141
1142
/* 240530 -> 240624 */
1143
void func_80191D60(struct ObjJoint *j) {
1144
j->velocity.x += j->unk3C.x - j->worldPos.x;
1145
j->velocity.y += j->unk3C.y - j->worldPos.y;
1146
j->velocity.z += j->unk3C.z - j->worldPos.z;
1147
1148
j->velocity.x *= 0.9; //? 0.9f
1149
j->velocity.y *= 0.9; //? 0.9f
1150
j->velocity.z *= 0.9; //? 0.9f
1151
1152
j->worldPos.x += j->velocity.x;
1153
j->worldPos.y += j->velocity.y;
1154
j->worldPos.z += j->velocity.z;
1155
}
1156
1157
/* 240624 -> 240658 */
1158
void func_80191E54(struct ObjJoint *j) {
1159
j->unk3C.x = j->worldPos.x;
1160
j->unk3C.y = j->worldPos.y;
1161
j->unk3C.z = j->worldPos.z;
1162
}
1163
1164
/* 240658 -> 2406B8 */
1165
void func_80191E88(struct ObjGroup *grp) {
1166
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191BF8, grp);
1167
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191D60, grp);
1168
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191E54, grp);
1169
}
1170
1171
/* 2406B8 -> 2406E0; orig name: func_80191EE8 */
1172
void reset_joint_counts(void) {
1173
sJointCount = 0;
1174
sJointNotF1Count = 0;
1175
sBoneCount = 0;
1176
}
1177
1178