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:
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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));
|
||||
/*
|
||||
|
30
src/lara.h
30
src/lara.h
@@ -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() {
|
||||
|
36
src/utils.h
36
src/utils.h
@@ -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 ¢er, 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 {
|
||||
|
Reference in New Issue
Block a user