Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/goddard/skin.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 "gd_main.h"
9
#include "gd_math.h"
10
#include "gd_types.h"
11
#include "joints.h"
12
#include "macros.h"
13
#include "objects.h"
14
#include "particles.h"
15
#include "renderer.h"
16
#include "skin.h"
17
#include "skin_movement.h"
18
19
// bss
20
struct ObjNet *gGdSkinNet; // @ 801BAAF0
21
22
static s32 D_801BAAF4;
23
static s32 sNetCount; // @ 801BAAF8
24
25
/* 2406E0 -> 240894 */
26
void compute_net_bounding_box(struct ObjNet *net) {
27
reset_bounding_box();
28
if (net->unk1D0 != NULL) {
29
apply_to_obj_types_in_group(OBJ_TYPE_ALL, (applyproc_t) add_obj_pos_to_bounding_box, net->unk1D0);
30
}
31
if (net->unk1C8 != NULL) {
32
apply_to_obj_types_in_group(OBJ_TYPE_ALL, (applyproc_t) add_obj_pos_to_bounding_box, net->unk1C8);
33
}
34
gSomeBoundingBox.minX *= net->scale.x;
35
gSomeBoundingBox.maxX *= net->scale.x;
36
gSomeBoundingBox.minY *= net->scale.y;
37
gSomeBoundingBox.maxY *= net->scale.y;
38
gSomeBoundingBox.minZ *= net->scale.z;
39
gSomeBoundingBox.maxZ *= net->scale.z;
40
41
net->boundingBox.minX = gSomeBoundingBox.minX;
42
net->boundingBox.minY = gSomeBoundingBox.minY;
43
net->boundingBox.minZ = gSomeBoundingBox.minZ;
44
net->boundingBox.maxX = gSomeBoundingBox.maxX;
45
net->boundingBox.maxY = gSomeBoundingBox.maxY;
46
net->boundingBox.maxZ = gSomeBoundingBox.maxZ;
47
}
48
49
/* 240894 -> 240A64; orig name: func_801920C4 */
50
void reset_net(struct ObjNet *net) {
51
struct ObjGroup *grp;
52
53
printf("reset_net %d\n", net->id);
54
55
net->worldPos.x = net->initPos.x;
56
net->worldPos.y = net->initPos.y;
57
net->worldPos.z = net->initPos.z;
58
net->velocity.x = net->velocity.y = net->velocity.z = 0.0f;
59
net->torque.x = net->torque.y = net->torque.z = 0.0f;
60
61
compute_net_bounding_box(net);
62
gd_print_vec("net scale: ", &net->scale);
63
gd_print_bounding_box("net box: ", &net->boundingBox);
64
65
gGdSkinNet = net;
66
D_801BAAF4 = 0;
67
gd_set_identity_mat4(&net->mat168);
68
gd_set_identity_mat4(&net->matE8);
69
gd_rot_mat_about_vec(&net->matE8, &net->unk68); // set rot mtx to initial rotation?
70
gd_add_vec3f_to_mat4f_offset(&net->matE8, &net->worldPos); // set to initial position?
71
gd_copy_mat4f(&net->matE8, &net->mat128);
72
73
if ((grp = net->unk1C8) != NULL) {
74
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) reset_joint, grp);
75
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191220, grp);
76
apply_to_obj_types_in_group(OBJ_TYPE_BONES, (applyproc_t) func_8018FB58, grp);
77
apply_to_obj_types_in_group(OBJ_TYPE_BONES, (applyproc_t) func_8018FA68, grp);
78
}
79
}
80
81
/* 240A64 -> 240ACC */
82
void func_80192294(struct ObjNet *net) {
83
UNUSED s32 sp1C = 0;
84
85
if (net->attachedToObj == NULL) {
86
restart_timer("childpos");
87
sp1C = transform_child_objects_recursive(&net->header, NULL);
88
split_timer("childpos");
89
}
90
}
91
92
/* 240ACC -> 240B84 */
93
void func_801922FC(struct ObjNet *net) {
94
struct ObjGroup *group; // 24
95
UNUSED u32 pad18[2];
96
97
gGdSkinNet = net;
98
// TODO: netype constants?
99
if (net->netType == 4) {
100
if (net->shapePtr != NULL) {
101
D_801B9E38 = &net->mat128;
102
scale_verts(net->shapePtr->vtxGroup);
103
}
104
if ((group = net->unk1C8) != NULL) {
105
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) reset_joint_weights, group);
106
}
107
}
108
}
109
110
/* 240B84 -> 240CF8 */
111
struct ObjNet *make_net(UNUSED s32 a0, struct ObjShape *shapedata, struct ObjGroup *a2,
112
struct ObjGroup *a3, struct ObjGroup *a4) {
113
struct ObjNet *net;
114
115
net = (struct ObjNet *) make_object(OBJ_TYPE_NETS);
116
gd_set_identity_mat4(&net->mat128);
117
net->initPos.x = net->initPos.y = net->initPos.z = 0.0f;
118
net->id = ++sNetCount;
119
net->scale.x = net->scale.y = net->scale.z = 1.0f;
120
net->shapePtr = shapedata;
121
net->unk1C8 = a2;
122
net->unk1CC = a3;
123
net->unk1D0 = a4;
124
net->netType = 0;
125
net->ctrlType = 0;
126
net->unk21C = NULL;
127
net->unk3C = 1;
128
net->colourNum = 0;
129
net->skinGrp = NULL;
130
reset_net(net);
131
132
return net;
133
}
134
135
/* 240CF8 -> 240E74 */
136
void func_80192528(struct ObjNet *net) {
137
net->unusedForce.x = net->unusedForce.y = net->unusedForce.z = 0.0f;
138
net->collDisp.x = net->collDisp.y = net->collDisp.z = 0.0f;
139
net->collTorque.x = net->collTorque.y = net->collTorque.z = 0.0f;
140
net->unusedCollDispOff.x = net->unusedCollDispOff.y = net->unusedCollDispOff.z = 0.0f;
141
net->unusedCollMaxD = 0.0f;
142
143
gGdCounter.ctr0 = 0;
144
gGdCounter.ctr1 = 0;
145
D_801B9E18.x = 0.0f;
146
D_801B9E18.y = 0.0f;
147
D_801B9E18.z = 0.0f;
148
D_801B9E28.x = 0.0f;
149
D_801B9E28.y = 0.0f;
150
D_801B9E28.z = 0.0f;
151
D_801B9E34 = 0.0f;
152
153
if (net->flags & 0x1) {
154
net->velocity.y += -4.0; //? 4.0f
155
}
156
157
net->worldPos.x += net->velocity.x / 1.0f;
158
net->worldPos.y += net->velocity.y / 1.0f;
159
net->worldPos.z += net->velocity.z / 1.0f;
160
}
161
162
/* 240E74 -> 2412A0 */
163
void collision_something_801926A4(struct ObjNet *net) {
164
if (gGdCounter.ctr1 != 0) {
165
if (D_801B9E34 != 0.0f) {
166
D_801B9E28.x /= D_801B9E34;
167
D_801B9E28.y /= D_801B9E34;
168
D_801B9E28.z /= D_801B9E34;
169
}
170
171
D_801B9E28.x *= 1.0 / gGdCounter.ctr1; // !1.0f
172
D_801B9E28.y *= 1.0 / gGdCounter.ctr1; // !1.0f
173
D_801B9E28.z *= 1.0 / gGdCounter.ctr1; // !1.0f
174
D_801B9E18.x *= 1.0 / gGdCounter.ctr1; // !1.0f
175
D_801B9E18.y *= 1.0 / gGdCounter.ctr1; // !1.0f
176
D_801B9E18.z *= 1.0 / gGdCounter.ctr1; // !1.0f
177
178
func_8017E584(gGdSkinNet, &D_801B9E28, &D_801B9E18);
179
func_8017E838(gGdSkinNet, &D_801B9E28, &D_801B9E18);
180
}
181
182
net->torque.x += net->collTorque.x;
183
net->torque.y += net->collTorque.y;
184
net->torque.z += net->collTorque.z;
185
net->collDisp.x *= 1.0; // 1.0f;
186
net->collDisp.y *= 1.0; // 1.0f;
187
net->collDisp.z *= 1.0; // 1.0f;
188
net->velocity.x += net->collDisp.x;
189
net->velocity.y += net->collDisp.y;
190
net->velocity.z += net->collDisp.z;
191
net->worldPos.x += net->collDisp.x;
192
net->worldPos.y += net->collDisp.y;
193
net->worldPos.z += net->collDisp.z;
194
func_8017E9EC(net);
195
196
net->torque.x *= 0.98; //? 0.98f
197
net->torque.z *= 0.98; //? 0.98f
198
net->torque.y *= 0.9; //? 0.9f
199
}
200
201
/* 2412A0 -> 24142C; not called */
202
void func_80192AD0(struct ObjNet *net) {
203
UNUSED u32 pad64;
204
struct ObjGroup *sp60;
205
UNUSED u32 pad20[0x10];
206
UNUSED u32 sp1C;
207
struct ObjNet *sp18;
208
209
if ((sp60 = net->unk1C8) == NULL) {
210
return;
211
}
212
213
sp18 = net->unk1F0;
214
net->worldPos.x = net->unk1F4.x;
215
net->worldPos.y = net->unk1F4.y;
216
net->worldPos.z = net->unk1F4.z;
217
gd_rotate_and_translate_vec3f(&net->worldPos, &sp18->mat128);
218
219
net->worldPos.x += net->unk1F0->worldPos.x;
220
net->worldPos.y += net->unk1F0->worldPos.y;
221
net->worldPos.z += net->unk1F0->worldPos.z;
222
net->unk200.x = 0.0f;
223
net->unk200.y = 10.0f;
224
net->unk200.z = -4.0f;
225
gd_rotate_and_translate_vec3f(&net->unk200, &sp18->mat128);
226
227
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191824, sp60);
228
func_80191E88(sp60);
229
apply_to_obj_types_in_group(OBJ_TYPE_BONES, (applyproc_t) func_8018F328, net->unk20C);
230
}
231
232
/* 24142C -> 24149C; orig name: func_80192C5C */
233
void move_bonesnet(struct ObjNet *net) {
234
struct ObjGroup *sp24;
235
UNUSED u32 pad18[3];
236
237
imin("move_bonesnet");
238
gd_set_identity_mat4(&D_801B9DC8);
239
if ((sp24 = net->unk1C8) != NULL) {
240
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_801913C0, sp24);
241
}
242
imout();
243
}
244
245
/* 24149C -> 241768 */
246
void func_80192CCC(struct ObjNet *net) {
247
Mat4f sp38;
248
UNUSED struct GdControl *ctrl; // 34
249
struct ObjGroup *group; // 30
250
struct GdVec3f sp24;
251
252
ctrl = &gGdCtrl;
253
if (gGdCtrl.unk2C != NULL) {
254
menu_cb_reset_positions();
255
}
256
gd_set_identity_mat4(&D_801B9DC8);
257
258
if (gGdCtrl.unk30 != NULL) {
259
sp24.x = net->mat128[0][0];
260
sp24.y = net->mat128[0][1];
261
sp24.z = net->mat128[0][2];
262
gd_create_rot_mat_angular(&sp38, &sp24, 4.0f);
263
gd_mult_mat4f(&sp38, &D_801B9DC8, &D_801B9DC8);
264
net->torque.x = net->torque.y = net->torque.z = 0.0f;
265
}
266
267
if (gGdCtrl.unk28 != NULL) {
268
sp24.x = net->mat128[0][0];
269
sp24.y = net->mat128[0][1];
270
sp24.z = net->mat128[0][2];
271
gd_create_rot_mat_angular(&sp38, &sp24, -4.0f);
272
gd_mult_mat4f(&sp38, &D_801B9DC8, &D_801B9DC8);
273
net->torque.x = net->torque.y = net->torque.z = 0.0f;
274
}
275
276
if (gGdCtrl.newStartPress) {
277
return;
278
} // start was pressed
279
280
switch (net->ctrlType) {
281
case 2:
282
break;
283
}
284
285
func_80192528(net);
286
if ((group = net->unk1C8) != NULL) {
287
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191220, group);
288
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_801913F0, group);
289
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) stub_joints_2, group);
290
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_801911A8, group);
291
}
292
293
collision_something_801926A4(net);
294
gd_mult_mat4f(&net->mat128, &D_801B9DC8, &net->mat128);
295
if (group != NULL) {
296
apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_801913C0, group);
297
apply_to_obj_types_in_group(OBJ_TYPE_BONES, (applyproc_t) func_8018FA68, group);
298
}
299
}
300
301
/* 241768 -> 241AB4; orig name: func_80192F98 */
302
void convert_gd_verts_to_Vn(struct ObjGroup *grp) {
303
UNUSED u8 pad[0x40 - 0x2c];
304
Vtx *vn; // 28
305
u8 nx, ny, nz; // 24, 25, 26
306
UNUSED u32 pad20;
307
register struct VtxLink *vtxlink; // a1
308
#ifndef GBI_FLOATS
309
register s16 *vnPos; // a2
310
#endif
311
register s16 x; // a3
312
register s16 y; // t0
313
register s16 z; // t1
314
register struct ObjVertex *vtx; // t2
315
register struct ListNode *link; // t3
316
struct GdObj *obj; // sp4
317
318
for (link = grp->firstMember; link != NULL; link = link->next) {
319
obj = link->obj;
320
vtx = (struct ObjVertex *) obj;
321
x = (s16) vtx->pos.x;
322
y = (s16) vtx->pos.y;
323
z = (s16) vtx->pos.z;
324
325
nx = (u8)(vtx->normal.x * 255.0f);
326
ny = (u8)(vtx->normal.y * 255.0f);
327
nz = (u8)(vtx->normal.z * 255.0f);
328
329
for (vtxlink = vtx->gbiVerts; vtxlink != NULL; vtxlink = vtxlink->prev) {
330
#ifndef GBI_FLOATS
331
vnPos = vtxlink->data->n.ob;
332
vn = vtxlink->data;
333
*vnPos++ = x;
334
*vnPos++ = y;
335
*vnPos++ = z;
336
#else
337
vn = vtxlink->data;
338
vn->n.ob[0] = x;
339
vn->n.ob[1] = y;
340
vn->n.ob[2] = z;
341
#endif
342
vn->n.n[0] = nx;
343
vn->n.n[1] = ny;
344
vn->n.n[2] = nz;
345
}
346
}
347
}
348
349
/* 241AB4 -> 241BCC; orig name: func_801932E4 */
350
void convert_gd_verts_to_Vtx(struct ObjGroup *grp) {
351
UNUSED u32 pad24[6];
352
register struct VtxLink *vtxlink; // a1
353
#ifndef GBI_FLOATS
354
register s16 *vtxcoords; // a2
355
#endif
356
register s16 x; // a3
357
register s16 y; // t0
358
register s16 z; // t1
359
register struct ObjVertex *vtx; // t2
360
register struct ListNode *link; // t3
361
struct GdObj *obj; // sp4
362
363
for (link = grp->firstMember; link != NULL; link = link->next) {
364
obj = link->obj;
365
vtx = (struct ObjVertex *) obj;
366
x = (s16) vtx->pos.x;
367
y = (s16) vtx->pos.y;
368
z = (s16) vtx->pos.z;
369
370
for (vtxlink = vtx->gbiVerts; vtxlink != NULL; vtxlink = vtxlink->prev) {
371
#ifndef GBI_FLOATS
372
vtxcoords = vtxlink->data->v.ob;
373
vtxcoords[0] = x;
374
vtxcoords[1] = y;
375
vtxcoords[2] = z;
376
#else
377
vtxlink->data->v.ob[0] = x;
378
vtxlink->data->v.ob[1] = y;
379
vtxlink->data->v.ob[2] = z;
380
#endif
381
}
382
}
383
}
384
385
/* 241BCC -> 241CA0; orig name: Proc801933FC */
386
void convert_net_verts(struct ObjNet *net) {
387
if (net->shapePtr != NULL) {
388
if (net->shapePtr->unk30) {
389
convert_gd_verts_to_Vn(net->shapePtr->vtxGroup);
390
}
391
}
392
393
switch (net->netType) {
394
case 2:
395
if (net->shapePtr != NULL) {
396
convert_gd_verts_to_Vtx(net->shapePtr->scaledVtxGroup);
397
}
398
break;
399
}
400
}
401
402
/* 241CA0 -> 241D6C */
403
static void move_joints_in_net(struct ObjNet *net) {
404
struct ObjGroup *grp; // 2c
405
register struct ListNode *link; // s0
406
struct GdObj *obj; // 24
407
408
if ((grp = net->unk1C8) != NULL) {
409
for (link = grp->firstMember; link != NULL; link = link->next) {
410
obj = link->obj;
411
switch (obj->type) {
412
case OBJ_TYPE_JOINTS:
413
if (((struct ObjJoint *) obj)->updateFunc != NULL) {
414
(*((struct ObjJoint *) obj)->updateFunc)((struct ObjJoint *) obj);
415
}
416
break;
417
default:;
418
}
419
}
420
}
421
}
422
423
/* 241D6C -> 241E94; orig name: func_8019359C */
424
void move_net(struct ObjNet *net) {
425
gGdSkinNet = net;
426
427
switch (net->netType) {
428
case 1:
429
break;
430
case 7:
431
func_80192CCC(net);
432
break;
433
case 4:
434
restart_timer("move_bones");
435
move_bonesnet(net);
436
split_timer("move_bones");
437
break;
438
case 2:
439
restart_timer("move_skin");
440
move_skin(net);
441
split_timer("move_skin");
442
break;
443
case 3:
444
move_joints_in_net(net);
445
break;
446
case 5:
447
func_801823A0(net);
448
break;
449
case 6:
450
break;
451
default:
452
fatal_printf("move_net(%d(%d)): Undefined net type", net->id, net->netType);
453
}
454
}
455
456
/* 241E94 -> 241F0C; orig name: func_801936C4 */
457
void move_nets(struct ObjGroup *group) {
458
imin("move_nets");
459
restart_timer("move_nets");
460
apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) func_80192294, group);
461
apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) move_net, group);
462
split_timer("move_nets");
463
imout();
464
}
465
466
/* 241F0C -> 242018 */
467
void func_8019373C(struct ObjNet *net) {
468
register struct ListNode *link;
469
struct ObjVertex *vtx;
470
471
switch (net->netType) {
472
case 2:
473
if (net->shapePtr != NULL) {
474
net->shapePtr->scaledVtxGroup = make_group(0);
475
for (link = net->shapePtr->vtxGroup->firstMember; link != NULL; link = link->next) {
476
vtx = (struct ObjVertex *) link->obj;
477
if (vtx->scaleFactor != 1.0) {
478
addto_group(net->shapePtr->scaledVtxGroup, &vtx->header);
479
}
480
}
481
}
482
break;
483
}
484
}
485
486
/* 242018 -> 24208C */
487
void func_80193848(struct ObjGroup *group) {
488
apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) reset_net, group);
489
apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) func_80192294, group);
490
apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) func_801922FC, group);
491
apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) func_8019373C, group);
492
}
493
494
/* 24208C -> 2422E0; not called; orig name: func_801938BC */
495
void gd_print_net(struct ObjNet *net) {
496
gd_printf("Flags:%x\n", net->flags);
497
gd_print_vec("World:", &net->worldPos);
498
gd_print_vec("Force:", &net->unusedForce);
499
gd_print_vec("Vel:", &net->velocity);
500
gd_print_vec("Rot:", &net->rotation);
501
gd_print_vec("CollDisp:", &net->collDisp);
502
gd_print_vec("CollTorque:", &net->collTorque);
503
gd_print_vec("CollTorqueL:", &net->unusedCollTorqueL);
504
gd_print_vec("CollTorqueD:", &net->unusedCollTorqueD);
505
gd_print_vec("Torque:", &net->torque);
506
gd_print_vec("CofG:", &net->centerOfGravity);
507
gd_print_bounding_box("BoundBox:", &net->boundingBox);
508
gd_print_vec("CollDispOff:", &net->unusedCollDispOff);
509
gd_printf("CollMaxD: %f\n", net->unusedCollMaxD);
510
gd_printf("MaxRadius: %f\n", net->maxRadius);
511
gd_print_mtx("Matrix:", &net->mat128);
512
if (net->shapePtr != NULL) {
513
gd_printf("ShapePtr: %x (%s)\n", (u32) (uintptr_t) net->shapePtr, net->shapePtr->name);
514
} else {
515
gd_printf("ShapePtr: NULL\n");
516
}
517
gd_print_vec("Scale:", &net->scale);
518
gd_printf("Mass: %f\n", net->unusedMass);
519
gd_printf("NumModes: %d\n", net->numModes);
520
gd_printf("NodeGroup: %x\n", (u32) (uintptr_t) net->unk1C8);
521
gd_printf("PlaneGroup: %x\n", (u32) (uintptr_t) net->unk1CC);
522
gd_printf("VertexGroup: %x\n", (u32) (uintptr_t) net->unk1D0);
523
}
524
525
/* 2422E0 -> 2422F8; orig name: func_80193B10 */
526
void reset_net_count(void) {
527
sNetCount = 0;
528
}
529
530