light: change CalcPoints to only trace the model the face belongs to
This commit is contained in:
parent
2a3b87bf1f
commit
fcc54c547f
|
|
@ -54,6 +54,9 @@ qboolean TestSky(const vec3_t start, const vec3_t dirn, const dmodel_t *self);
|
|||
qboolean TestLight(const vec3_t start, const vec3_t stop, const dmodel_t *self);
|
||||
hittype_t DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const dmodel_t *self, vec_t *hitdist_out, plane_t *hitplane_out, const bsp2_dface_t **face_out);
|
||||
|
||||
// used for CalcPoints
|
||||
bool IntersectSingleModel(const vec3_t start, const vec3_t dir, vec_t dist, const dmodel_t *self, vec_t *hitdist_out);
|
||||
|
||||
class raystream_t {
|
||||
public:
|
||||
virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const dmodel_t *selfshadow, const vec_t *color = nullptr) = 0;
|
||||
|
|
@ -77,6 +80,7 @@ void Embree_TraceInit(const bsp2_t *bsp);
|
|||
qboolean Embree_TestSky(const vec3_t start, const vec3_t dirn, const dmodel_t *self);
|
||||
qboolean Embree_TestLight(const vec3_t start, const vec3_t stop, const dmodel_t *self);
|
||||
hittype_t Embree_DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const dmodel_t *self, vec_t *hitdist_out, plane_t *hitplane_out, const bsp2_dface_t **face_out);
|
||||
bool Embree_IntersectSingleModel(const vec3_t start, const vec3_t dir, vec_t dist, const dmodel_t *self, vec_t *hitdist_out);
|
||||
|
||||
raystream_t *Embree_MakeRayStream(int maxrays);
|
||||
|
||||
|
|
|
|||
|
|
@ -591,10 +591,6 @@ CheckObstructed(const lightsurf_t *surf, const vec3_t offset, const vec_t us, co
|
|||
TexCoordToWorld(us + (x/10.0), ut + (y/10.0), &surf->texorg, testpoint);
|
||||
VectorAdd(testpoint, offset, testpoint);
|
||||
|
||||
plane_t hitplane = {0};
|
||||
|
||||
const dmodel_t *selfshadow = (surf->modelinfo->shadowself.boolValue()) ? surf->modelinfo->model : NULL;
|
||||
|
||||
vec3_t dirn;
|
||||
VectorSubtract(testpoint, surf->midpoint, dirn);
|
||||
vec_t dist = VectorNormalize(dirn);
|
||||
|
|
@ -604,7 +600,7 @@ CheckObstructed(const lightsurf_t *surf, const vec3_t offset, const vec_t us, co
|
|||
|
||||
// trace from surf->midpoint to testpoint
|
||||
vec_t hitdist = 0;
|
||||
if (hittype_t::SOLID == DirtTrace(surf->midpoint, dirn, dist, selfshadow, &hitdist, &hitplane, NULL)) {
|
||||
if (IntersectSingleModel(surf->midpoint, dirn, dist, surf->modelinfo->model, &hitdist)) {
|
||||
// make a corrected point
|
||||
VectorMA(surf->midpoint, qmax(0.0f, hitdist - 0.25f), dirn, corrected);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -694,6 +694,24 @@ BSP_DirtTrace(const vec3_t start, const vec3_t dirn, const vec_t dist, const dmo
|
|||
return hittype_t::NONE;
|
||||
}
|
||||
|
||||
bool BSP_IntersectSingleModel(const vec3_t start, const vec3_t dirn, vec_t dist, const dmodel_t *self, vec_t *hitdist_out)
|
||||
{
|
||||
vec3_t stop;
|
||||
VectorMA(start, dist, dirn, stop);
|
||||
|
||||
traceinfo_t ti = {0};
|
||||
VectorCopy(dirn, ti.dir);
|
||||
|
||||
if (TraceFaces (&ti, self->headnode[0], start, stop)) {
|
||||
if (hitdist_out) {
|
||||
vec3_t delta;
|
||||
VectorSubtract(ti.point, start, delta);
|
||||
*hitdist_out = VectorLength(delta);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
|
|
@ -822,6 +840,19 @@ hittype_t DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const dmo
|
|||
Error("no backend available");
|
||||
}
|
||||
|
||||
bool IntersectSingleModel(const vec3_t start, const vec3_t dir, vec_t dist, const dmodel_t *self, vec_t *hitdist_out)
|
||||
{
|
||||
#ifdef HAVE_EMBREE
|
||||
if (rtbackend == backend_embree) {
|
||||
return Embree_IntersectSingleModel(start, dir, dist, self, hitdist_out);
|
||||
}
|
||||
#endif
|
||||
if (rtbackend == backend_bsp) {
|
||||
return BSP_IntersectSingleModel(start, dir, dist, self, hitdist_out);
|
||||
}
|
||||
Error("no backend available");
|
||||
}
|
||||
|
||||
class bsp_ray_t {
|
||||
public:
|
||||
int _pointindex;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
static constexpr float MAX_SKY_RAY_DEPTH = 8192.0f;
|
||||
|
||||
/**
|
||||
|
|
@ -101,6 +103,29 @@ CreateGeometry(const bsp2_t *bsp, RTCScene scene, const std::vector<const bsp2_d
|
|||
return s;
|
||||
}
|
||||
|
||||
// Creates a scene with just the faces in this model,
|
||||
// used by CalcPoints.
|
||||
// Liquids are left out but sky faces are included
|
||||
RTCScene CreatePerModelScene(RTCDevice device, const bsp2_t *bsp, const dmodel_t *model) {
|
||||
std::vector<const bsp2_dface_t *> faces;
|
||||
|
||||
for (int i=0; i<model->numfaces; i++) {
|
||||
const bsp2_dface_t *face = &bsp->dfaces[model->firstface + i];
|
||||
|
||||
const char *texname = Face_TextureName(bsp, face);
|
||||
if (texname[0] == '*') {
|
||||
// ignore liquids
|
||||
} else {
|
||||
faces.push_back(face);
|
||||
}
|
||||
}
|
||||
|
||||
RTCScene scene = rtcDeviceNewScene(device, RTC_SCENE_STATIC | RTC_SCENE_COHERENT, RTC_INTERSECT1);
|
||||
sceneinfo geom = CreateGeometry(bsp, scene, faces);
|
||||
rtcCommit(scene);
|
||||
return scene;
|
||||
}
|
||||
|
||||
RTCDevice device;
|
||||
RTCScene scene;
|
||||
/* global shadow casters */
|
||||
|
|
@ -225,6 +250,8 @@ Embree_FilterFuncN(int* valid,
|
|||
}
|
||||
}
|
||||
|
||||
vector<RTCScene> perModelScenes;
|
||||
|
||||
void
|
||||
Embree_TraceInit(const bsp2_t *bsp)
|
||||
{
|
||||
|
|
@ -267,6 +294,12 @@ Embree_TraceInit(const bsp2_t *bsp)
|
|||
Error("embree must be built with ray masks disabled");
|
||||
}
|
||||
|
||||
// set up per-model scenes, used for CalcPoints
|
||||
for (int i=0; i<bsp->nummodels; i++) {
|
||||
perModelScenes.push_back(CreatePerModelScene(device, bsp, &bsp->dmodels[i]));
|
||||
}
|
||||
assert(perModelScenes.size() == bsp->nummodels);
|
||||
|
||||
scene = rtcDeviceNewScene(device, RTC_SCENE_STATIC | RTC_SCENE_COHERENT, RTC_INTERSECT1 | RTC_INTERSECT_STREAM);
|
||||
skygeom = CreateGeometry(bsp, scene, skyfaces);
|
||||
solidgeom = CreateGeometry(bsp, scene, solidfaces);
|
||||
|
|
@ -380,6 +413,24 @@ hittype_t Embree_DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, co
|
|||
}
|
||||
}
|
||||
|
||||
// used for CalcPoints
|
||||
bool Embree_IntersectSingleModel(const vec3_t start, const vec3_t dir, vec_t dist, const dmodel_t *self, vec_t *hitdist_out)
|
||||
{
|
||||
const int modelnum = self - bsp_static->dmodels;
|
||||
RTCScene singleModelScene = perModelScenes.at(modelnum);
|
||||
|
||||
RTCRay ray = SetupRay(start, dir, dist, nullptr);
|
||||
rtcIntersect(singleModelScene, ray);
|
||||
|
||||
if (ray.geomID == RTC_INVALID_GEOMETRY_ID)
|
||||
return false; // no obstruction
|
||||
|
||||
if (hitdist_out) {
|
||||
*hitdist_out = ray.tfar;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//enum class streamstate_t {
|
||||
// READY, DID_OCCLUDE, DID_INTERSECT
|
||||
//};
|
||||
|
|
|
|||
Loading…
Reference in New Issue