1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-13 08:34:32 +02:00

#3 fix flash lights after death, fix check hit (now using OBB and spheres instead of AABB)

This commit is contained in:
XProger
2017-05-20 02:43:35 +03:00
parent 669350a02d
commit 821f5826c0
4 changed files with 70 additions and 29 deletions

View File

@@ -254,16 +254,17 @@ struct Controller {
return animation.getBoundingBox(vec3(0, 0, 0), oriented ? getEntity().rotation.value / 0x4000 : 0);
}
void getSpheres(Sphere *spheres) {
void getSpheres(Sphere *spheres, int &count) {
TR::Model *m = getModel();
Basis basis(getMatrix());
count = 0;
for (int i = 0; i < m->mCount; i++) {
TR::Mesh &aMesh = level->meshes[level->meshOffsets[m->mStart + i]];
if (aMesh.radius <= 0) continue;
vec3 center = animation.getJoints(basis, i, true) * aMesh.center;
spheres[i] = Sphere(center, aMesh.radius);
spheres[count++] = Sphere(center, aMesh.radius);
}
}
int collide(Controller *controller, bool checkBoxes = true) {
@@ -280,18 +281,18 @@ struct Controller {
Sphere aSpheres[34];
Sphere bSpheres[34];
int aCount, bCount;
getSpheres(aSpheres);
controller->getSpheres(bSpheres);
getSpheres(aSpheres, aCount);
controller->getSpheres(bSpheres, bCount);
int mask = 0;
for (int i = 0; i < a->mCount; i++)
if (aSpheres[i].radius > 0.0f)
for (int j = 0; j < b->mCount; j++)
if (bSpheres[j].radius > 0.0f && bSpheres[j].intersect(aSpheres[i])) {
mask |= (1 << i);
break;
}
for (int i = 0; i < aCount; i++)
for (int j = 0; j < bCount; j++)
if (bSpheres[j].intersect(aSpheres[i])) {
mask |= (1 << i);
break;
}
return mask;
}

View File

@@ -498,9 +498,8 @@ namespace Debug {
bool bboxIntersect = false;
Sphere spheres[34];
ASSERT(m->mCount <= 34);
controller->getSpheres(spheres);
int mask = 0;
for (int j = 0; j < level.entitiesCount; j++) {
TR::Entity &t = level.entities[j];
@@ -515,8 +514,11 @@ namespace Debug {
Box box = controller->getBoundingBoxLocal();
Debug::Draw::box(matrix, box.min, box.max, bboxIntersect ? vec4(1, 0, 0, 1): vec4(1));
Sphere spheres[34];
int count;
controller->getSpheres(spheres, count);
for (int joint = 0; joint < m->mCount; joint++) {
for (int joint = 0; joint < count; joint++) {
Sphere &sphere = spheres[joint];
Debug::Draw::sphere(sphere.center, sphere.radius, (mask & (1 << joint)) ? vec4(1, 0, 0, 0.5f) : vec4(0, 1, 1, 0.5f));
/*

View File

@@ -1088,15 +1088,26 @@ struct Lara : Character {
bool checkHit(int target, const vec3 &from, const vec3 &to, vec3 &point) {
TR::Entity &e = level->entities[target];
Box box = ((Controller*)e.controller)->getBoundingBox();
Controller *controller = (Controller*)e.controller;
Box box = controller->getBoundingBoxLocal();
mat4 m = controller->getMatrix();
float t;
vec3 v = (to - from);
vec3 dir = v.normal();
if (box.intersect(from, dir, t) && v.length() > t) {
point = from + dir * t;
return true;
} else
return false;
vec3 v = to - from;
if (box.intersect(m, from, v, t)) {
v = v.normal();
Sphere spheres[34];
int count;
controller->getSpheres(spheres, count);
for (int i = 0; i < count; i++)
if (spheres[i].intersect(from, v, t)) {
point = from + v * t;
return true;
}
}
return false;
}
virtual void cmdEmpty() {
@@ -1145,6 +1156,9 @@ struct Lara : Character {
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation + 1);
}
if (health <= 0)
Core::lightColor[1 + 0] = Core::lightColor[1 + 1] = vec4(0, 0, 0, 1);
};
bool waterOut() {

View File

@@ -868,19 +868,24 @@ struct Box {
}
bool intersect(const vec3 &rayPos, const vec3 &rayDir, float &t) const {
float t1 = INF, t0 = -t1;
float tMax = INF, tMin = -tMax;
for (int i = 0; i < 3; i++)
if (rayDir[i] != 0) {
float lo = (min[i] - rayPos[i]) / rayDir[i];
float hi = (max[i] - rayPos[i]) / rayDir[i];
t0 = ::max(t0, ::min(lo, hi));
t1 = ::min(t1, ::max(lo, hi));
tMin = ::max(tMin, ::min(lo, hi));
tMax = ::min(tMax, ::max(lo, hi));
} else
if (rayPos[i] < min[i] || rayPos[i] > max[i])
return false;
t = t0;
return (t0 <= t1) && (t1 > 0);
t = tMin;
return (tMin <= tMax) && (tMax > 0.0f);
}
bool intersect(const mat4 &matrix, const vec3 &rayPos, const vec3 &rayDir, float &t) const {
mat4 mInv = matrix.inverse();
return intersect(mInv * rayPos, (mInv * vec4(rayDir, 0)).xyz, t);
}
};
@@ -891,11 +896,30 @@ struct Sphere {
Sphere() {}
Sphere(const vec3 &center, float radius) : center(center), radius(radius) {}
bool intersect(const Sphere &s) {
bool intersect(const Sphere &s) const {
float d = (center - s.center).length2();
float r = (radius + s.radius);
return d < r * r;
}
bool intersect(const vec3 &rayPos, const vec3 &rayDir, float &t) const {
vec3 v = rayPos - center;
float h = -v.dot(rayDir);
float d = h * h + radius * radius - v.length2();
if (d > 0.0f) {
d = sqrtf(d);
float tMin = h - d;
float tMax = h + d;
if (tMax > 0.0f) {
if (tMin < 0.0f)
tMin = 0.0f;
t = tMin;
return true;
}
}
return false;
}
};
struct Stream {