Awfully complicated camera collision bits (#54)

* Awfully complicated camera collision bits
This commit is contained in:
Jeff Harris 2021-07-18 22:27:08 +12:00 committed by GitHub
parent a8f34c5815
commit 3244bdbd55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 887 additions and 40 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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 {

View File

@ -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);

View File

@ -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>)

View File

@ -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>)

View File

@ -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;

View File

@ -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>)

View File

@ -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>)

View File

@ -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)

View File

@ -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;
}

View File

@ -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)