link m_collision_obj

This commit is contained in:
Prakxo
2023-09-04 17:59:55 +02:00
parent 1d9045ad10
commit e5f349ee9c
6 changed files with 1172 additions and 86 deletions
+5
View File
@@ -32,6 +32,11 @@ m_banti.c:
.bss: [0x8125A830, 0x8125AC80]
m_cockroach.c:
.text: [0x80385430, 0x80385A80]
m_collision_obj.c:
.text: [0x80394518, 0x80395B24]
.rodata: [0x80641CE8, 0x80641D20]
.data: [0x80651208,0x806512D8]
.bss: [0x812663D0, 0x81266400]
m_common_data.c:
.text: [0x80395B24, 0x80395BE8]
m_controller.c:
+127 -9
View File
@@ -2,7 +2,7 @@
#define M_COLLISION_OBJ_H
#include "types.h"
#include "m_actor.h"
#include "m_actor_type.h"
#include "sys_math3d.h"
#include "m_play_h.h"
@@ -18,6 +18,15 @@ enum collision_type {
ClObj_TYPE_NUM
};
enum weight{
MASS_IMMOVABLE,
MASS_HEAVY,
MASS_NORMAL
};
#define MASSTYPE_IMMOVABLE 0XFF
#define MASSTYPE_HEAVY 0XFE
typedef struct collision_obj_s {
ACTOR* owner_actor; // actor which owns this collision object
ACTOR* collided_actor; // actor which the owner collided with or NULL
@@ -64,6 +73,55 @@ typedef struct collision_obj_pipe_data_s {
ClObjPipeAttrData_c attribute_data;
} ClObjPipeData_c;
typedef struct collision_check_tris_element_attr_data_s{
xyz_t vtx[3];
}ClObjTrisElemAttrData_c;
typedef struct collision_check_tris_element_data_s{
ClObjElemData_c element;
ClObjTrisElemAttrData_c data;
}ClObjTrisElemData_c;
typedef struct collision_check_tris_element_s{
Math3D_triangle_c tri;
xyz_t t;
}ClObjTrisElemAttr_c;
typedef struct collision_tris_elem_s{
ClObjElem_c element;
ClObjTrisElemAttr_c attribute;
}ClObjTrisElem_c;
typedef struct collision_tris_s {
ClObj_c collision_obj;
int count;
ClObjTrisElem_c* elements;
} ClObjTris_c;
typedef struct ClObjTris_Init {
ClObjData_c data;
int count;
ClObjTrisElemData_c* elem_data;
} ClObjTrisData_c;
typedef struct collision_obj_joint_sphere_elem_attribute_s{
Math3D_sphere_c s1;
Math3D_sphere_c s2;
f32 unk8;
u8 unk14;
}ClObjJntSphElemAttr_c;
typedef struct collision_joint_sphere_elem_s{
ClObjElem_c element;
ClObjJntSphElemAttr_c attribute;
}ClObjJntSphElem_c;
typedef struct collision_joint_sphere_s {
ClObj_c collision_obj;
int count;
ClObjJntSphElem_c* elements;
}ClObjJntSph_c;
#define Cl_COLLIDER_NUM 50
typedef struct collision_check_s {
u16 flags;
@@ -95,14 +153,74 @@ typedef struct status_data_s {
u8 weight;
} StatusData_c;
extern void ClObjPipe_ct(GAME_PLAY* play, ClObjPipe_c* pipe);
extern void ClObjPipe_dt(GAME_PLAY* play, ClObjPipe_c* pipe);
extern void ClObjPipe_set5(GAME_PLAY* play, ClObjPipe_c* pipe, ACTOR* owner, ClObjPipeData_c* data);
extern void CollisionCheck_Uty_ActorWorldPosSetPipeC(ACTOR* actor, ClObjPipe_c* col_pipe);
extern int CollisionCheck_setOC(GAME_PLAY* play, CollisionCheck_c* collision_check, ClObj_c* col_obj);
extern void CollisionCheck_Status_set3(Status_c* status, StatusData_c* data);
extern void CollisionCheck_Status_ct(Status_c* status);
extern void CollisionCheck_Status_Clear(Status_c* status);
typedef struct mco_work_s {
int count;
ClObj_c* colliders[10];
} McoWork;
extern McoWork mco_work;
typedef void (*CollisionOCFunction)(GAME_PLAY*, CollisionCheck_c*, ClObj_c*,ClObj_c*);
typedef int (*CollisionOCClear)(GAME_PLAY*, ClObj_c*);
typedef int (*CollisionClearFunction)(GAME_PLAY*, ClObj_c*);
extern void CollisionCheck_workTrisElemCenter(ClObjTrisElem_c *, xyz_t *);
extern int ClObj_ct(GAME_PLAY *, ClObj_c *);
extern int ClObj_dt(GAME_PLAY *, ClObj_c *);
extern int ClObj_set4(GAME_PLAY *, ClObj_c *, ACTOR *, ClObjData_c *);
extern void ClObj_OCClear(GAME_PLAY *, ClObj_c *);
extern int ClObjElem_ct(ClObjElem_c *);
extern int ClObjElem_set(ClObjElem_c *, ClObjElemData_c *);
extern void ClObjElem_OCClear(GAME_PLAY *, ClObjElem_c *);
extern int ClObjJntSphElem_OCClear(GAME_PLAY *, ClObjJntSphElem_c *);
extern int ClObjJntSph_OCClear(GAME_PLAY *, ClObj_c *);
extern int ClObjPipeAttr_ct(GAME_PLAY *, ClObjPipeAttr_c *);
extern int ClObjPipeAttr_dt(GAME_PLAY *, ClObjPipeAttr_c *);
extern int ClObjPipeAttr_set(GAME_PLAY *, ClObjPipeAttr_c *, ClObjPipeAttr_c *);
extern int ClObjPipe_ct(GAME_PLAY *, ClObjPipe_c *);
extern int ClObjPipe_dt(GAME_PLAY *, ClObjPipe_c *);
extern int ClObjPipe_set5(GAME_PLAY *, ClObjPipe_c *, ACTOR *, ClObjPipeData_c *);
extern int ClObjPipe_OCClear(GAME_PLAY *, ClObj_c *);
extern int ClObjTrisElemAttr_ct(GAME_PLAY *, ClObjTrisElemAttr_c *);
extern int ClObjTrisElemAttr_dt(GAME_PLAY *, ClObjTrisElemAttr_c *);
extern int ClObjTrisElemAttr_set(GAME_PLAY *, ClObjTrisElemAttr_c *, ClObjTrisElemAttrData_c *);
extern int ClObjTrisElem_ct(GAME_PLAY *, ClObjTrisElem_c *);
extern int ClObjTrisElem_dt(GAME_PLAY *, ClObjTrisElem_c *);
extern int ClObjTrisElem_set(GAME_PLAY *, ClObjTrisElem_c *, ClObjTrisElemData_c *);
extern int ClObjTrisElem_OCClear(GAME_PLAY *, ClObjTrisElem_c *);
extern int ClObjTris_ct(GAME_PLAY *, ClObjTris_c *);
extern int ClObjTris_dt_nzf(GAME_PLAY *, ClObjTris_c *);
extern int ClObjTris_set5_nzm(GAME_PLAY *, ClObjTris_c *, ACTOR *, ClObjTrisData_c *, ClObjTrisElem_c *);
extern int ClObjTris_OCClear(GAME_PLAY *, ClObj_c *);
extern void CollisionCheck_ct(GAME_PLAY *, CollisionCheck_c *);
extern void CollisionCheck_dt(GAME_PLAY *, CollisionCheck_c *);
extern void CollisionCheck_clear(GAME_PLAY *, CollisionCheck_c *);
extern int CollisionCheck_setOC(GAME_PLAY *, CollisionCheck_c *, ClObj_c *);
extern int get_type(u8);
extern void CollisionCheck_setOC_HitInfo(ClObj_c *, ClObjElem_c *, xyz_t *, ClObj_c *, ClObjElem_c *, xyz_t *, f32);
extern void CollisionCheck_OC_JntSph_Vs_JntSph(GAME_PLAY *, CollisionCheck_c *, ClObj_c *, ClObj_c *);
extern void CollisionCheck_OC_JntSph_Vs_Pipe(GAME_PLAY *, CollisionCheck_c *, ClObj_c *, ClObj_c *);
extern void CollisionCheck_OC_Pipe_Vs_JntSph(GAME_PLAY *, CollisionCheck_c *, ClObj_c *, ClObj_c *);
extern void CollisionCheck_OC_Pipe_Vs_Pipe(GAME_PLAY *, CollisionCheck_c *, ClObj_c *, ClObj_c *);
extern int CollisionCheck_Check1ClObjNoOC(ClObj_c *);
extern int CollisionCheck_Check2ClObjNoOC(ClObj_c *, ClObj_c *);
extern void CollisionCheck_OC(GAME_PLAY *, CollisionCheck_c *);
extern void CollisionCheck_setOCC_HitInfo(GAME_PLAY *, ClObj_c *, ClObjTrisElem_c *, xyz_t *, ClObj_c *, ClObjElem_c *, xyz_t *, xyz_t *);
extern void CollisionCheck_OCC_Tris_Vs_JntSph(GAME_PLAY *, CollisionCheck_c *, ClObjTris_c *, ClObjJntSph_c *);
extern void CollisionCheck_OCC_Tris_Vs_Pipe(GAME_PLAY *, CollisionCheck_c *, ClObjTris_c *, ClObjPipe_c *);
extern int CollisionCheck_Check1ClObjNoOCC(ClObj_c *);
extern void CollisionCheck_OCC(GAME_PLAY *, CollisionCheck_c *);
extern int ClObjTrisElem_OCCClear(GAME_PLAY *, ClObjTrisElem_c *);
extern int ClObj_OCCClear(GAME_PLAY *, ClObj_c *);
extern int ClObjTris_OCCClear(GAME_PLAY *, ClObj_c *);
extern int CollisionCheck_setOCC(GAME_PLAY *, CollisionCheck_c *, ClObj_c *);
extern void CollisionCheck_Status_ct(Status_c *);
extern void CollisionCheck_Status_Clear(Status_c *);
extern void CollisionCheck_Status_set3(Status_c *, StatusData_c *);
extern int CollisionCheck_Uty_ActorWorldPosSetPipeC(ACTOR *, ClObjPipe_c *);
#ifdef __cplusplus
}
+33 -76
View File
@@ -1,5 +1,4 @@
# PowerPC Register Constants
# General Purpose Registers (GPRs)
/* Register name macros */
.set r0, 0
.set r1, 1
.set r2, 2
@@ -32,8 +31,6 @@
.set r29, 29
.set r30, 30
.set r31, 31
# Floating Point Registers (FPRs)
.set f0, 0
.set f1, 1
.set f2, 2
@@ -66,8 +63,6 @@
.set f29, 29
.set f30, 30
.set f31, 31
# Graphics Quantization Registers (GQRs)
.set qr0, 0
.set qr1, 1
.set qr2, 2
@@ -76,73 +71,35 @@
.set qr5, 5
.set qr6, 6
.set qr7, 7
# Special Purpose Registers (SPRs)
.set XER, 1
.set LR, 8
.set CTR, 9
.set DSISR, 18
.set DAR, 19
.set DEC, 22
.set SDR1, 25
.set SRR0, 26
.set SRR1, 27
.set SPRG0, 272
.set SPRG1, 273
.set SPRG2, 274
.set SPRG3, 275
.set EAR, 282
.set PVR, 287
.set IBAT0U, 528
.set IBAT0L, 529
.set IBAT1U, 530
.set IBAT1L, 531
.set IBAT2U, 532
.set IBAT2L, 533
.set IBAT3U, 534
.set IBAT3L, 535
.set DBAT0U, 536
.set DBAT0L, 537
.set DBAT1U, 538
.set DBAT1L, 539
.set DBAT2U, 540
.set DBAT2L, 541
.set DBAT3U, 542
.set DBAT3L, 543
.set GQR0, 912
.set GQR1, 913
.set GQR2, 914
.set GQR3, 915
.set GQR4, 916
.set GQR5, 917
.set GQR6, 918
.set GQR7, 919
.set HID2, 920
.set WPAR, 921
.set DMA_U, 922
.set DMA_L, 923
.set UMMCR0, 936
.set UPMC1, 937
.set UPMC2, 938
.set USIA, 939
.set UMMCR1, 940
.set UPMC3, 941
.set UPMC4, 942
.set USDA, 943
.set MMCR0, 952
.set PMC1, 953
.set PMC2, 954
.set SIA, 955
.set MMCR1, 956
.set PMC3, 957
.set PMC4, 958
.set SDA, 959
.set HID0, 1008
.set HID1, 1009
.set IABR, 1010
.set DABR, 1013
.set L2CR, 1017
.set ICTC, 1019
.set THRM1, 1020
.set THRM2, 1021
.set THRM3, 1022
.set cr0lt, 0
.set cr0gt, 1
.set cr0eq, 2
.set cr0un, 3
.set cr1lt, 4
.set cr1gt, 5
.set cr1eq, 6
.set cr1un, 7
.set cr2lt, 8
.set cr2gt, 9
.set cr2eq, 10
.set cr2un, 11
.set cr3lt, 12
.set cr3gt, 13
.set cr3eq, 14
.set cr3un, 15
.set cr4lt, 16
.set cr4gt, 17
.set cr4eq, 18
.set cr4un, 19
.set cr5lt, 20
.set cr5gt, 21
.set cr5eq, 22
.set cr5un, 23
.set cr6lt, 24
.set cr6gt, 25
.set cr6eq, 26
.set cr6un, 27
.set cr7lt, 28
.set cr7gt, 29
.set cr7eq, 30
.set cr7un, 31
+22
View File
@@ -15,10 +15,32 @@ typedef struct math_3d_pipe_s {
s_xyz center;
} Math3D_pipe_c;
typedef struct math_3d_sphere_s{
s_xyz center;
s16 radius;
}Math3D_sphere_c;
typedef struct math_3d_plane_s {
xyz_t normal;
f32 originDist;
} Math3D_plane_c; // size = 0x10
typedef struct math_3d_triangle_s {
xyz_t vtx[3];
Math3D_plane_c plane;
} Math3D_triangle_c; // size = 0x34
extern f32 Math3DVecLength(xyz_t* vec);
extern void sMath_RotateX(xyz_t* pos, f32 rad);
extern void sMath_RotateY(xyz_t* pos, f32 rad);
extern void sMath_RotateZ(xyz_t* pos, f32 rad);
extern void Math3DPlane(xyz_t* va, xyz_t* vb, xyz_t* vc, f32* nox, f32* noy, f32* noz, f32* odist);
extern int Math3D_sphereCrossSphere_cl(Math3D_sphere_c* a, Math3D_sphere_c* b, f32* in);
extern int Math3D_sphereVsPipe_cl(Math3D_sphere_c* s, Math3D_pipe_c* c, f32* in);
extern int Math3D_pipeVsPipe_cl(Math3D_pipe_c* a, Math3D_pipe_c* b , f32* d);
extern int Math3D_sphereCrossTriangle3_cp(Math3D_sphere_c* s, Math3D_triangle_c* tri, xyz_t* ip);
extern int Math3D_pipeCrossTriangle_cp(Math3D_pipe_c* c,Math3D_triangle_c* tri, xyz_t* in);
extern xyz_t ZeroVec;
extern s_xyz ZeroSVec;
+984
View File
@@ -0,0 +1,984 @@
#include "m_collision_obj.h"
#include "m_actor.h"
McoWork mco_work;
void CollisionCheck_workTrisElemCenter(ClObjTrisElem_c* tri, xyz_t* vec)
{
vec->x = (tri->attribute.tri.vtx[0].x + tri->attribute.tri.vtx[1].x + tri->attribute.tri.vtx[2].x) * (1.0f / 3.0f);
vec->y = (tri->attribute.tri.vtx[0].y + tri->attribute.tri.vtx[1].y +
tri->attribute.tri.vtx[2].y) *
(1.0f / 3.0f);
vec->z = (tri->attribute.tri.vtx[0].z + tri->attribute.tri.vtx[1].z +
tri->attribute.tri.vtx[2].z) *
(1.0f / 3.0f);
}
int ClObj_ct(GAME_PLAY* play, ClObj_c* cl)
{
static ClObj_c clobj_default = {NULL, NULL, 0, 0, 3};
*cl = clobj_default;
return 1;
}
int ClObj_dt(GAME_PLAY*, ClObj_c*)
{
return 1;
}
int ClObj_set4(GAME_PLAY*, ClObj_c* cl, ACTOR* actor, ClObjData_c* data)
{
cl->owner_actor = actor;
cl->collision_flags0 = data->collision_flags0;
cl->collision_flags1 = data->collision_flags1;
cl->collision_type = data->type;
return 1;
}
void ClObj_OCClear(GAME_PLAY *, ClObj_c* cl)
{
cl->collision_flags0 &= ~2;
cl->collided_actor = NULL;
cl->collision_flags1 &= 0xFE;
}
int ClObjElem_ct(ClObjElem_c* elem)
{
elem->flags = 0;
return 1;
}
int ClObjElem_set(ClObjElem_c* elem, ClObjElemData_c* data)
{
elem->flags = data->flags;
return 1;
}
void ClObjElem_OCClear(GAME_PLAY*, ClObjElem_c* elem)
{
elem->flags &= ~2;
}
int ClObjJntSphElem_OCClear(GAME_PLAY* play, ClObjJntSphElem_c* col)
{
ClObjElem_OCClear(play, &col->element);
return 1;
}
int ClObjJntSph_OCClear(GAME_PLAY* play, ClObj_c* cl)
{
ClObjJntSph_c* jntsph = (ClObjJntSph_c*)cl;
ClObjJntSphElem_c* elem;
ClObj_OCClear(play, &jntsph->collision_obj);
for (elem = jntsph->elements; elem < &jntsph->elements[jntsph->count]; elem++)
{
ClObjJntSphElem_OCClear(play, elem);
}
return 1;
}
int ClObjPipeAttr_ct(GAME_PLAY* play, ClObjPipeAttr_c* attribute)
{
static ClObjPipeAttr_c default_pipe_attr = {0, 0, 0};
*attribute = default_pipe_attr;
return 1;
}
int ClObjPipeAttr_dt(GAME_PLAY*, ClObjPipeAttr_c*)
{
return 1;
}
int ClObjPipeAttr_set(GAME_PLAY* play, ClObjPipeAttr_c* dst, ClObjPipeAttr_c* src)
{
*dst = *src;
return 1;
}
int ClObjPipe_ct(GAME_PLAY* play, ClObjPipe_c* pipe)
{
ClObj_ct(play, &pipe->collision_obj);
ClObjElem_ct(&pipe->element);
ClObjPipeAttr_ct(play, &pipe->attribute);
return 1;
}
int ClObjPipe_dt(GAME_PLAY* play, ClObjPipe_c* pipe)
{
ClObj_dt(play, &pipe->collision_obj);
ClObjPipeAttr_dt(play, &pipe->attribute);
return 1;
}
int ClObjPipe_set5(GAME_PLAY* play, ClObjPipe_c* pipe, ACTOR* owner, ClObjPipeData_c* data)
{
ClObj_set4(play, &pipe->collision_obj, owner, &data->collision_data);
ClObjElem_set(&pipe->element, &data->element_data);
ClObjPipeAttr_set(play, &pipe->attribute, (ClObjPipeAttr_c *)&data->attribute_data);
return 1;
}
int ClObjPipe_OCClear(GAME_PLAY* play, ClObj_c* cl)
{
ClObjPipe_c* pipe = (ClObjPipe_c *)cl;
ClObj_OCClear(play, &pipe->collision_obj);
ClObjElem_OCClear(play, &pipe->element);
return 1;
}
int ClObjTrisElemAttr_ct(GAME_PLAY *play, ClObjTrisElemAttr_c *tris)
{
static ClObjTrisElemAttr_c default_clobjtriselem_attr = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
*tris = default_clobjtriselem_attr;
return 1;
}
int ClObjTrisElemAttr_dt(GAME_PLAY *play, ClObjTrisElemAttr_c *tris)
{
return 1;
}
int ClObjTrisElemAttr_set(GAME_PLAY* play, ClObjTrisElemAttr_c* tris, ClObjTrisElemAttrData_c* data)
{
xyz_t* dst;
xyz_t* src;
f32 nox, noy, noz, odist;
for (dst = tris->tri.vtx, src = data->vtx; dst < &tris->tri.vtx[3]; dst++, src++)
{
*dst = *src;
}
Math3DPlane(&data->vtx[0], &data->vtx[1], &data->vtx[2], &nox, &noy, &noz, &odist);
tris->tri.plane.normal.x = nox;
tris->tri.plane.normal.y = noy;
tris->tri.plane.normal.z = noz;
tris->tri.plane.originDist = odist;
return 1;
}
int ClObjTrisElem_ct(GAME_PLAY* play, ClObjTrisElem_c* tris)
{
ClObjElem_ct(&tris->element);
ClObjTrisElemAttr_ct(play, &tris->attribute);
return 1;
}
int ClObjTrisElem_dt(GAME_PLAY* play, ClObjTrisElem_c* tris)
{
ClObjTrisElemAttr_dt(play, &tris->attribute);
return 1;
}
int ClObjTrisElem_set(GAME_PLAY* play, ClObjTrisElem_c* tris, ClObjTrisElemData_c* data)
{
ClObjElem_set(&tris->element, &data->element);
ClObjTrisElemAttr_set(play, &tris->attribute, &data->data);
return 1;
}
int ClObjTrisElem_OCClear(GAME_PLAY* play, ClObjTrisElem_c* tris)
{
ClObjElem_OCClear(play, &tris->element);
return 1;
}
int ClObjTris_ct(GAME_PLAY* play, ClObjTris_c* tris)
{
ClObj_ct(play, &tris->collision_obj);
tris->count = 0;
tris->elements = NULL;
return 1;
}
int ClObjTris_dt_nzf(GAME_PLAY *play, ClObjTris_c *tris)
{
ClObjTrisElem_c *element;
ClObj_dt(play, &tris->collision_obj);
for (element = tris->elements; element < &tris->elements[tris->count]; element++)
{
ClObjTrisElem_dt(play, element);
}
tris->count = 0;
tris->elements = NULL;
return 1;
}
int ClObjTris_set5_nzm(GAME_PLAY* play, ClObjTris_c* tris, ACTOR* actor, ClObjTrisData_c* data,
ClObjTrisElem_c *elem)
{
ClObjTrisElem_c* element;
ClObjTrisElemData_c* elementData;
ClObj_set4(play, &tris->collision_obj, actor, &data->data);
tris->count = data->count;
tris->elements = elem;
for (element = tris->elements, elementData = data->elem_data;
element < &tris->elements[tris->count]; element++, elementData++)
{
ClObjTrisElem_ct(play, element);
ClObjTrisElem_set(play, element, elementData);
}
return 1;
}
int ClObjTris_OCClear(GAME_PLAY* play, ClObj_c* cl)
{
ClObjTris_c* tris = (ClObjTris_c*)cl;
ClObjTrisElem_c* element;
ClObj_OCClear(play, &tris->collision_obj);
for (element = tris->elements; element < &tris->elements[tris->count]; element++)
{
ClObjTrisElem_OCClear(play, element);
}
return 1;
}
void CollisionCheck_ct(GAME_PLAY* play, CollisionCheck_c* col)
{
col->flags = 0;
CollisionCheck_clear(play, col);
}
void CollisionCheck_dt(GAME_PLAY* play, CollisionCheck_c* col)
{
}
void CollisionCheck_clear(GAME_PLAY* play, CollisionCheck_c* col)
{
ClObj_c** clp;
if (col->flags & 1)
{
return;
}
col->collider_num = 0;
for (clp = col->collider_table; clp < &col->collider_table[Cl_COLLIDER_NUM]; clp++)
{
*clp = NULL;
}
mco_work.count = 0;
for (clp = mco_work.colliders; clp < &mco_work.colliders[10]; clp++)
{
*clp = NULL;
}
}
CollisionClearFunction OCClearFunctionTable[ClObj_TYPE_NUM] = {
ClObjJntSph_OCClear,ClObjPipe_OCClear,ClObjTris_OCClear
};
CollisionOCFunction oc_collision_function[ClObj_TYPE_NUM][ClObj_TYPE_NUM] = {
{CollisionCheck_OC_JntSph_Vs_JntSph, CollisionCheck_OC_JntSph_Vs_Pipe, NULL},
{CollisionCheck_OC_Pipe_Vs_JntSph, CollisionCheck_OC_Pipe_Vs_Pipe, NULL},
{NULL, NULL, NULL}};
CollisionOCFunction occ_collision_function[ClObj_TYPE_NUM][ClObj_TYPE_NUM] = {
{NULL, NULL, NULL},
{NULL, NULL, NULL},
{(CollisionOCFunction)CollisionCheck_OCC_Tris_Vs_JntSph, (CollisionOCFunction)CollisionCheck_OCC_Tris_Vs_Pipe, NULL}
};
CollisionOCClear OCCClearFunctionTable[ClObj_TYPE_NUM] = {
NULL, NULL, ClObjTris_OCCClear};
int CollisionCheck_setOC(GAME_PLAY* play, CollisionCheck_c* col, ClObj_c* cl)
{
int ret;
if (_Game_play_isPause(play) == 1)
{
return -1;
}
else
{
OCClearFunctionTable[cl->collision_type](play, cl);
if ((cl->owner_actor != NULL) && (cl->owner_actor->mv_proc == NULL))
{
return -1;
}
if (col->collider_num >= Cl_COLLIDER_NUM)
{
return -1;
}
if (col->flags & 1)
{
return -1;
}
ret = col->collider_num;
col->collider_table[col->collider_num] = cl;
col->collider_num++;
}
return ret;
}
int get_type(u8 type)
{
if (type == MASSTYPE_IMMOVABLE)
{
return MASS_IMMOVABLE;
}
if (type == MASSTYPE_HEAVY)
{
return MASS_HEAVY;
}
return MASS_NORMAL;
}
void CollisionCheck_setOC_HitInfo(ClObj_c* col1, ClObjElem_c* colelem1, xyz_t* pos1, ClObj_c* col2,
ClObjElem_c* colelem2, xyz_t* pos2, f32 diff)
{
ACTOR* actor1;
ACTOR* actor2;
int type1;
int type2;
f32 xdiff;
f32 zdiff;
f32 xzdist;
f32 weight1;
f32 weight2;
f32 minweight;
f32 comweight;
f32 coldis1;
f32 coldis2;
actor1 = col1->owner_actor;
actor2 = col2->owner_actor;
col1->collided_actor = actor2;
col1->collision_flags0 |= 2;
colelem1->flags |= 2;
if (col2->collision_flags1 & 8)
{
col1->collision_flags1 |= 1;
}
col2->collided_actor = actor1;
col2->collision_flags0 |= 2;
colelem2->flags |= 2;
if (col1->collision_flags1 & 8)
{
col2->collision_flags1 |= 1;
}
if ((actor1 == NULL) || (actor2 == NULL))
{
return;
}
if ((col1->collision_flags0 & 4) || (col2->collision_flags0 & 4))
{
return;
}
type1 = get_type(actor1->status_data.weight);
type2 = get_type(actor2->status_data.weight);
weight1 = actor1->status_data.weight;
weight2 = actor2->status_data.weight;
comweight = weight1 + weight2;
if (fabsf(comweight) < 0.008f)
{
weight1 = weight2 = 1.0f;
comweight = 2.0f;
}
minweight = 1.0f / comweight;
xdiff = pos2->x - pos1->x;
zdiff = pos2->z - pos1->z;
xzdist = sqrtf((xdiff * xdiff) + (zdiff * zdiff));
if (type1 == 0)
{
if (type2 == 0)
{
return;
}
coldis1 = 0.0f;
coldis2 = 1.0f;
}
else if (type1 == 1)
{
if (type2 == 0)
{
coldis1 = 1.0f;
coldis2 = 0.0f;
}
else if (type2 == 1)
{
coldis1 = 0.5f;
coldis2 = 0.5f;
}
else
{
coldis1 = 0.0f;
coldis2 = 1.0f;
}
}
else
{
if (type2 == 2)
{
coldis1 = weight2 * minweight;
coldis2 = weight1 * minweight;
}
else
{
coldis1 = 1.0f;
coldis2 = 0.0f;
}
}
if (col1->collision_flags0 & 0x40)
{
coldis1 = 0.0f;
coldis2 = 1.0f;
actor2->speed = 0.0f;
}
else if (col2->collision_flags0 & 0x40)
{
coldis1 = 1.0f;
coldis2 = 0.0f;
actor1->speed = 0.0f;
}
if (!(fabsf(xzdist) < 0.008f))
{
xdiff *= diff / xzdist;
zdiff *= diff / xzdist;
actor1->status_data.collision_vec.x += -xdiff * coldis1;
actor1->status_data.collision_vec.z += -zdiff * coldis1;
actor2->status_data.collision_vec.x += xdiff * coldis2;
actor2->status_data.collision_vec.z += zdiff * coldis2;
}
else if (diff != 0)
{
actor1->status_data.collision_vec.x += -diff * coldis1;
actor2->status_data.collision_vec.x += diff * coldis2;
}
else
{
actor1->status_data.collision_vec.x -= coldis1;
actor2->status_data.collision_vec.x += coldis2;
}
}
void CollisionCheck_OC_JntSph_Vs_JntSph(GAME_PLAY* play, CollisionCheck_c* check, ClObj_c* col1,
ClObj_c* col2)
{
ClObjJntSph_c* jntsph1 = (ClObjJntSph_c*)col1;
ClObjJntSph_c* jntsph2 = (ClObjJntSph_c*)col2;
ClObjJntSphElem_c* elem1;
ClObjJntSphElem_c* elem2;
if ((jntsph1->count <= 0) || (jntsph1->elements == NULL) || (jntsph2->count <= 0) || (jntsph2->elements == NULL))
{
return;
}
for (elem1 = jntsph1->elements; elem1 < &jntsph1->elements[jntsph1->count]; elem1++)
{
if ((elem1->element.flags & 1))
{
for (elem2 = jntsph2->elements; elem2 < &jntsph2->elements[jntsph2->count]; elem2++)
{
f32 in;
if ((elem2->element.flags & 1))
{
if (Math3D_sphereCrossSphere_cl(&elem1->attribute.s2, &elem2->attribute.s2, &in) == 1)
{
xyz_t pos1;
xyz_t pos2;
xyz_t_move_s_xyz(&pos1, &elem1->attribute.s2.center);
xyz_t_move_s_xyz(&pos2, &elem2->attribute.s2.center);
CollisionCheck_setOC_HitInfo(&jntsph1->collision_obj, &elem1->element, &pos1,
&jntsph2->collision_obj, &elem2->element, &pos2, in);
}
}
}
}
}
}
void CollisionCheck_OC_JntSph_Vs_Pipe(GAME_PLAY* play, CollisionCheck_c* check, ClObj_c* col1,
ClObj_c* col2)
{
ClObjJntSph_c* jntsph = (ClObjJntSph_c*)col1;
ClObjPipe_c* pipe = (ClObjPipe_c*)col2;
ClObjJntSphElem_c* elem;
f32 in;
xyz_t sphpos;
xyz_t pipepos;
if ((jntsph->count > 0) && (jntsph->elements) != NULL)
{
if (!(jntsph->collision_obj.collision_flags0 & 1) || !(pipe->collision_obj.collision_flags0 & 1) ||
!(pipe->element.flags & 1))
{
return;
}
for (elem = jntsph->elements; elem < &jntsph->elements[jntsph->count]; elem++)
{
if (!(elem->element.flags & 1))
{
continue;
}
if (Math3D_sphereVsPipe_cl(&elem->attribute.s2, &pipe->attribute.pipe, &in) == 1)
{
xyz_t_move_s_xyz(&sphpos, &elem->attribute.s2.center);
xyz_t_move_s_xyz(&pipepos, &pipe->attribute.pipe.center);
CollisionCheck_setOC_HitInfo(&jntsph->collision_obj, &elem->element, &sphpos,
&pipe->collision_obj, &pipe->element, &pipepos, in);
}
}
}
}
void CollisionCheck_OC_Pipe_Vs_JntSph(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObj_c* col1,
ClObj_c* col2)
{
CollisionCheck_OC_JntSph_Vs_Pipe(play, colcheck, col2, col1);
}
void CollisionCheck_OC_Pipe_Vs_Pipe(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObj_c* col1,
ClObj_c* col2)
{
ClObjPipe_c* pipe1 = (ClObjPipe_c*)col1;
ClObjPipe_c* pipe2 = (ClObjPipe_c*)col2;
f32 in;
xyz_t pipepos1;
xyz_t pipepos2;
if (!(pipe1->collision_obj.collision_flags0 & 1) || !(pipe2->collision_obj.collision_flags0 & 1) || !(pipe1->element.flags & 1) || !(pipe2->element.flags & 1))
{
return;
}
if (Math3D_pipeVsPipe_cl(&pipe1->attribute.pipe, &pipe2->attribute.pipe, &in) != 1)
{
return;
}
xyz_t_move_s_xyz(&pipepos1, &pipe1->attribute.pipe.center);
xyz_t_move_s_xyz(&pipepos2, &pipe2->attribute.pipe.center);
CollisionCheck_setOC_HitInfo(&pipe1->collision_obj, &pipe1->element, &pipepos1,
&pipe2->collision_obj, &pipe2->element, &pipepos2, in);
}
int CollisionCheck_Check1ClObjNoOC(ClObj_c* col)
{
return col->collision_flags0 & 1 ^ 1;
}
int CollisionCheck_Check2ClObjNoOC(ClObj_c* col1, ClObj_c* col2)
{
if (!(col1->collision_flags0 & col2->collision_flags1 & 0x38) ||
!(col1->collision_flags1 & col2->collision_flags0 & 0x38))
{
return 1;
}
if (col1->owner_actor == col2->owner_actor)
{
return 1;
}
return 0;
}
void CollisionCheck_OC(GAME_PLAY* play, CollisionCheck_c* colcheck)
{
ClObj_c** col1p;
ClObj_c** col2p;
CollisionOCFunction current;
for (col1p = colcheck->collider_table; col1p < &colcheck->collider_table[colcheck->collider_num]; col1p++)
{
if (((*col1p) == NULL) || (CollisionCheck_Check1ClObjNoOC(*col1p) == 1))
{
continue;
}
for (col2p = col1p + 1; col2p < &colcheck->collider_table[colcheck->collider_num]; col2p++)
{
if ((*col2p == NULL) || (CollisionCheck_Check1ClObjNoOC(*col2p) == 1) ||
(CollisionCheck_Check2ClObjNoOC(*col1p, *col2p) == 1))
{
continue;
}
current = oc_collision_function[(*col1p)->collision_type][(*col2p)->collision_type];
if (current == NULL)
{
continue;
}
current(play, colcheck, *col1p, *col2p);
}
}
CollisionCheck_OCC(play, colcheck);
}
void CollisionCheck_setOCC_HitInfo(GAME_PLAY* play, ClObj_c* col1, ClObjTrisElem_c* elem1, xyz_t* pos1,
ClObj_c* col2, ClObjElem_c* elem2, xyz_t* pos2, xyz_t* pos3)
{
col1->collided_actor = col2->owner_actor;
col1->collision_flags1 |= 4;
elem1->attribute.t.x = pos3->x;
elem1->attribute.t.y = pos3->y;
elem1->attribute.t.z = pos3->z;
}
void CollisionCheck_OCC_Tris_Vs_JntSph(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObjTris_c* tris,
ClObjJntSph_c* jntsph)
{
ClObjTrisElem_c* triselem;
ClObjJntSphElem_c* jntsphelem;
xyz_t pos;
xyz_t sphpos;
xyz_t trispos;
if ((tris->count <= 0) || (tris->elements == NULL) ||
(jntsph->count <= 0) || (jntsph->elements == NULL))
{
return;
}
for (jntsphelem = jntsph->elements; jntsphelem < &jntsph->elements[jntsph->count]; jntsphelem++)
{
if ((jntsphelem->element.flags & 1))
{
for (triselem = tris->elements; triselem < &tris->elements[tris->count]; triselem++)
{
if (Math3D_sphereCrossTriangle3_cp(&jntsphelem->attribute.s2, &triselem->attribute.tri, &pos) != 0)
{
xyz_t_move_s_xyz(&sphpos, &jntsphelem->attribute.s2.center);
CollisionCheck_workTrisElemCenter(triselem, &trispos);
CollisionCheck_setOCC_HitInfo(play, &tris->collision_obj, triselem, &trispos, &jntsph->collision_obj, &jntsphelem->element,
&sphpos, &pos);
}
}
}
}
}
void CollisionCheck_OCC_Tris_Vs_Pipe(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObjTris_c* tris, ClObjPipe_c* pipe)
{
ClObjTrisElem_c* triselem;
xyz_t pos;
xyz_t pipepos;
xyz_t trispos;
if ((pipe->attribute.pipe.radius > 0) && (pipe->attribute.pipe.height > 0) && (pipe->element.flags & 1))
{
if ((tris->count <= 0) || (tris->elements == NULL))
{
return;
}
for (triselem = tris->elements; triselem < &tris->elements[tris->count]; triselem++)
{
if (Math3D_pipeCrossTriangle_cp(&pipe->attribute.pipe, &triselem->attribute.tri, &pos) != 0)
{
CollisionCheck_workTrisElemCenter(triselem, &trispos);
xyz_t_move_s_xyz(&pipepos, &pipe->attribute.pipe.center);
CollisionCheck_setOCC_HitInfo(play, &tris->collision_obj, triselem, &trispos, &pipe->collision_obj, &pipe->element, &pipepos, &pos);
break;
}
}
}
}
int CollisionCheck_Check1ClObjNoOCC(ClObj_c* col)
{
return col->collision_flags1 >> 1 & 1 ^ 1;
}
void CollisionCheck_OCC(GAME_PLAY* play, CollisionCheck_c* colcheck)
{
ClObj_c** col1p;
ClObj_c** col2p;
CollisionOCFunction current;
if (mco_work.count == 0)
{
return;
}
for (col1p = mco_work.colliders; col1p < &mco_work.colliders[mco_work.count]; col1p++)
{
if (((*col1p) == NULL) || (CollisionCheck_Check1ClObjNoOCC(*col1p) == 1))
{
continue;
}
for (col2p = colcheck->collider_table; col2p < &colcheck->collider_table[colcheck->collider_num]; col2p++)
{
if ((*col2p) == NULL)
{
continue;
}
if ((*col1p)->owner_actor == (*col2p)->owner_actor)
{
continue;
}
current = occ_collision_function[(*col1p)->collision_type][(*col2p)->collision_type];
if (current == NULL)
{
continue;
}
current(play, colcheck, *col1p, *col2p);
}
}
}
int ClObjTrisElem_OCCClear(GAME_PLAY* play, ClObjTrisElem_c* triselem)
{
triselem->attribute.t.x = 0.0f;
triselem->attribute.t.y = 0.0f;
triselem->attribute.t.z = 0.0f;
return 1;
}
int ClObj_OCCClear(GAME_PLAY* play, ClObj_c* col)
{
col->collided_actor = NULL;
col->collision_flags1 &= ~4;
}
int ClObjTris_OCCClear(GAME_PLAY* play, ClObj_c* col)
{
ClObjTris_c* tris = (ClObjTris_c*)col;
ClObjTrisElem_c* triselem;
ClObj_OCCClear(play, &tris->collision_obj);
for (triselem = tris->elements; triselem < &tris->elements[tris->count]; triselem++)
{
ClObjTrisElem_OCCClear(play, triselem);
}
return 1;
}
int CollisionCheck_setOCC(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObj_c* col)
{
int ret;
if (_Game_play_isPause(play) == 1)
{
return -1;
}
if ((col->collision_type == 0) || (col->collision_type == 1))
{
return -1;
}
OCCClearFunctionTable[col->collision_type](play, col);
if ((col->owner_actor != NULL) && (col->owner_actor->mv_proc == NULL))
{
return -1;
}
if (mco_work.count >= 10)
{
return -1;
}
if (colcheck->flags & 1)
{
return -1;
}
ret = mco_work.count;
mco_work.colliders[mco_work.count] = col;
mco_work.count++;
return ret;
}
void CollisionCheck_Status_ct(Status_c* status)
{
static Status_c status_org = {{0.0f, 0.0f, 0.0f}, 10, 10, 0, 50, 8, 0, 0, 0};
*status = status_org;
}
void CollisionCheck_Status_Clear(Status_c* status)
{
status->damage = 0;
status->damage_effect = 0;
status->at_hit_effect = 0;
status->ac_hit_effect = 0;
status->collision_vec.z = 0.0f;
status->collision_vec.y = 0.0f;
status->collision_vec.x = 0.0f;
}
void CollisionCheck_Status_set3(Status_c* status, StatusData_c* data)
{
status->hp = data->health;
status->radius = data->radius;
status->height = data->height;
status->offset = data->offset;
status->weight = data->weight;
}
int CollisionCheck_Uty_ActorWorldPosSetPipeC(ACTOR* actor, ClObjPipe_c* pipe)
{
pipe->attribute.pipe.center.x = actor->world.position.x;
pipe->attribute.pipe.center.y = actor->world.position.y;
pipe->attribute.pipe.center.z = actor->world.position.z;
}