Awfully complicated camera collision bits (#54)
* Awfully complicated camera collision bits
This commit is contained in:
parent
a8f34c5815
commit
3244bdbd55
|
|
@ -372,7 +372,10 @@ void BrMatrix34TApplyP(br_vector3* A, br_vector3* B, br_matrix34* C) {
|
|||
// IDA: void __cdecl BrMatrix34TApplyV(br_vector3 *A, br_vector3 *B, br_matrix34 *C)
|
||||
void BrMatrix34TApplyV(br_vector3* A, br_vector3* B, br_matrix34* C) {
|
||||
LOG_TRACE("(%p, %p, %p)", A, B, C);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
A->v[0] = BR_MAC3(B->v[0], C(0, 0), B->v[1], C(0, 1), B->v[2], C(0, 2));
|
||||
A->v[1] = BR_MAC3(B->v[0], C(1, 0), B->v[1], C(1, 1), B->v[2], C(1, 2));
|
||||
A->v[2] = BR_MAC3(B->v[0], C(2, 0), B->v[1], C(2, 1), B->v[2], C(2, 2));
|
||||
}
|
||||
|
||||
// IDA: void __cdecl BrMatrix34Pre(br_matrix34 *mat, br_matrix34 *A)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,20 @@ br_actor* BrActorAdd(br_actor* parent, br_actor* a) {
|
|||
br_actor* BrActorRemove(br_actor* a) {
|
||||
br_actor* ac;
|
||||
LOG_TRACE("(%p)", a);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
br_actor* ac2; //Added ?
|
||||
|
||||
BrSimpleRemove((br_simple_node*)a);
|
||||
a->parent = NULL;
|
||||
a->depth = 0;
|
||||
|
||||
for (ac2 = a->children; ac2; ac2 = ac2->next) {
|
||||
ac2->depth = 1;
|
||||
for (ac = ac2->children; ac; ac = ac->next) {
|
||||
RenumberActor(ac, 2);
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl BrActorRelink(br_actor *parent, br_actor *a)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#define BR_SIMPLEHEAD(l) (void*)(((br_simple_list*)(l))->head)
|
||||
#define BR_SIMPLENEXT(n) (void*)(((br_simple_node*)(n))->next)
|
||||
#define BR_FOR_SIMPLELIST(list, ptr) for ((ptr) = BR_SIMPLEHEAD(list); (ptr); (ptr) = BR_SIMPLENEXT(ptr))
|
||||
#define BR_SIMPLEREMOVE(n) ((void*)BrSimpleRemove((br_simple_node*)(n)))
|
||||
|
||||
#define V_X 0
|
||||
#define V_Y 1
|
||||
|
|
|
|||
|
|
@ -2796,7 +2796,6 @@ typedef struct v11group {
|
|||
void* stored;
|
||||
v11face* faces;
|
||||
br_colour* face_colours;
|
||||
br_material* face_colours_material; // Jeff added to avoid 64 bit issues trying to pack br_material* into br_colour
|
||||
br_uint_16* face_user;
|
||||
fmt_vertex* vertices;
|
||||
br_colour* vertex_colours;
|
||||
|
|
@ -2804,6 +2803,8 @@ typedef struct v11group {
|
|||
br_uint_16 nfaces;
|
||||
br_uint_16 nvertices;
|
||||
br_uint_16 nedges;
|
||||
|
||||
br_material* face_colours_material; // Added to avoid 64 bit issues trying to pack br_material* into br_colour. eek ;)
|
||||
} v11group;
|
||||
|
||||
typedef struct v11model {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ void BrMatrix34Identity(br_matrix34* mat);
|
|||
void BrMatrix34Pre(br_matrix34* mat, br_matrix34* A);
|
||||
void BrMatrix34ApplyV(br_vector3* A, br_vector3* B, br_matrix34* C);
|
||||
br_scalar BrMatrix34Inverse(br_matrix34* B, br_matrix34* A);
|
||||
void BrMatrix34LPInverse(br_matrix34* A, br_matrix34* B);
|
||||
void BrMatrix34ApplyP(br_vector3* A, br_vector3* B, br_matrix34* C);
|
||||
void BrMatrix34Scale(br_matrix34* mat, br_scalar sx, br_scalar sy, br_scalar sz);
|
||||
void BrMatrix34PostTranslate(br_matrix34* mat, br_scalar x, br_scalar y, br_scalar z);
|
||||
|
|
@ -71,6 +72,7 @@ void BrMatrix34PostScale(br_matrix34* mat, br_scalar sx, br_scalar sy, br_scalar
|
|||
void BrMatrix34PreTransform(br_matrix34* mat, br_transform* xform);
|
||||
void BrMatrix34PostTransform(br_matrix34* mat, br_transform* xform);
|
||||
void BrMatrix34PreRotateX(br_matrix34* mat, br_angle rx);
|
||||
void BrMatrix34TApplyV(br_vector3* A, br_vector3* B, br_matrix34* C);
|
||||
|
||||
// BrMem
|
||||
void BrMemFree(void* block);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,23 @@ void XZToColumnXZ(tU8* pColumn_x, tU8* pColumn_z, br_scalar pX, br_scalar pZ, tT
|
|||
br_scalar x;
|
||||
br_scalar z;
|
||||
LOG_TRACE("(%p, %p, %f, %f, %p)", pColumn_x, pColumn_z, pX, pZ, pTrack_spec);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
x = (pX - pTrack_spec->origin_x) / pTrack_spec->column_size_x;
|
||||
z = (pZ - pTrack_spec->origin_z) / pTrack_spec->column_size_z;
|
||||
if (x < 0.0) {
|
||||
x = 0.0;
|
||||
}
|
||||
if (pTrack_spec->ncolumns_x <= x) {
|
||||
x = pTrack_spec->ncolumns_x - 1.0;
|
||||
}
|
||||
if (z < 0.0) {
|
||||
z = 0.0;
|
||||
}
|
||||
if (pTrack_spec->ncolumns_z <= z) {
|
||||
z = pTrack_spec->ncolumns_z - 1.0;
|
||||
}
|
||||
*pColumn_x = x;
|
||||
*pColumn_z = z;
|
||||
}
|
||||
|
||||
// IDA: void __usercall StripBlendedFaces(br_actor *pActor@<EAX>, br_model *pModel@<EDX>)
|
||||
|
|
|
|||
|
|
@ -1988,8 +1988,196 @@ int CollideCamera2(br_vector3* car_pos, br_vector3* cam_pos, br_vector3* old_cam
|
|||
tFace_ref face_list[3];
|
||||
LOG_TRACE("(%p, %p, %p, %d)", car_pos, cam_pos, old_camera_pos, manual_move);
|
||||
|
||||
SILENT_STUB();
|
||||
return 0;
|
||||
hither = ((br_camera*)gCamera->type_data)->hither_z * 3.0;
|
||||
gCamera_has_collided = 0;
|
||||
for (i = 0; i < 1; i++) {
|
||||
tv.v[0] = cam_pos->v[0] - car_pos->v[0];
|
||||
tv.v[1] = cam_pos->v[1] - car_pos->v[1];
|
||||
tv.v[2] = cam_pos->v[2] - car_pos->v[2];
|
||||
dist = sqrt(tv.v[1] * tv.v[1] + tv.v[2] * tv.v[2] + tv.v[0] * tv.v[0]);
|
||||
tv.v[0] = tv.v[0] * 1.2;
|
||||
tv.v[1] = tv.v[1] * 1.2;
|
||||
tv.v[2] = tv.v[2] * 1.2;
|
||||
FindFace(car_pos, &tv, &a, &ts, &material);
|
||||
if (ts <= 1.0) {
|
||||
gCamera_has_collided = 1;
|
||||
if (a.v[1] * tv.v[1] + a.v[2] * tv.v[2] + a.v[0] * tv.v[0] > 0.0) {
|
||||
a.v[0] = -a.v[0];
|
||||
a.v[1] = -a.v[1];
|
||||
a.v[2] = -a.v[2];
|
||||
}
|
||||
if (gCamera_mode == 1 && !manual_move) {
|
||||
tv2.v[0] = car_pos->v[0] - old_camera_pos->v[0];
|
||||
tv2.v[1] = car_pos->v[1] - old_camera_pos->v[1];
|
||||
tv2.v[2] = car_pos->v[2] - old_camera_pos->v[2];
|
||||
FindFace(old_camera_pos, &tv2, &b, &ts2, &material);
|
||||
if (ts2 > 1.0) {
|
||||
*cam_pos = *old_camera_pos;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
tv.v[0] = tv.v[0] * ts;
|
||||
tv.v[1] = tv.v[1] * ts;
|
||||
tv.v[2] = tv.v[2] * ts;
|
||||
tv2.v[0] = a.v[0] * hither;
|
||||
tv2.v[1] = a.v[1] * hither;
|
||||
tv2.v[2] = a.v[2] * hither;
|
||||
tv.v[0] = tv2.v[0] + tv.v[0];
|
||||
tv.v[1] = tv2.v[1] + tv.v[1];
|
||||
tv.v[2] = tv2.v[2] + tv.v[2];
|
||||
dist = sqrt(tv.v[1] * tv.v[1] + tv.v[2] * tv.v[2] + tv.v[0] * tv.v[0]);
|
||||
cam_pos->v[0] = car_pos->v[0] + tv.v[0];
|
||||
cam_pos->v[1] = car_pos->v[1] + tv.v[1];
|
||||
cam_pos->v[2] = car_pos->v[2] + tv.v[2];
|
||||
if (gMin_camera_car_distance > dist && !i && a.v[1] > -0.7) {
|
||||
tv2.v[0] = -a.v[1] * a.v[0];
|
||||
tv2.v[1] = -a.v[1] * a.v[1];
|
||||
tv2.v[2] = -a.v[1] * a.v[2];
|
||||
tv2.v[1] = tv2.v[1] + 1.0;
|
||||
if (gProgram_state.current_car.car_master_actor->t.t.mat.m[1][1] < 0.0) {
|
||||
tv2.v[0] = -tv2.v[0];
|
||||
tv2.v[1] = -tv2.v[1];
|
||||
tv2.v[2] = -tv2.v[2];
|
||||
}
|
||||
d = tv2.v[1] * tv2.v[1] + tv2.v[2] * tv2.v[2] + tv2.v[0] * tv2.v[0];
|
||||
l = tv2.v[1] * tv.v[1] + tv2.v[2] * tv.v[2] + tv2.v[0] * tv.v[0];
|
||||
alpha = tv.v[1] * tv.v[1]
|
||||
+ tv.v[2] * tv.v[2]
|
||||
+ tv.v[0] * tv.v[0]
|
||||
- gMin_camera_car_distance * gMin_camera_car_distance;
|
||||
ts2 = l * l - alpha * d * 4.0;
|
||||
if (alpha >= 0 && d != 0.0) {
|
||||
sa = (sqrt(ts2) - l) / (d * 2.0);
|
||||
tv2.v[0] = tv2.v[0] * sa;
|
||||
tv2.v[1] = tv2.v[1] * sa;
|
||||
tv2.v[2] = tv2.v[2] * sa;
|
||||
FindFace(cam_pos, &tv2, &a, &ts, &material);
|
||||
if (ts < 1.0) {
|
||||
tv2.v[0] = tv2.v[0] * ts;
|
||||
tv2.v[1] = tv2.v[1] * ts;
|
||||
tv2.v[2] = tv2.v[2] * ts;
|
||||
}
|
||||
b.v[0] = tv.v[0];
|
||||
b.v[1] = 0.0;
|
||||
b.v[2] = tv.v[2];
|
||||
dist = sqrt(0.0 * 0.0 + tv.v[2] * tv.v[2] + tv.v[0] * tv.v[0]);
|
||||
if (alpha <= 2.3841858e-7) {
|
||||
b.v[0] = 1.0;
|
||||
b.v[1] = 0.0;
|
||||
b.v[2] = 0.0;
|
||||
} else {
|
||||
alpha = 1.0 / dist;
|
||||
b.v[0] = b.v[0] * alpha;
|
||||
b.v[1] = b.v[1] * alpha;
|
||||
b.v[2] = b.v[2] * alpha;
|
||||
}
|
||||
tv.v[0] = tv2.v[0] + tv.v[0];
|
||||
tv.v[1] = tv2.v[1] + tv.v[1];
|
||||
tv.v[2] = tv2.v[2] + tv.v[2];
|
||||
ts2 = tv.v[1] * b.v[1] + tv.v[2] * b.v[2] + b.v[0] * tv.v[0];
|
||||
if (ts2 < 0.029999999 && !gAction_replay_mode) {
|
||||
dist = sqrt(tv2.v[1] * tv2.v[1] + tv2.v[2] * tv2.v[2] + tv2.v[0] * tv2.v[0]);
|
||||
if (dist <= 2.3841858e-7) {
|
||||
tv2.v[0] = 1.0;
|
||||
tv2.v[1] = 0.0;
|
||||
tv2.v[2] = 0.0;
|
||||
} else {
|
||||
alpha = 1.0 / dist;
|
||||
tv2.v[0] = tv2.v[0] * alpha;
|
||||
tv2.v[1] = tv2.v[1] * alpha;
|
||||
tv2.v[2] = tv2.v[2] * alpha;
|
||||
}
|
||||
if (tv2.v[2] * b.v[2] + tv2.v[0] * b.v[0] + tv2.v[1] * b.v[1] < -0.029999999)
|
||||
alpha = tv2.v[1] * b.v[1] + tv2.v[2] * b.v[2] + b.v[0] * tv2.v[0];
|
||||
alpha = (0.029999999 - ts2) / alpha;
|
||||
tv2.v[0] = tv2.v[0] * alpha;
|
||||
tv2.v[1] = tv2.v[1] * alpha;
|
||||
tv2.v[2] = tv2.v[2] * alpha;
|
||||
tv.v[0] = tv2.v[0] + tv.v[0];
|
||||
tv.v[1] = tv2.v[1] + tv.v[1];
|
||||
tv.v[2] = tv2.v[2] + tv.v[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
cam_pos->v[0] = car_pos->v[0] + tv.v[0];
|
||||
cam_pos->v[1] = car_pos->v[1] + tv.v[1];
|
||||
cam_pos->v[2] = car_pos->v[2] + tv.v[2];
|
||||
}
|
||||
|
||||
bnds.mat = &mat;
|
||||
BrMatrix34Identity(&mat);
|
||||
tv2.v[0] = hither;
|
||||
tv2.v[1] = hither;
|
||||
tv2.v[2] = hither;
|
||||
bnds.original_bounds.min.v[0] = cam_pos->v[0] - hither;
|
||||
bnds.original_bounds.min.v[1] = cam_pos->v[1] - hither;
|
||||
bnds.original_bounds.min.v[2] = cam_pos->v[2] - hither;
|
||||
bnds.original_bounds.max.v[0] = cam_pos->v[0] + hither;
|
||||
bnds.original_bounds.max.v[1] = cam_pos->v[1] + hither;
|
||||
bnds.original_bounds.max.v[2] = cam_pos->v[2] + hither;
|
||||
k = FindFacesInBox(&bnds, face_list, 3);
|
||||
if (k > 0) {
|
||||
tv2.v[0] = cam_pos->v[0] - face_list[0].v[0].v[0];
|
||||
tv2.v[1] = cam_pos->v[1] - face_list[0].v[0].v[1];
|
||||
tv2.v[2] = cam_pos->v[2] - face_list[0].v[0].v[2];
|
||||
sa = face_list[0].normal.v[2] * tv2.v[2]
|
||||
+ face_list[0].normal.v[1] * tv2.v[1]
|
||||
+ face_list[0].normal.v[0] * tv2.v[0];
|
||||
//ts2 = sa;
|
||||
if (sa < hither && sa >= 0.0) {
|
||||
tv2.v[0] = (hither - sa) * face_list[0].normal.v[0];
|
||||
tv2.v[1] = (hither - sa) * face_list[0].normal.v[1];
|
||||
tv2.v[2] = (hither - sa) * face_list[0].normal.v[2];
|
||||
cam_pos->v[0] = cam_pos->v[0] + tv2.v[0];
|
||||
cam_pos->v[1] = cam_pos->v[1] + tv2.v[1];
|
||||
cam_pos->v[2] = cam_pos->v[2] + tv2.v[2];
|
||||
}
|
||||
if (k > 1) {
|
||||
sb = face_list[1].normal.v[2] * face_list[0].normal.v[2]
|
||||
+ face_list[1].normal.v[1] * face_list[0].normal.v[1]
|
||||
+ face_list[1].normal.v[0] * face_list[0].normal.v[0];
|
||||
if (sb > 0.94999999 && k > 2) {
|
||||
face_list[1].normal.v[0] = face_list[2].normal.v[0];
|
||||
face_list[1].normal.v[1] = face_list[2].normal.v[1];
|
||||
face_list[1].normal.v[2] = face_list[2].normal.v[2];
|
||||
face_list[1].v[0].v[0] = face_list[2].v[0].v[0];
|
||||
face_list[1].v[0].v[1] = face_list[2].v[0].v[1];
|
||||
face_list[1].v[0].v[2] = face_list[2].v[0].v[2];
|
||||
sb = face_list[2].normal.v[2] * face_list[0].normal.v[2]
|
||||
+ face_list[2].normal.v[1] * face_list[0].normal.v[1]
|
||||
+ face_list[2].normal.v[0] * face_list[0].normal.v[0];
|
||||
k = 2;
|
||||
}
|
||||
if (sb <= 0.94999999) {
|
||||
tv2.v[0] = cam_pos->v[0] - face_list[1].v[0].v[0];
|
||||
tv2.v[1] = cam_pos->v[1] - face_list[1].v[0].v[1];
|
||||
tv2.v[2] = cam_pos->v[2] - face_list[1].v[0].v[2];
|
||||
sc = face_list[1].normal.v[2] * tv2.v[2]
|
||||
+ face_list[1].normal.v[1] * tv2.v[1]
|
||||
+ face_list[1].normal.v[0] * tv2.v[0];
|
||||
if (sc < hither && sc >= 0.0) {
|
||||
sc = face_list[1].normal.v[2] * face_list[0].normal.v[2]
|
||||
+ face_list[1].normal.v[1] * face_list[0].normal.v[1]
|
||||
+ face_list[1].normal.v[0] * face_list[0].normal.v[0];
|
||||
b.v[0] = face_list[0].normal.v[0] * sc;
|
||||
b.v[1] = face_list[0].normal.v[1] * sc;
|
||||
b.v[2] = face_list[0].normal.v[2] * sc;
|
||||
face_list[1].normal.v[0] = face_list[1].normal.v[0] - b.v[0];
|
||||
face_list[1].normal.v[1] = face_list[1].normal.v[1] - b.v[1];
|
||||
face_list[1].normal.v[2] = face_list[1].normal.v[2] - b.v[2];
|
||||
tv2.v[0] = (hither - ts2) * face_list[1].normal.v[0];
|
||||
tv2.v[1] = (hither - ts2) * face_list[1].normal.v[1];
|
||||
tv2.v[2] = (hither - ts2) * face_list[1].normal.v[2];
|
||||
cam_pos->v[0] = cam_pos->v[0] + tv2.v[0];
|
||||
cam_pos->v[1] = cam_pos->v[1] + tv2.v[1];
|
||||
cam_pos->v[2] = cam_pos->v[2] + tv2.v[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i += k;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// IDA: int __usercall BoundsTest@<EAX>(br_bounds *bnds@<EAX>, br_vector3 *p@<EDX>)
|
||||
|
|
@ -2449,7 +2637,11 @@ int TestOldMats(tCollision_info* c1, tCollision_info* c2, int newmats) {
|
|||
// IDA: int __usercall PullActorFromWorld@<EAX>(br_actor *pActor@<EAX>)
|
||||
int PullActorFromWorld(br_actor* pActor) {
|
||||
LOG_TRACE("(%p)", pActor);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (gDoing_physics) {
|
||||
return DoPullActorFromWorld(pActor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: int __usercall DoPullActorFromWorld@<EAX>(br_actor *pActor@<EAX>)
|
||||
|
|
@ -2459,7 +2651,9 @@ int DoPullActorFromWorld(br_actor* pActor) {
|
|||
tCollision_info* c;
|
||||
tNon_car_spec* non_car;
|
||||
LOG_TRACE("(%p)", pActor);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
STUB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: void __usercall CheckForDeAttachmentOfNonCars(tU32 pTime@<EAX>)
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ void ExternalSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_act
|
|||
int repetitions;
|
||||
br_pixelmap* col_map;
|
||||
LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
|
||||
|
||||
return;
|
||||
dx = 0;
|
||||
col_map = gHorizon_material->colour_map;
|
||||
camera = (br_camera*)pCamera->type_data;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#include "finteray.h"
|
||||
#include "brender.h"
|
||||
#include "brucetrk.h"
|
||||
#include "car.h"
|
||||
#include "globvars.h"
|
||||
#include "world.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
br_matrix34 gPick_model_to_view;
|
||||
|
|
@ -39,6 +42,56 @@ int PickBoundsTestRay_finteray(br_bounds* b, br_vector3* rp, br_vector3* rd, br_
|
|||
float s;
|
||||
float t;
|
||||
LOG_TRACE("(%p, %p, %p, %f, %f, %p, %p)", b, rp, rd, t_near, t_far, new_t_near, new_t_far);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (rd->v[i] >= -0.00000023841858) {
|
||||
if (rd->v[i] <= 0.00000023841858) {
|
||||
if (b->max.v[i] < rp->v[i] || rp->v[i] < b->min.v[i]) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
s = (-1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]);
|
||||
if (s >= BR_SCALAR_MIN) {
|
||||
if (s < t_far) {
|
||||
t_far = (-1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]);
|
||||
}
|
||||
} else {
|
||||
t_far = BR_SCALAR_MIN;
|
||||
}
|
||||
t = (-1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]);
|
||||
if (t <= BR_SCALAR_MAX) {
|
||||
if (t > t_near) {
|
||||
t_near = (-1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]);
|
||||
}
|
||||
} else {
|
||||
t_near = BR_SCALAR_MAX;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s = (-1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]);
|
||||
if (s <= BR_SCALAR_MAX) {
|
||||
if (s > t_near) {
|
||||
t_near = (-1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]);
|
||||
}
|
||||
} else {
|
||||
t_near = BR_SCALAR_MAX;
|
||||
}
|
||||
t = (-1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]);
|
||||
if (t >= BR_SCALAR_MIN) {
|
||||
if (t < t_far) {
|
||||
t_far = (-1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]);
|
||||
}
|
||||
} else {
|
||||
t_far = BR_SCALAR_MIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (t_far < t_near) {
|
||||
return 0;
|
||||
}
|
||||
*new_t_near = t_near;
|
||||
*new_t_far = t_far;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// IDA: int __usercall ActorRayPick2D@<EAX>(br_actor *ap@<EAX>, br_vector3 *pPosition@<EDX>, br_vector3 *pDir@<EBX>, br_model *model@<ECX>, br_material *material, dr_pick2d_cbfn *callback)
|
||||
|
|
@ -55,13 +108,74 @@ int ActorRayPick2D(br_actor* ap, br_vector3* pPosition, br_vector3* pDir, br_mod
|
|||
br_vector3 dir;
|
||||
void* arg;
|
||||
LOG_TRACE("(%p, %p, %p, %p, %p, %p)", ap, pPosition, pDir, model, material, callback);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
t_near = 0.0;
|
||||
t_far = 1.0;
|
||||
r = 0;
|
||||
arg = NULL;
|
||||
if (ap->model) {
|
||||
this_model = ap->model;
|
||||
} else {
|
||||
this_model = model;
|
||||
}
|
||||
if (ap->material) {
|
||||
this_material = ap->material;
|
||||
} else {
|
||||
this_material = material;
|
||||
}
|
||||
if (ap->render_style == 1) {
|
||||
return 0;
|
||||
}
|
||||
if (ap->identifier && *ap->identifier == '&') {
|
||||
BrTransformToMatrix34(&mat, &ap->t);
|
||||
BrMatrix34Inverse(&invmat, &mat);
|
||||
BrMatrix34ApplyP(&pos, pPosition, &invmat);
|
||||
BrMatrix34ApplyV(&dir, pDir, &invmat);
|
||||
pPosition = &pos;
|
||||
pDir = &dir;
|
||||
}
|
||||
if (ap->type == BR_ACTOR_MODEL) {
|
||||
if (PickBoundsTestRay_finteray(&this_model->bounds, pPosition, pDir, t_near, t_far, &t_near, &t_far)) {
|
||||
t_near = 0.0;
|
||||
if (gNearest_T >= 1.0) {
|
||||
t_far = 1.0;
|
||||
} else {
|
||||
t_far = gNearest_T;
|
||||
}
|
||||
r = callback(ap, this_model, this_material, pPosition, pDir, t_near, t_far, arg);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
} else if (ap->type >= BR_ACTOR_BOUNDS && ap->type <= BR_ACTOR_BOUNDS_CORRECT) {
|
||||
if (PickBoundsTestRay_finteray((br_bounds*)ap->type_data, pPosition, pDir, t_near, t_far, &t_near, &t_far)) {
|
||||
for (a = ap->children; a; a = a->next) {
|
||||
r = ActorRayPick2D(a, pPosition, pDir, this_model, this_material, callback);
|
||||
if (r) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
for (a = ap->children; a; a = a->next) {
|
||||
r = ActorRayPick2D(a, pPosition, pDir, this_model, this_material, callback);
|
||||
if (r) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// IDA: int __usercall DRSceneRayPick2D@<EAX>(br_actor *world@<EAX>, br_vector3 *pPosition@<EDX>, br_vector3 *pDir@<EBX>, dr_pick2d_cbfn *callback@<ECX>)
|
||||
int DRSceneRayPick2D(br_actor* world, br_vector3* pPosition, br_vector3* pDir, dr_pick2d_cbfn* callback) {
|
||||
LOG_TRACE("(%p, %p, %p, %p)", world, pPosition, pDir, callback);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrMatrix34Inverse(&gPick_model_to_view, &world->t.t.mat);
|
||||
return ActorRayPick2D(world, pPosition, pDir, NULL, NULL, callback);
|
||||
}
|
||||
|
||||
// Offset: 1544
|
||||
|
|
@ -100,7 +214,129 @@ int DRModelPick2D_finteray(br_model* model, br_material* material, br_vector3* r
|
|||
float f_numerator;
|
||||
int group;
|
||||
LOG_TRACE("(%p, %p, %p, %p, %f, %f, %p, %p)", model, material, ray_pos, ray_dir, t_near, t_far, callback, arg);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
t_near -= 0.0000099999997;
|
||||
t_far += 0.0000099999997;
|
||||
for (group = 0; group < V11MODEL(model)->ngroups; group++) {
|
||||
for (f = 0; f < V11MODEL(model)->groups[group].nfaces; f++) {
|
||||
fp = &V11MODEL(model)->groups[group].faces[f];
|
||||
if (V11MODEL(model)->groups[group].face_colours_material) {
|
||||
this_material = V11MODEL(model)->groups[group].face_colours_material;
|
||||
} else {
|
||||
this_material = material;
|
||||
}
|
||||
d = fp->eqn.v[1] * ray_dir->v[1] + fp->eqn.v[2] * ray_dir->v[2] + fp->eqn.v[0] * ray_dir->v[0];
|
||||
if (fabs(d) >= 0.00000023841858 && (!this_material || !this_material->identifier || *this_material->identifier != '!' || !gPling_materials)
|
||||
&& (!this_material || (this_material->flags & 0x1800) != 0 || d <= 0.0)) {
|
||||
numerator = fp->eqn.v[1] * ray_pos->v[1]
|
||||
+ fp->eqn.v[2] * ray_pos->v[2]
|
||||
+ fp->eqn.v[0] * ray_pos->v[0]
|
||||
- fp->eqn.v[3];
|
||||
if (!BadDiv_finteray(numerator, d)) {
|
||||
t = -(numerator / d);
|
||||
if (t >= t_near && t <= t_far) {
|
||||
p.v[0] = ray_dir->v[0] * t;
|
||||
p.v[1] = ray_dir->v[1] * t;
|
||||
p.v[2] = ray_dir->v[2] * t;
|
||||
p.v[0] = ray_pos->v[0] + p.v[0];
|
||||
p.v[1] = ray_pos->v[1] + p.v[1];
|
||||
p.v[2] = ray_pos->v[2] + p.v[2];
|
||||
axis_m = fabs(fp->eqn.v[0]) < fabs(fp->eqn.v[1]);
|
||||
if (fabs(fp->eqn.v[2]) > fabs(fp->eqn.v[axis_m])) {
|
||||
axis_m = 2;
|
||||
}
|
||||
if (axis_m) {
|
||||
axis_0 = 0;
|
||||
if (axis_m == 1) {
|
||||
axis_1 = 2;
|
||||
} else {
|
||||
axis_1 = 1;
|
||||
}
|
||||
} else {
|
||||
axis_0 = 1;
|
||||
axis_1 = 2;
|
||||
}
|
||||
|
||||
v0 = V11MODEL(model)->groups[group].vertices[fp->vertices[0]].p.v[axis_0];
|
||||
u0 = V11MODEL(model)->groups[group].vertices[fp->vertices[0]].p.v[axis_1];
|
||||
v1 = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].p.v[axis_0] - v0;
|
||||
u1 = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].p.v[axis_1] - u0;
|
||||
v2 = V11MODEL(model)->groups[group].vertices[fp->vertices[2]].p.v[axis_0] - v0;
|
||||
u2 = V11MODEL(model)->groups[group].vertices[fp->vertices[2]].p.v[axis_1] - u0;
|
||||
|
||||
v0i1 = p.v[axis_0] - v0;
|
||||
v0i2 = p.v[axis_1] - u0;
|
||||
if (fabs(v1) > 0.0000002384185791015625) {
|
||||
f_n = u2 * v1 - u1 * v2;
|
||||
f_d = v0i2 * v1 - u1 * v0i1;
|
||||
if (fabs(f_n) < fabs(f_d)) {
|
||||
continue;
|
||||
}
|
||||
if (f_n == 0) {
|
||||
continue;
|
||||
}
|
||||
beta = f_d / f_n;
|
||||
if (beta < 0.0 || beta > 1.0 || v1 == 0.0) {
|
||||
continue;
|
||||
}
|
||||
alpha = (v0i1 - beta * v2) / v1;
|
||||
} else {
|
||||
if (fabs(v2) < fabs(v0i1)) {
|
||||
continue;
|
||||
}
|
||||
if (v2 == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
beta = v0i1 / v2;
|
||||
if (beta < 0.0 || beta > 1.0 || u1 == 0.0) {
|
||||
continue;
|
||||
}
|
||||
alpha = (v0i2 - beta * u2) / u1;
|
||||
}
|
||||
|
||||
if (alpha >= 0.0 && beta + alpha <= 1.0) {
|
||||
s_alpha = alpha;
|
||||
s_beta = beta;
|
||||
map.v[0] = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].map.v[0] * s_alpha;
|
||||
map.v[1] = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].map.v[1] * s_alpha;
|
||||
DRVector2AccumulateScale_finteray(
|
||||
&map,
|
||||
&V11MODEL(model)->groups[group].vertices[fp->vertices[2]].map,
|
||||
s_beta);
|
||||
DRVector2AccumulateScale_finteray(
|
||||
&map,
|
||||
&V11MODEL(model)->groups[group].vertices[fp->vertices[0]].map,
|
||||
1.0 - (s_alpha + s_beta));
|
||||
v = 0;
|
||||
e = 1;
|
||||
if (s_alpha <= s_beta) {
|
||||
if (0.5 - s_beta / 2.0 > s_alpha) {
|
||||
e = 0;
|
||||
}
|
||||
if (1.0 - s_beta * 2.0 < s_alpha) {
|
||||
v = 1;
|
||||
}
|
||||
} else {
|
||||
if (1.0 - s_beta * 2.0 > s_alpha) {
|
||||
e = 2;
|
||||
}
|
||||
if (0.5 - s_beta / 2.0 < s_alpha) {
|
||||
v = 2;
|
||||
}
|
||||
}
|
||||
gTemp_group = group;
|
||||
r = callback(model, this_material, ray_pos, ray_dir, t, f, e, v, &p, &map, arg);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: int __cdecl FindHighestPolyCallBack(br_model *pModel, br_material *pMaterial, br_vector3 *pRay_pos, br_vector3 *pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3 *pPoint, br_vector2 *pMap, void *pArg)
|
||||
|
|
@ -131,7 +367,17 @@ int FindHighestCallBack_finteray(br_actor* pActor, br_model* pModel, br_material
|
|||
void FindFace(br_vector3* pPosition, br_vector3* pDir, br_vector3* nor, br_scalar* t, br_material** material) {
|
||||
int group;
|
||||
LOG_TRACE("(%p, %p, %p, %p, %p)", pPosition, pDir, nor, t, material);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gNearest_T = 100.0;
|
||||
DRSceneRayPick2D(gTrack_actor, pPosition, pDir, FindHighestCallBack_finteray);
|
||||
*t = gNearest_T;
|
||||
if (*t < 100.0) {
|
||||
group = gNearest_face_group;
|
||||
nor->v[0] = V11MODEL(gNearest_model)->groups[gNearest_face_group].faces[gNearest_face].eqn.v[0];
|
||||
nor->v[1] = V11MODEL(gNearest_model)->groups[group].faces[gNearest_face].eqn.v[1];
|
||||
nor->v[2] = V11MODEL(gNearest_model)->groups[group].faces[gNearest_face].eqn.v[2];
|
||||
*material = V11MODEL(gNearest_model)->groups[group].face_colours_material;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl EnablePlingMaterials()
|
||||
|
|
@ -249,7 +495,68 @@ int FindFacesInBox(tBounds* bnds, tFace_ref* face_list, int max_face) {
|
|||
tU8 cz_max;
|
||||
tTrack_spec* track_spec;
|
||||
LOG_TRACE("(%p, %p, %d)", bnds, face_list, max_face);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
j = 0;
|
||||
track_spec = &gProgram_state.track_spec;
|
||||
a.v[0] = bnds->original_bounds.min.v[0] + bnds->original_bounds.max.v[0];
|
||||
a.v[1] = bnds->original_bounds.min.v[1] + bnds->original_bounds.max.v[1];
|
||||
a.v[2] = bnds->original_bounds.min.v[2] + bnds->original_bounds.max.v[2];
|
||||
b.v[0] = a.v[0] * 0.5;
|
||||
b.v[1] = a.v[1] * 0.5;
|
||||
b.v[2] = a.v[2] * 0.5;
|
||||
BrMatrix34ApplyP(&bnds->box_centre, &b, bnds->mat);
|
||||
b.v[0] = bnds->original_bounds.max.v[0] - bnds->original_bounds.min.v[0];
|
||||
b.v[1] = bnds->original_bounds.max.v[1] - bnds->original_bounds.min.v[1];
|
||||
b.v[2] = bnds->original_bounds.max.v[2] - bnds->original_bounds.min.v[2];
|
||||
bnds->radius = sqrt(b.v[1] * b.v[1] + b.v[2] * b.v[2] + b.v[0] * b.v[0]) / 2.0;
|
||||
BrMatrix34ApplyP(&bnds->real_bounds.min, &bnds->original_bounds.min, bnds->mat);
|
||||
bnds->real_bounds.max = bnds->real_bounds.min;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
c[i].v[0] = bnds->mat->m[i][0] * b.v[i];
|
||||
c[i].v[1] = bnds->mat->m[i][1] * b.v[i];
|
||||
c[i].v[2] = bnds->mat->m[i][2] * b.v[i];
|
||||
}
|
||||
for (i = 0; i < 3; ++i) {
|
||||
bnds->real_bounds.min.v[i] = (double)(c[2].v[i] < 0.0) * c[2].v[i]
|
||||
+ (double)(c[1].v[i] < 0.0) * c[1].v[i]
|
||||
+ (double)(c[0].v[i] < 0.0) * c[0].v[i]
|
||||
+ bnds->real_bounds.min.v[i];
|
||||
bnds->real_bounds.max.v[i] = (double)(c[2].v[i] > 0.0) * c[2].v[i]
|
||||
+ (double)(c[1].v[i] > 0.0) * c[1].v[i]
|
||||
+ (double)(c[0].v[i] > 0.0) * c[0].v[i]
|
||||
+ bnds->real_bounds.max.v[i];
|
||||
}
|
||||
XZToColumnXZ(&cx_min, &cz_min, bnds->real_bounds.min.v[0], bnds->real_bounds.min.v[2], track_spec);
|
||||
XZToColumnXZ(&cx_max, &cz_max, bnds->real_bounds.max.v[0], bnds->real_bounds.max.v[2], track_spec);
|
||||
if (cx_min) {
|
||||
cx_min--;
|
||||
}
|
||||
if (cz_min) {
|
||||
cz_min--;
|
||||
}
|
||||
if (track_spec->ncolumns_x > cx_max + 1) {
|
||||
cx_max++;
|
||||
}
|
||||
if (track_spec->ncolumns_z > cz_max + 1) {
|
||||
cz_max++;
|
||||
}
|
||||
for (x = cx_min; cx_max >= x; ++x) {
|
||||
for (z = cz_min; cz_max >= z; ++z) {
|
||||
if (track_spec->columns[z][x]) {
|
||||
if (track_spec->blends[z][x]) {
|
||||
track_spec->blends[z][x]->render_style = BR_RSTYLE_FACES;
|
||||
}
|
||||
j = max_face - ActorBoxPick(bnds, track_spec->columns[z][x], NULL, NULL, &face_list[j], max_face - j, 0);
|
||||
if (track_spec->blends[z][x]) {
|
||||
track_spec->blends[z][x]->render_style = BR_RSTYLE_NONE;
|
||||
}
|
||||
}
|
||||
if (track_spec->lollipops[z][x]) {
|
||||
j = max_face - ActorBoxPick(bnds, track_spec->lollipops[z][x], NULL, NULL, &face_list[j], max_face - j, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
// IDA: int __usercall FindFacesInBox2@<EAX>(tBounds *bnds@<EAX>, tFace_ref *face_list@<EDX>, int max_face@<EBX>)
|
||||
|
|
@ -279,7 +586,77 @@ int ActorBoxPick(tBounds* bnds, br_actor* ap, br_model* model, br_material* mate
|
|||
tBounds new_bounds;
|
||||
br_bounds br_bnds;
|
||||
LOG_TRACE("(%p, %p, %p, %p, %p, %d, %p)", bnds, ap, model, material, face_list, max_face, pMat);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
i = 0;
|
||||
test_children = 1;
|
||||
if (ap->model) {
|
||||
this_model = ap->model;
|
||||
} else {
|
||||
this_model = model;
|
||||
}
|
||||
if (ap->material) {
|
||||
this_material = ap->material;
|
||||
} else {
|
||||
this_material = material;
|
||||
}
|
||||
if (ap->render_style == 1) {
|
||||
return max_face;
|
||||
}
|
||||
if (ap->identifier && *ap->identifier == '&') {
|
||||
if (!ap->children
|
||||
&& (ap->type != BR_ACTOR_MODEL || !BoundsTransformTest(&this_model->bounds, &bnds->real_bounds, &ap->t.t.mat))) {
|
||||
return max_face;
|
||||
}
|
||||
if (pMat) {
|
||||
BrMatrix34Mul(&mat, &ap->t.t.mat, pMat);
|
||||
pMat = &mat;
|
||||
} else {
|
||||
pMat = &ap->t.t.mat;
|
||||
}
|
||||
BrMatrix34LPInverse(&invmat, &ap->t.t.mat);
|
||||
BrMatrix34Mul(&mat2, bnds->mat, &invmat);
|
||||
new_bounds.mat = &mat2;
|
||||
new_bounds.original_bounds = bnds->original_bounds;
|
||||
BrMatrix34ApplyP(&new_bounds.box_centre, &bnds->box_centre, &invmat);
|
||||
new_bounds.radius = bnds->radius;
|
||||
GetNewBoundingBox(&new_bounds.real_bounds, &new_bounds.original_bounds, new_bounds.mat);
|
||||
if (ap->identifier[1] >= '0' && ap->identifier[1] <= '9') {
|
||||
if (!BoundsOverlapTest_finteray(&new_bounds.real_bounds, &this_model->bounds)) {
|
||||
return max_face;
|
||||
}
|
||||
BrMatrix34LPInverse(&invmat, bnds->mat);
|
||||
BrMatrix34Mul(&box_to_actor, &ap->t.t.mat, &invmat);
|
||||
GetNewBoundingBox(&br_bnds, &ap->model->bounds, &box_to_actor);
|
||||
if (!BoundsOverlapTest_finteray(&br_bnds, &bnds->original_bounds)) {
|
||||
return max_face;
|
||||
}
|
||||
if (PullActorFromWorld(ap)) {
|
||||
return max_face;
|
||||
}
|
||||
}
|
||||
bnds = &new_bounds;
|
||||
}
|
||||
if (ap->type == BR_ACTOR_MODEL) {
|
||||
if (BoundsOverlapTest_finteray(&bnds->real_bounds, &this_model->bounds)) {
|
||||
n = ModelPickBox(ap, bnds, this_model, this_material, &face_list[i], max_face, pMat);
|
||||
if (pMat && max_face != n) {
|
||||
StopGroovidelic(ap);
|
||||
}
|
||||
i += max_face - n;
|
||||
max_face = n;
|
||||
}
|
||||
} else if (ap->type >= 5u && ap->type <= 6u) {
|
||||
test_children = BoundsOverlapTest_finteray(&bnds->real_bounds, (br_bounds*)ap->type_data);
|
||||
}
|
||||
if (test_children) {
|
||||
for (a = ap->children; a; a = next_a) {
|
||||
next_a = a->next;
|
||||
n = ActorBoxPick(bnds, a, this_model, this_material, &face_list[i], max_face, pMat);
|
||||
i += max_face - n;
|
||||
max_face = n;
|
||||
}
|
||||
}
|
||||
return max_face;
|
||||
}
|
||||
|
||||
// IDA: int __usercall ModelPickBox@<EAX>(br_actor *actor@<EAX>, tBounds *bnds@<EDX>, br_model *model@<EBX>, br_material *model_material@<ECX>, tFace_ref *face_list, int max_face, br_matrix34 *pMat)
|
||||
|
|
@ -298,7 +675,145 @@ int ModelPickBox(br_actor* actor, tBounds* bnds, br_model* model, br_material* m
|
|||
br_scalar t;
|
||||
v11model* prepared;
|
||||
LOG_TRACE("(%p, %p, %p, %p, %p, %d, %p)", actor, bnds, model, model_material, face_list, max_face, pMat);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
prepared = model->prepared;
|
||||
if (max_face <= 0) {
|
||||
return 0;
|
||||
}
|
||||
for (group = 0; prepared->ngroups > group; group++) {
|
||||
fp = prepared->groups[group].faces;
|
||||
for (f = 0; f < prepared->groups[group].nfaces; f++) {
|
||||
v1 = fp->vertices[0];
|
||||
a.v[0] = prepared->groups[group].vertices[v1].p.v[0] - bnds->box_centre.v[0];
|
||||
a.v[1] = prepared->groups[group].vertices[v1].p.v[1] - bnds->box_centre.v[1];
|
||||
a.v[2] = prepared->groups[group].vertices[v1].p.v[2] - bnds->box_centre.v[2];
|
||||
t = fp->eqn.v[1] * a.v[1] + fp->eqn.v[2] * a.v[2] + fp->eqn.v[0] * a.v[0];
|
||||
if (fabs(t) <= bnds->radius) {
|
||||
v2 = fp->vertices[1];
|
||||
v3 = fp->vertices[2];
|
||||
t = bnds->real_bounds.min.v[0];
|
||||
if (prepared->groups[group].vertices[v1].p.v[0] >= (double)t
|
||||
|| prepared->groups[group].vertices[v2].p.v[0] >= (double)t
|
||||
|| prepared->groups[group].vertices[v3].p.v[0] >= (double)t) {
|
||||
t = bnds->real_bounds.max.v[0];
|
||||
if (prepared->groups[group].vertices[v1].p.v[0] <= (double)t
|
||||
|| prepared->groups[group].vertices[v2].p.v[0] <= (double)t
|
||||
|| prepared->groups[group].vertices[v3].p.v[0] <= (double)t) {
|
||||
t = bnds->real_bounds.min.v[1];
|
||||
if (prepared->groups[group].vertices[v1].p.v[1] >= (double)t
|
||||
|| prepared->groups[group].vertices[v2].p.v[1] >= (double)t
|
||||
|| prepared->groups[group].vertices[v3].p.v[1] >= (double)t) {
|
||||
t = bnds->real_bounds.max.v[1];
|
||||
if (prepared->groups[group].vertices[v1].p.v[1] <= (double)t
|
||||
|| prepared->groups[group].vertices[v2].p.v[1] <= (double)t
|
||||
|| prepared->groups[group].vertices[v3].p.v[1] <= (double)t) {
|
||||
t = bnds->real_bounds.min.v[2];
|
||||
if (prepared->groups[group].vertices[v1].p.v[2] >= (double)t
|
||||
|| prepared->groups[group].vertices[v2].p.v[2] >= (double)t
|
||||
|| prepared->groups[group].vertices[v3].p.v[2] >= (double)t) {
|
||||
t = bnds->real_bounds.max.v[2];
|
||||
if (prepared->groups[group].vertices[v1].p.v[2] <= (double)t
|
||||
|| prepared->groups[group].vertices[v2].p.v[2] <= (double)t
|
||||
|| prepared->groups[group].vertices[v3].p.v[2] <= (double)t) {
|
||||
polygon[1].v[0] = prepared->groups[group].vertices[v1].p.v[0]
|
||||
- bnds->mat->m[3][0];
|
||||
polygon[1].v[1] = prepared->groups[group].vertices[v1].p.v[1]
|
||||
- bnds->mat->m[3][1];
|
||||
polygon[1].v[2] = prepared->groups[group].vertices[v1].p.v[2]
|
||||
- bnds->mat->m[3][2];
|
||||
polygon[2].v[0] = prepared->groups[group].vertices[v2].p.v[0]
|
||||
- bnds->mat->m[3][0];
|
||||
polygon[2].v[1] = prepared->groups[group].vertices[v2].p.v[1]
|
||||
- bnds->mat->m[3][1];
|
||||
polygon[2].v[2] = prepared->groups[group].vertices[v2].p.v[2]
|
||||
- bnds->mat->m[3][2];
|
||||
polygon[3].v[0] = prepared->groups[group].vertices[v3].p.v[0]
|
||||
- bnds->mat->m[3][0];
|
||||
polygon[3].v[1] = prepared->groups[group].vertices[v3].p.v[1]
|
||||
- bnds->mat->m[3][1];
|
||||
polygon[3].v[2] = prepared->groups[group].vertices[v3].p.v[2]
|
||||
- bnds->mat->m[3][2];
|
||||
BrMatrix34TApplyV(polygon, &polygon[1], bnds->mat);
|
||||
BrMatrix34TApplyV(&polygon[1], &polygon[2], bnds->mat);
|
||||
BrMatrix34TApplyV(&polygon[2], &polygon[3], bnds->mat);
|
||||
n = 3;
|
||||
for (i = 0; i < 3; i++) {
|
||||
ClipToPlaneGE(polygon, &n, i, bnds->original_bounds.min.v[i]);
|
||||
if (n < 3) {
|
||||
break;
|
||||
}
|
||||
ClipToPlaneLE(polygon, &n, i, bnds->original_bounds.max.v[i]);
|
||||
if (n < 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n >= 3) {
|
||||
if (pMat) {
|
||||
BrMatrix34ApplyP(&face_list->v[0], &prepared->groups[group].vertices[v1].p, pMat);
|
||||
BrMatrix34ApplyP(&face_list->v[1], &prepared->groups[group].vertices[v2].p, pMat);
|
||||
BrMatrix34ApplyP(&face_list->v[2], &prepared->groups[group].vertices[v3].p, pMat);
|
||||
tv.v[0] = fp->eqn.v[0];
|
||||
tv.v[1] = fp->eqn.v[1];
|
||||
tv.v[2] = fp->eqn.v[2];
|
||||
BrMatrix34ApplyV(&face_list->normal, &tv, pMat);
|
||||
} else {
|
||||
face_list->v[0].v[0] = prepared->groups[group].vertices[v1].p.v[0];
|
||||
face_list->v[0].v[1] = prepared->groups[group].vertices[v1].p.v[1];
|
||||
face_list->v[0].v[2] = prepared->groups[group].vertices[v1].p.v[2];
|
||||
face_list->v[1].v[0] = prepared->groups[group].vertices[v2].p.v[0];
|
||||
face_list->v[1].v[1] = prepared->groups[group].vertices[v2].p.v[1];
|
||||
face_list->v[1].v[2] = prepared->groups[group].vertices[v2].p.v[2];
|
||||
face_list->v[2].v[0] = prepared->groups[group].vertices[v3].p.v[0];
|
||||
face_list->v[2].v[1] = prepared->groups[group].vertices[v3].p.v[1];
|
||||
face_list->v[2].v[2] = prepared->groups[group].vertices[v3].p.v[2];
|
||||
face_list->normal.v[0] = fp->eqn.v[0];
|
||||
face_list->normal.v[1] = fp->eqn.v[1];
|
||||
face_list->normal.v[2] = fp->eqn.v[2];
|
||||
}
|
||||
if (prepared->groups[group].face_colours_material) {
|
||||
face_list->material = prepared->groups[group].face_colours_material;
|
||||
} else {
|
||||
face_list->material = model_material;
|
||||
}
|
||||
face_list->flags = 0;
|
||||
if (face_list->material && (face_list->material->flags & 0x1800) == 0) {
|
||||
face_list->flags |= (v2 > v1) + 2 * (v3 > v2) + 4 * (v3 < v1);
|
||||
}
|
||||
if (pMat) {
|
||||
face_list->d = face_list->v[0].v[2] * face_list->normal.v[2]
|
||||
+ face_list->v[0].v[1] * face_list->normal.v[1]
|
||||
+ face_list->v[0].v[0] * face_list->normal.v[0];
|
||||
} else {
|
||||
face_list->d = fp->eqn.v[3];
|
||||
}
|
||||
face_list->map[0] = &prepared->groups[group].vertices[v1].map;
|
||||
face_list->map[1] = &prepared->groups[group].vertices[v2].map;
|
||||
face_list->map[2] = &prepared->groups[group].vertices[v3].map;
|
||||
if (face_list->material
|
||||
&& face_list->material->identifier
|
||||
&& *face_list->material->identifier == '!') {
|
||||
gPling_face = face_list;
|
||||
}
|
||||
face_list++;
|
||||
max_face--;
|
||||
if (!max_face) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++fp;
|
||||
}
|
||||
if (!max_face) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return max_face;
|
||||
}
|
||||
|
||||
// IDA: void __usercall ClipToPlaneGE(br_vector3 *p@<EAX>, int *nv@<EDX>, int i@<EBX>, br_scalar limit)
|
||||
|
|
@ -309,7 +824,35 @@ void ClipToPlaneGE(br_vector3* p, int* nv, int i, br_scalar limit) {
|
|||
int k;
|
||||
br_vector3 p2[12];
|
||||
LOG_TRACE("(%p, %p, %d, %f)", p, nv, i, limit);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
last_vertex = *nv - 1;
|
||||
j = 0;
|
||||
for (vertex = 0; *nv > vertex; ++vertex) {
|
||||
if ((p[last_vertex].v[i] > limit) != (p[vertex].v[i] > limit)) {
|
||||
for (k = 0; k < 3; ++k) {
|
||||
if (i != k) {
|
||||
p2[j].v[k] = (p[vertex].v[k] - p[last_vertex].v[k])
|
||||
* (limit - p[last_vertex].v[i])
|
||||
/ (p[vertex].v[i] - p[last_vertex].v[i])
|
||||
+ p[last_vertex].v[k];
|
||||
}
|
||||
}
|
||||
p2[j++].v[i] = limit;
|
||||
}
|
||||
if (p[vertex].v[i] >= limit) {
|
||||
p2[j].v[0] = p[vertex].v[0];
|
||||
p2[j].v[1] = p[vertex].v[1];
|
||||
p2[j].v[2] = p[vertex].v[2];
|
||||
j++;
|
||||
}
|
||||
last_vertex = vertex;
|
||||
}
|
||||
*nv = j;
|
||||
for (k = 0; k < j; k++) {
|
||||
p[k].v[0] = p2[k].v[0];
|
||||
p[k].v[1] = p2[k].v[1];
|
||||
p[k].v[2] = p2[k].v[2];
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall ClipToPlaneLE(br_vector3 *p@<EAX>, int *nv@<EDX>, int i@<EBX>, br_scalar limit)
|
||||
|
|
@ -320,13 +863,47 @@ void ClipToPlaneLE(br_vector3* p, int* nv, int i, br_scalar limit) {
|
|||
int k;
|
||||
br_vector3 p2[12];
|
||||
LOG_TRACE("(%p, %p, %d, %f)", p, nv, i, limit);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
last_vertex = *nv - 1;
|
||||
j = 0;
|
||||
for (vertex = 0; *nv > vertex; ++vertex) {
|
||||
if ((p[vertex].v[i] > limit) != (p[last_vertex].v[i] > limit)) {
|
||||
for (k = 0; k < 3; ++k) {
|
||||
if (k != i) {
|
||||
p2[j].v[k] = (p[vertex].v[k] - p[last_vertex].v[k])
|
||||
* (limit - p[last_vertex].v[i])
|
||||
/ (p[vertex].v[i] - p[last_vertex].v[i])
|
||||
+ p[last_vertex].v[k];
|
||||
}
|
||||
}
|
||||
p2[j++].v[i] = limit;
|
||||
}
|
||||
if (p[vertex].v[i] <= (double)limit) {
|
||||
p2[j].v[0] = p[vertex].v[0];
|
||||
p2[j].v[1] = p[vertex].v[1];
|
||||
p2[j].v[2] = p[vertex].v[2];
|
||||
j++;
|
||||
}
|
||||
last_vertex = vertex;
|
||||
}
|
||||
*nv = j;
|
||||
for (k = 0; k < j; k++) {
|
||||
p[k].v[0] = p2[k].v[0];
|
||||
p[k].v[1] = p2[k].v[1];
|
||||
p[k].v[2] = p2[k].v[2];
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: int __usercall BoundsOverlapTest@<EAX>(br_bounds *b1@<EAX>, br_bounds *b2@<EDX>)
|
||||
int BoundsOverlapTest_finteray(br_bounds* b1, br_bounds* b2) {
|
||||
LOG_TRACE("(%p, %p)", b1, b2);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
return b1->min.v[0] <= b2->max.v[0]
|
||||
&& b1->max.v[0] >= b2->min.v[0]
|
||||
&& b1->min.v[1] <= b2->max.v[1]
|
||||
&& b2->min.v[1] <= b1->max.v[1]
|
||||
&& b1->min.v[2] <= b2->max.v[2]
|
||||
&& b1->max.v[2] >= b2->min.v[2];
|
||||
}
|
||||
|
||||
// IDA: int __usercall BoundsTransformTest@<EAX>(br_bounds *b1@<EAX>, br_bounds *b2@<EDX>, br_matrix34 *M@<EBX>)
|
||||
|
|
@ -334,7 +911,56 @@ int BoundsTransformTest(br_bounds* b1, br_bounds* b2, br_matrix34* M) {
|
|||
br_scalar val;
|
||||
br_vector3 o;
|
||||
LOG_TRACE("(%p, %p, %p)", b1, b2, M);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
o.v[0] = b1->max.v[0] - b1->min.v[0];
|
||||
o.v[1] = b1->max.v[1] - b1->min.v[1];
|
||||
o.v[2] = b1->max.v[2] - b1->min.v[2];
|
||||
val = M->m[2][0] * b1->min.v[2] + b1->min.v[1] * M->m[1][0] + M->m[0][0] * b1->min.v[0] + M->m[3][0];
|
||||
|
||||
if ((M->m[0][0] <= 0.0 ? 0.0 : M->m[0][0] * o.v[0])
|
||||
+ (M->m[1][0] <= 0.0 ? 0.0 : M->m[1][0] * o.v[1])
|
||||
+ (M->m[2][0] <= 0.0 ? 0.0 : M->m[2][0] * o.v[2])
|
||||
+ val
|
||||
< b2->min.v[0]) {
|
||||
return 0;
|
||||
}
|
||||
if ((M->m[0][0] < 0.0 ? M->m[0][0] * o.v[0] : 0.0)
|
||||
+ (M->m[1][0] < 0.0 ? M->m[1][0] * o.v[1] : 0.0)
|
||||
+ (M->m[2][0] < 0.0 ? M->m[2][0] * o.v[2] : 0.0)
|
||||
+ val
|
||||
> b2->max.v[0]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = M->m[1][2] * b1->min.v[1] + b1->min.v[2] * M->m[2][2] + M->m[0][2] * b1->min.v[0] + M->m[3][2];
|
||||
if ((M->m[0][2] <= 0.0 ? 0.0 : M->m[0][2] * o.v[0])
|
||||
+ (M->m[1][2] <= 0.0 ? 0.0 : M->m[1][2] * o.v[1])
|
||||
+ (M->m[2][2] <= 0.0 ? 0.0 : M->m[2][2] * o.v[2])
|
||||
+ val
|
||||
< b2->min.v[2]) {
|
||||
return 0;
|
||||
}
|
||||
if ((M->m[0][2] < 0.0 ? M->m[0][2] * o.v[0] : 0.0)
|
||||
+ (M->m[1][2] < 0.0 ? M->m[1][2] * o.v[1] : 0.0)
|
||||
+ (M->m[2][2] < 0.0 ? M->m[2][2] * o.v[2] : 0.0)
|
||||
+ val
|
||||
> b2->max.v[2]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = b1->min.v[2] * M->m[2][1] + b1->min.v[1] * M->m[1][1] + M->m[0][1] * b1->min.v[0] + M->m[3][1];
|
||||
if ((M->m[0][1] <= 0.0 ? 0.0 : M->m[0][1] * o.v[0])
|
||||
+ (M->m[1][1] <= 0.0 ? 0.0 : M->m[1][1] * o.v[1])
|
||||
+ (M->m[2][1] <= 0.0 ? 0.0 : M->m[2][1] * o.v[2])
|
||||
+ val
|
||||
< b2->min.v[1]) {
|
||||
return 0;
|
||||
}
|
||||
return ((M->m[0][1] < 0.0 ? M->m[0][1] * o.v[0] : 0.0)
|
||||
+ (M->m[1][1] < 0.0 ? M->m[1][1] * o.v[1] : 0.0)
|
||||
+ (M->m[2][1] < 0.0 ? M->m[2][1] * o.v[2] : 0.0)
|
||||
+ val
|
||||
<= b2->max.v[1]);
|
||||
}
|
||||
|
||||
// IDA: int __usercall LineBoxColl@<EAX>(br_vector3 *o@<EAX>, br_vector3 *p@<EDX>, br_bounds *pB@<EBX>, br_vector3 *pHit_point@<ECX>)
|
||||
|
|
|
|||
|
|
@ -212,8 +212,6 @@ void ReinitialiseRenderStuff() {
|
|||
gProgram_state.current_render_top = gProgram_state.current_car.render_top[gProgram_state.cockpit_image_index];
|
||||
gProgram_state.current_render_right = gProgram_state.current_car.render_right[gProgram_state.cockpit_image_index];
|
||||
gProgram_state.current_render_bottom = gProgram_state.current_car.render_bottom[gProgram_state.cockpit_image_index];
|
||||
LOG_DEBUG("renderbottom %d", gProgram_state.current_render_bottom);
|
||||
|
||||
} else {
|
||||
gProgram_state.current_render_top = (gGraf_specs[gGraf_spec_index].total_height / 18 & 0xFFFFFFFE) * gRender_indent;
|
||||
gProgram_state.current_render_left = (gGraf_specs[gGraf_spec_index].total_width / 18 & 0xFFFFFFFC) * gRender_indent;
|
||||
|
|
@ -614,7 +612,8 @@ void DisposeRace() {
|
|||
// IDA: int __cdecl GetScreenSize()
|
||||
int GetScreenSize() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
return gRender_indent;
|
||||
}
|
||||
|
||||
// IDA: void __usercall SetScreenSize(int pNew_size@<EAX>)
|
||||
|
|
|
|||
|
|
@ -159,7 +159,9 @@ tS16 FindNearestPathNode(br_vector3* pActor_coords, br_scalar* pDistance) {
|
|||
// IDA: tS16 __usercall FindNearestPathSection@<AX>(br_vector3 *pActor_coords@<EAX>, br_vector3 *pPath_direction@<EDX>, br_vector3 *pIntersect@<EBX>, br_scalar *pDistance@<ECX>)
|
||||
tS16 FindNearestPathSection(br_vector3* pActor_coords, br_vector3* pPath_direction, br_vector3* pIntersect, br_scalar* pDistance) {
|
||||
LOG_TRACE("(%p, %p, %p, %p)", pActor_coords, pPath_direction, pIntersect, pDistance);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
STUB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: tS16 __usercall FindNearestGeneralSection@<AX>(tCar_spec *pPursuee@<EAX>, br_vector3 *pActor_coords@<EDX>, br_vector3 *pPath_direction@<EBX>, br_vector3 *pIntersect@<ECX>, br_scalar *pDistance)
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ br_scalar gLowest_y_above;
|
|||
br_model* model_unk1;
|
||||
br_material* material_unk1;
|
||||
|
||||
// Note: THIS is the _0 in Mac 3dfx build
|
||||
|
||||
// IDA: int __usercall DRActorToRoot@<EAX>(br_actor *a@<EAX>, br_actor *world@<EDX>, br_matrix34 *m@<EBX>)
|
||||
int DRActorToRoot(br_actor* a, br_actor* world, br_matrix34* m) {
|
||||
LOG_TRACE("(%p, %p, %p)", a, world, m);
|
||||
|
|
@ -292,6 +290,8 @@ int DRModelPick2D_raycast(br_model* model, br_material* material, br_vector3* ra
|
|||
double f_numerator;
|
||||
LOG_TRACE("(%p, %p, %p, %p, %f, %f, %p, %p)", model, material, ray_pos, ray_dir, t_near, t_far, callback, arg);
|
||||
|
||||
t_near -= 0.001;
|
||||
t_far += 0.001;
|
||||
for (group = 0; group < V11MODEL(model)->ngroups; group++) {
|
||||
for (f = 0; f < V11MODEL(model)->groups[group].nfaces; f++) {
|
||||
fp = &V11MODEL(model)->groups[group].faces[f];
|
||||
|
|
@ -309,7 +309,7 @@ int DRModelPick2D_raycast(br_model* model, br_material* material, br_vector3* ra
|
|||
- fp->eqn.v[3];
|
||||
if (!BadDiv_raycast(numerator, d)) {
|
||||
t = -(numerator / d);
|
||||
if (t >= (t_near - 0.001) && t <= (t_far + 0.001)) {
|
||||
if (t >= t_near && t <= t_far) {
|
||||
p.v[0] = ray_dir->v[0] * t;
|
||||
p.v[1] = ray_dir->v[1] * t;
|
||||
p.v[2] = ray_dir->v[2] * t;
|
||||
|
|
@ -384,18 +384,7 @@ int DRModelPick2D_raycast(br_model* model, br_material* material, br_vector3* ra
|
|||
v = 2;
|
||||
}
|
||||
}
|
||||
r = callback(
|
||||
model,
|
||||
this_material,
|
||||
ray_pos,
|
||||
ray_dir,
|
||||
t,
|
||||
f,
|
||||
e,
|
||||
v,
|
||||
&p,
|
||||
&map,
|
||||
arg);
|
||||
r = callback(model, this_material, ray_pos, ray_dir, t, f, e, v, &p, &map, arg);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2612,7 +2612,8 @@ void StopGroovidelic(br_actor* pActor) {
|
|||
int i;
|
||||
tGroovidelic_spec* the_groove;
|
||||
LOG_TRACE("(%p)", pActor);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
STUB();
|
||||
}
|
||||
|
||||
// IDA: void __usercall SetGrooveInterrupt(int pGroove_index@<EAX>, br_matrix34 *pMatrix@<EDX>, int pPath_interrupt@<EBX>, int pObject_interrupt@<ECX>, float pPath_resumption, float pObject_resumption)
|
||||
|
|
|
|||
Loading…
Reference in New Issue