diff --git a/include/light/trace.hh b/include/light/trace.hh index 5642987d..08f4851b 100644 --- a/include/light/trace.hh +++ b/include/light/trace.hh @@ -62,10 +62,10 @@ class modelinfo_t; class raystream_t { public: - virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const modelinfo_t *modelinfo, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) = 0; + virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) = 0; virtual size_t numPushedRays() = 0; - virtual void tracePushedRaysOcclusion() = 0; - virtual void tracePushedRaysIntersection() = 0; + virtual void tracePushedRaysOcclusion(const modelinfo_t *self) = 0; + virtual void tracePushedRaysIntersection(const modelinfo_t *self) = 0; virtual bool getPushedRayOccluded(size_t j) = 0; virtual float getPushedRayDist(size_t j) = 0; virtual float getPushedRayHitDist(size_t j) = 0; @@ -79,11 +79,11 @@ public: virtual void clearPushedRays() = 0; virtual ~raystream_t() {}; - void pushRay(int i, const qvec3f &origin, const qvec3f &dir, float dist, const modelinfo_t *modelinfo) { + void pushRay(int i, const qvec3f &origin, const qvec3f &dir, float dist) { vec3_t originTemp, dirTemp; glm_to_vec3_t(origin, originTemp); glm_to_vec3_t(dir, dirTemp); - this->pushRay(i, originTemp, dirTemp, dist, modelinfo); + this->pushRay(i, originTemp, dirTemp, dist); } qvec3f getPushedRayDir(size_t j) { diff --git a/light/entities.cc b/light/entities.cc index 2123e873..558fb57e 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -1248,11 +1248,11 @@ void EstimateVisibleBoundsAtPoint(const vec3_t point, vec3_t mins, vec3_t maxs) vec3_t dir; UniformPointOnSphere(dir, u1, u2); - rs->pushRay(0, point, dir, 65536.0f, nullptr); + rs->pushRay(0, point, dir, 65536.0f); } } - rs->tracePushedRaysIntersection(); + rs->tracePushedRaysIntersection(nullptr); for (int i=0; igetPushedRayHitDist(i); diff --git a/light/ltface.cc b/light/ltface.cc index bc0dc2dd..35ab285a 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -1491,10 +1491,10 @@ LightFace_Entity(const mbsp_t *bsp, continue; } - rs->pushRay(i, surfpoint, surfpointToLightDir, surfpointToLightDist, modelinfo, color, normalcontrib); + rs->pushRay(i, surfpoint, surfpointToLightDir, surfpointToLightDist, color, normalcontrib); } - rs->tracePushedRaysOcclusion(); + rs->tracePushedRaysOcclusion(modelinfo); total_light_rays += rs->numPushedRays(); int cached_style = entity->style.intValue(); @@ -1594,10 +1594,10 @@ LightFace_Sky(const sun_t *sun, const lightsurf_t *lightsurf, lightmapdict_t *li continue; } - rs->pushRay(i, surfpoint, incoming, MAX_SKY_DIST, modelinfo, color, normalcontrib); + rs->pushRay(i, surfpoint, incoming, MAX_SKY_DIST, color, normalcontrib); } - rs->tracePushedRaysIntersection(); + rs->tracePushedRaysIntersection(modelinfo); /* if sunlight is set, use a style 0 light map */ int cached_style = sun->style; @@ -1718,11 +1718,11 @@ LightFace_Min(const mbsp_t *bsp, const bsp2_dface_t *face, vec3_t surfpointToLightDir; const vec_t surfpointToLightDist = GetDir(surfpoint, *entity.origin.vec3Value(), surfpointToLightDir); - rs->pushRay(i, surfpoint, surfpointToLightDir, surfpointToLightDist, modelinfo); + rs->pushRay(i, surfpoint, surfpointToLightDir, surfpointToLightDist); } } - rs->tracePushedRaysOcclusion(); + rs->tracePushedRaysOcclusion(modelinfo); total_light_rays += rs->numPushedRays(); const int N = rs->numPushedRays(); @@ -2002,14 +2002,14 @@ LightFace_Bounce(const mbsp_t *bsp, const bsp2_dface_t *face, const lightsurf_t glm_to_vec3_t(dir, vplDir); glm_to_vec3_t(indirect, vplColor); - rs->pushRay(i, vplPos, vplDir, dist, lightsurf->modelinfo, vplColor); + rs->pushRay(i, vplPos, vplDir, dist, vplColor); } if (!rs->numPushedRays()) continue; total_bounce_rays += rs->numPushedRays(); - rs->tracePushedRaysOcclusion(); + rs->tracePushedRaysOcclusion(lightsurf->modelinfo); lightmap_t *lightmap = Lightmap_ForStyle(lightmaps, style, lightsurf); @@ -2072,10 +2072,10 @@ LightFace_Bounce(const mbsp_t *bsp, const bsp2_dface_t *face, const lightsurf_t //printf("bad dot\n"); } - rs->pushRay(i, surfpoint, rayDir, 8192, lightsurf->modelinfo); + rs->pushRay(i, surfpoint, rayDir, 8192); } - rs->tracePushedRaysIntersection(); + rs->tracePushedRaysIntersection(lightsurf->modelinfo); qvec3f colorAvg(0); int Nhits = 0; @@ -2200,14 +2200,14 @@ LightFace_SurfaceLight(const lightsurf_t *lightsurf, lightmapdict_t *lightmaps) glm_to_vec3_t(dir, vplDir); glm_to_vec3_t(indirect, vplColor); - rs->pushRay(i, vplPos, vplDir, dist, lightsurf->modelinfo, vplColor); + rs->pushRay(i, vplPos, vplDir, dist, vplColor); } if (!rs->numPushedRays()) continue; total_surflight_rays += rs->numPushedRays(); - rs->tracePushedRaysOcclusion(); + rs->tracePushedRaysOcclusion(lightsurf->modelinfo); const int lightmapstyle = 0; lightmap_t *lightmap = Lightmap_ForStyle(lightmaps, lightmapstyle, lightsurf); @@ -2466,13 +2466,13 @@ DirtAtPoint(const globalconfig_t &cfg, raystream_t *rs, const vec3_t point, cons vec3_t dir; TransformToTangentSpace(normal, myUp, myRt, dirtvec, dir); - rs->pushRay(j, point, dir, cfg.dirtDepth.floatValue(), selfshadow); + rs->pushRay(j, point, dir, cfg.dirtDepth.floatValue()); } Q_assert(rs->numPushedRays() == numDirtVectors); // trace the batch - rs->tracePushedRaysIntersection(); + rs->tracePushedRaysIntersection(selfshadow); // accumulate hitdists for (int j=0; jnormals[i], myUps[i], myRts[i], dirtvec, dir); - rs->pushRay(i, lightsurf->points[i], dir, cfg.dirtDepth.floatValue(), lightsurf->modelinfo); + rs->pushRay(i, lightsurf->points[i], dir, cfg.dirtDepth.floatValue()); } // trace the batch - rs->tracePushedRaysIntersection(); + rs->tracePushedRaysIntersection(lightsurf->modelinfo); // accumulate hitdists for (int k = 0; k < rs->numPushedRays(); k++) { diff --git a/light/trace.cc b/light/trace.cc index 7b40369a..11ad87e6 100644 --- a/light/trace.cc +++ b/light/trace.cc @@ -791,131 +791,9 @@ hittype_t DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const mod throw; //mxd. Silences compiler warning } -class bsp_ray_t { -public: - int _pointindex; - vec3_t _origin, _dir; - float _maxdist; - const dmodel_t *_selfshadow; - vec3_t _color; - vec3_t _normalcontrib; - - // hit info - float _hitdist; - hittype_t _hittype; - const bsp2_dface_t *_hitface; - bool _hit_occluded; - - bsp_ray_t(int i, const vec_t *origin, const vec3_t dir, float dist, const modelinfo_t *modelinfo, const vec_t *color, const vec_t *normalcontrib) : - _pointindex{i}, - _maxdist{dist}, - _selfshadow{ modelinfo != nullptr ? (modelinfo->shadowself.boolValue() ? modelinfo->model : nullptr) : nullptr }, - _hitdist{dist}, - _hittype{hittype_t::NONE}, - _hitface(nullptr), - _hit_occluded{false} { - VectorCopy(origin, _origin); - VectorCopy(dir, _dir); - if (color != nullptr) { - VectorCopy(color, _color); - } - if (normalcontrib != nullptr) { - VectorCopy(normalcontrib, _normalcontrib); - } - } -}; - -class raystream_bsp_t : public raystream_t { -private: - std::vector _rays; - int _maxrays; - -public: - raystream_bsp_t(int maxRays) : - _maxrays { maxRays } {} - - raystream_bsp_t() {} - - virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const modelinfo_t *modelinfo, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) { - bsp_ray_t r { i, origin, dir, dist, modelinfo, color, normalcontrib }; - _rays.push_back(r); - Q_assert(_rays.size() <= _maxrays); - } - - virtual size_t numPushedRays() { - return _rays.size(); - } - - virtual void tracePushedRaysOcclusion() { - if (!_rays.size()) - return; - - for (bsp_ray_t &ray : _rays) { - vec3_t stop; - VectorMA(ray._origin, ray._maxdist, ray._dir, stop); - ray._hit_occluded = !BSP_TestLight(ray._origin, stop, ray._selfshadow); - } - } - - virtual void tracePushedRaysIntersection() { - if (!_rays.size()) - return; - - for (bsp_ray_t &ray : _rays) { - ray._hittype = BSP_DirtTrace(ray._origin, ray._dir, ray._maxdist, ray._selfshadow, &ray._hitdist, nullptr, &ray._hitface); - } - } - - virtual bool getPushedRayOccluded(size_t j) { - return _rays.at(j)._hit_occluded; - } - - virtual float getPushedRayDist(size_t j) { - return _rays.at(j)._maxdist; - } - - virtual float getPushedRayHitDist(size_t j) { - return _rays.at(j)._hitdist; - } - - virtual hittype_t getPushedRayHitType(size_t j) { - return _rays.at(j)._hittype; - } - - virtual const bsp2_dface_t *getPushedRayHitFace(size_t j) { - return _rays.at(j)._hitface; - } - - virtual void getPushedRayDir(size_t j, vec3_t out) { - for (int i=0; i<3; i++) { - out[i] = _rays.at(j)._dir[i]; - } - } - - virtual int getPushedRayPointIndex(size_t j) { - return _rays.at(j)._pointindex; - } - - virtual void getPushedRayColor(size_t j, vec3_t out) { - VectorCopy(_rays.at(j)._color, out); - } - - virtual void getPushedRayNormalContrib(size_t j, vec3_t out) { - VectorCopy(_rays.at(j)._normalcontrib, out); - } - - virtual int getPushedRayDynamicStyle(size_t j) { - return 0; // not supported - } - - virtual void clearPushedRays() { - _rays.clear(); - } -}; - raystream_t *BSP_MakeRayStream(int maxrays) { - return new raystream_bsp_t{maxrays}; + return nullptr; } raystream_t *MakeRayStream(int maxrays) diff --git a/light/trace_embree.cc b/light/trace_embree.cc index 5131dc99..912e512a 100644 --- a/light/trace_embree.cc +++ b/light/trace_embree.cc @@ -45,6 +45,18 @@ public: std::vector triToModelinfo; }; +class raystream_embree_t; + +struct ray_source_info { + raystream_embree_t *raystream; // may be null if this ray is not from a ray stream + const modelinfo_t *self; + + ray_source_info(raystream_embree_t *raystream_, + const modelinfo_t *self_) : + raystream(raystream_), + self(self_) {} +}; + sceneinfo CreateGeometry(const mbsp_t *bsp, RTCScene scene, const std::vector &faces) { @@ -224,15 +236,6 @@ void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float void AddDynamicOccluderToRay(const RTCIntersectContext* context, unsigned rayIndex, int style); -static const unsigned RAYMASK_HASMODEL_SHIFT = 0; -static const unsigned RAYMASK_HASMODEL_MASK = (1 << RAYMASK_HASMODEL_SHIFT); - -static const unsigned RAYMASK_MODELINDEX_SHIFT = 1; -static const unsigned RAYMASK_MODELINDEX_MASK = (0xffff << RAYMASK_MODELINDEX_SHIFT); - -static const unsigned RAYMASK_RAYINDEX_SHIFT = 17; -static const unsigned RAYMASK_RAYINDEX_MASK = (0x7fff << RAYMASK_RAYINDEX_SHIFT); - // called to evaluate transparency template static void @@ -245,7 +248,9 @@ Embree_FilterFuncN(int* valid, { const int VALID = -1; const int INVALID = 0; - + + const ray_source_info *rsi = static_cast(context->userRayExt); + for (size_t i=0; i((mask & RAYMASK_HASMODEL_MASK) >> RAYMASK_HASMODEL_SHIFT); - const unsigned raySourceModelindex = (mask & RAYMASK_MODELINDEX_MASK) >> RAYMASK_MODELINDEX_SHIFT; - const unsigned rayIndex = (mask & RAYMASK_RAYINDEX_MASK) >> RAYMASK_RAYINDEX_SHIFT; + const unsigned rayIndex = mask; - const modelinfo_t *source_modelinfo = hasmodel ? ModelInfoForModel(bsp_static, raySourceModelindex) : nullptr; + const modelinfo_t *source_modelinfo = rsi->self; const modelinfo_t *hit_modelinfo = Embree_LookupModelinfo(geomID, primID); Q_assert(hit_modelinfo != nullptr); @@ -686,7 +689,7 @@ Embree_TraceInit(const mbsp_t *bsp) FreeWindings(skipwindings); } -static RTCRay SetupRay(unsigned rayindex, const vec3_t start, const vec3_t dir, vec_t dist, const modelinfo_t *modelinfo) +static RTCRay SetupRay(unsigned rayindex, const vec3_t start, const vec3_t dir, vec_t dist) { RTCRay ray; VectorCopy(start, ray.org); @@ -698,41 +701,26 @@ static RTCRay SetupRay(unsigned rayindex, const vec3_t start, const vec3_t dir, ray.instID = RTC_INVALID_GEOMETRY_ID; // NOTE: we are not using the ray masking feature of embree, but just using - // this field to store whether the ray is coming from self-shadow geometry - ray.mask = 0; - - if (modelinfo) { - ray.mask |= RAYMASK_HASMODEL_MASK; - - // Hacky.. - const int modelindex = (modelinfo->model - bsp_static->dmodels); - Q_assert(modelindex >= 0 && modelindex < bsp_static->nummodels); - Q_assert(modelindex <= 65535); - - ray.mask |= (static_cast(modelindex) << RAYMASK_MODELINDEX_SHIFT); - } - - // pack the ray index into the rest of the mask - Q_assert(rayindex <= 32767); - ray.mask |= (rayindex << RAYMASK_RAYINDEX_SHIFT); + // this field to store the ray index + ray.mask = rayindex; ray.time = 0.f; return ray; } -static RTCRay SetupRay_StartStop(const vec3_t start, const vec3_t stop, const modelinfo_t *self) +static RTCRay SetupRay_StartStop(const vec3_t start, const vec3_t stop) { vec3_t dir; VectorSubtract(stop, start, dir); vec_t dist = VectorNormalize(dir); - return SetupRay(0, start, dir, dist, self); + return SetupRay(0, start, dir, dist); } //public qboolean Embree_TestLight(const vec3_t start, const vec3_t stop, const modelinfo_t *self) { - RTCRay ray = SetupRay_StartStop(start, stop, self); + RTCRay ray = SetupRay_StartStop(start, stop); rtcOccluded(scene, ray); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) @@ -752,8 +740,14 @@ qboolean Embree_TestSky(const vec3_t start, const vec3_t dirn, const modelinfo_t VectorCopy(dirn, dir_normalized); VectorNormalize(dir_normalized); - RTCRay ray = SetupRay(0, start, dir_normalized, MAX_SKY_DIST, self); - rtcIntersect(scene, ray); + RTCRay ray = SetupRay(0, start, dir_normalized, MAX_SKY_DIST); + + ray_source_info ctx2(nullptr, self); + const RTCIntersectContext ctx = { + RTC_INTERSECT_COHERENT, + static_cast(&ctx2) + }; + rtcIntersect1Ex(scene, &ctx, ray); qboolean hit_sky = (ray.geomID == skygeom.geomID); @@ -772,8 +766,13 @@ qboolean Embree_TestSky(const vec3_t start, const vec3_t dirn, const modelinfo_t //public hittype_t Embree_DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const modelinfo_t *self, vec_t *hitdist_out, plane_t *hitplane_out, const bsp2_dface_t **face_out) { - RTCRay ray = SetupRay(0, start, dirn, dist, self); - rtcIntersect(scene, ray); + RTCRay ray = SetupRay(0, start, dirn, dist); + ray_source_info ctx2(nullptr, self); + const RTCIntersectContext ctx = { + RTC_INTERSECT_COHERENT, + static_cast(&ctx2) + }; + rtcIntersect1Ex(scene, &ctx, ray); if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return hittype_t::NONE; @@ -870,9 +869,9 @@ public: delete[] _ray_dynamic_styles; } - virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const modelinfo_t *modelinfo, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) { + virtual void pushRay(int i, const vec_t *origin, const vec3_t dir, float dist, const vec_t *color = nullptr, const vec_t *normalcontrib = nullptr) { Q_assert(_numrays<_maxrays); - _rays[_numrays] = SetupRay(_numrays, origin, dir, dist, modelinfo); + _rays[_numrays] = SetupRay(_numrays, origin, dir, dist); _rays_maxdist[_numrays] = dist; _point_indices[_numrays] = i; if (color) { @@ -889,27 +888,29 @@ public: return _numrays; } - virtual void tracePushedRaysOcclusion() { + virtual void tracePushedRaysOcclusion(const modelinfo_t *self) { //Q_assert(_state == streamstate_t::READY); if (!_numrays) return; - + + ray_source_info ctx2(this, self); const RTCIntersectContext ctx = { - RTC_INTERSECT_COHERENT, - static_cast(this) + RTC_INTERSECT_COHERENT, + static_cast(&ctx2) }; rtcOccluded1M(scene, &ctx, _rays, _numrays, sizeof(RTCRay)); } - virtual void tracePushedRaysIntersection() { + virtual void tracePushedRaysIntersection(const modelinfo_t *self) { if (!_numrays) return; + ray_source_info ctx2(this, self); const RTCIntersectContext ctx = { - RTC_INTERSECT_COHERENT, - static_cast(this) + RTC_INTERSECT_COHERENT, + static_cast(&ctx2) }; rtcIntersect1M(scene, &ctx, _rays, _numrays, sizeof(RTCRay)); @@ -997,14 +998,15 @@ raystream_t *Embree_MakeRayStream(int maxrays) } void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float opacity, const vec3_t glasscolor) { - if (context == nullptr) { - // FIXME: remove this.. + ray_source_info *ctx = static_cast(context->userRayExt); + raystream_embree_t *rs = ctx->raystream; + + if (rs == nullptr) { + // FIXME: remove this.. once all ray casts use raystreams // happens for bounce lights, e.g. Embree_TestSky return; } - raystream_embree_t *rs = static_cast(context->userRayExt); - // clamp opacity opacity = qmin(qmax(0.0f, opacity), 1.0f); @@ -1034,6 +1036,8 @@ void AddGlassToRay(const RTCIntersectContext* context, unsigned rayIndex, float void AddDynamicOccluderToRay(const RTCIntersectContext* context, unsigned rayIndex, int style) { - raystream_embree_t *rs = static_cast(context->userRayExt); + ray_source_info *ctx = static_cast(context->userRayExt); + raystream_embree_t *rs = ctx->raystream; + rs->_ray_dynamic_styles[rayIndex] = style; }