Fixes to light-level detection code.

This commit is contained in:
Dmitry 2019-05-10 13:51:09 +03:00 committed by jeefo
commit fbd42b92d1
6 changed files with 96 additions and 57 deletions

View file

@ -371,7 +371,11 @@ public:
} }
inline int avg (void) const { inline int avg (void) const {
return (red + green + blue) / (sizeof (SimpleColor) / sizeof (int)); return sum () / (sizeof (SimpleColor) / sizeof (int));
}
inline int sum (void) const {
return red + green + blue;
} }
}; };

View file

@ -409,6 +409,7 @@ private:
public: public:
LightMeasure (void) : m_doAnimation (false), m_worldModel (nullptr) { LightMeasure (void) : m_doAnimation (false), m_worldModel (nullptr) {
initializeLightstyles (); initializeLightstyles ();
m_point.reset (); m_point.reset ();
} }
@ -416,8 +417,11 @@ public:
void initializeLightstyles (void); void initializeLightstyles (void);
void animateLight (void); void animateLight (void);
bool recursiveLightPoint (const mnode_t *node, const Vector &start, const Vector &end);
float getLightLevel (const Vector &point); float getLightLevel (const Vector &point);
float getSkiesColor (void);
private:
template <typename S, typename M> bool recursiveLightPoint (const M *node, const Vector &start, const Vector &end);
public: public:
inline void resetWorldModel (void) { inline void resetWorldModel (void) {

View file

@ -54,7 +54,7 @@ typedef struct {
int flags; // sky or slime, no lightmap or 256 subdivision int flags; // sky or slime, no lightmap or 256 subdivision
} mtexinfo_t; } mtexinfo_t;
typedef struct mnode_s { typedef struct mnode_hw_s {
int contents; // 0, to differentiate from leafs int contents; // 0, to differentiate from leafs
int visframe; // node needs to be traversed if current int visframe; // node needs to be traversed if current
float minmaxs[6]; // for bounding box culling float minmaxs[6]; // for bounding box culling
@ -63,13 +63,24 @@ typedef struct mnode_s {
struct mnode_s *children[2]; struct mnode_s *children[2];
unsigned short firstsurface; unsigned short firstsurface;
unsigned short numsurfaces; unsigned short numsurfaces;
} mnode_hw_t;
typedef struct mnode_s {
int contents; // 0, to differentiate from leafs
int visframe; // node needs to be traversed if current
short minmaxs[6]; // for bounding box culling
struct mnode_s *parent;
mplane_t *plane;
struct mnode_s *children[2];
unsigned short firstsurface;
unsigned short numsurfaces;
} mnode_t; } mnode_t;
typedef struct { typedef struct {
byte r, g, b; byte r, g, b;
} color24; } color24;
typedef struct msurface_s { typedef struct msurface_hw_s {
int visframe; // should be drawn when node is crossed int visframe; // should be drawn when node is crossed
mplane_t *plane; // pointer to shared plane mplane_t *plane; // pointer to shared plane
int flags; // see SURF_ #defines int flags; // see SURF_ #defines
@ -86,9 +97,26 @@ typedef struct msurface_s {
int lightmaptexturenum; int lightmaptexturenum;
byte styles[MAXLIGHTMAPS]; byte styles[MAXLIGHTMAPS];
int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap
msurface_s* lightmapchain; // for new dlights rendering (was cached_dlight) qboolean cached_dlight; // true if dynamic light in cache
color24 *samples; // note: this is the actual lightmap data for this surface color24 *samples; // note: this is the actual lightmap data for this surface
struct decal_t *pdecals; struct decal_t *pdecals;
} msurface_hw_t;
typedef struct msurface_s {
int visframe; // should be drawn when node is crossed
int dlightframe; // last frame the surface was checked by an animated light
int dlightbits; // dynamically generated. Indicates if the surface illumination is modified by an animated light.
mplane_t *plane; // pointer to shared plane
int flags; // see SURF_ #defines
int firstedge; // look up in model->surfedges[], negative numbers
int numedges; // are backwards edges
struct surfcache_s *cachespots[4]; // surface generation data
short texturemins[2]; // smallest s/t position on the surface.
short extents[2]; // ?? s/t texture size, 1..256 for all non-sky surfaces
mtexinfo_t *texinfo;
byte styles[MAXLIGHTMAPS]; // index into d_lightstylevalue[] for animated lights no one surface can be effected by more than 4 animated lights.
color24 *samples;
struct decal_t *pdecals;
} msurface_t; } msurface_t;
typedef struct cache_user_s { typedef struct cache_user_s {

View file

@ -9,6 +9,10 @@
#include <yapb.h> #include <yapb.h>
ConVar sv_skycolor_r ("sv_skycolor_r", nullptr, VT_NOREGISTER);
ConVar sv_skycolor_g ("sv_skycolor_g", nullptr, VT_NOREGISTER);
ConVar sv_skycolor_b ("sv_skycolor_b", nullptr, VT_NOREGISTER);
Engine::Engine (void) { Engine::Engine (void) {
m_startEntity = nullptr; m_startEntity = nullptr;
m_localEntity = nullptr; m_localEntity = nullptr;
@ -1138,7 +1142,7 @@ void LightMeasure::animateLight (void) {
} }
} }
inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector &start, const Vector &end) { template <typename S, typename M> bool LightMeasure::recursiveLightPoint (const M *node, const Vector &start, const Vector &end) {
if (node->contents < 0) { if (node->contents < 0) {
return false; return false;
} }
@ -1153,7 +1157,7 @@ inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector
// if they're both on the same side of the plane, don't bother to split just check the appropriate child // if they're both on the same side of the plane, don't bother to split just check the appropriate child
if ((back < 0.0f) == side) { if ((back < 0.0f) == side) {
return recursiveLightPoint (node->children[side], start, end); return recursiveLightPoint <S, M> (reinterpret_cast <M *> (node->children[side]), start, end);
} }
// calculate mid point // calculate mid point
@ -1161,7 +1165,7 @@ inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector
auto mid = start + (end - start) * frac; auto mid = start + (end - start) * frac;
// go down front side // go down front side
if (recursiveLightPoint (node->children[side], start, mid)) { if (recursiveLightPoint <S, M> (reinterpret_cast <M *> (node->children[side]), start, mid)) {
return true; // hit something return true; // hit something
} }
@ -1173,7 +1177,7 @@ inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector
// check for impact on this node // check for impact on this node
// lightspot = mid; // lightspot = mid;
// lightplane = plane; // lightplane = plane;
auto surf = reinterpret_cast <msurface_t *> (m_worldModel->surfaces) + node->firstsurface; auto surf = reinterpret_cast <S *> (m_worldModel->surfaces) + node->firstsurface;
for (int i = 0; i < node->numsurfaces; i++, surf++) { for (int i = 0; i < node->numsurfaces; i++, surf++) {
if (surf->flags & SURF_DRAWTILED) { if (surf->flags & SURF_DRAWTILED) {
@ -1228,7 +1232,7 @@ inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector
return true; return true;
} }
return recursiveLightPoint (node->children[!side], mid, end); // go down back side return recursiveLightPoint <S, M> (reinterpret_cast <M *> (node->children[!side]), mid, end); // go down back side
} }
float LightMeasure::getLightLevel (const Vector &point) { float LightMeasure::getLightLevel (const Vector &point) {
@ -1243,5 +1247,16 @@ float LightMeasure::getLightLevel (const Vector &point) {
Vector endPoint (point); Vector endPoint (point);
endPoint.z -= 2048.0f; endPoint.z -= 2048.0f;
return recursiveLightPoint (m_worldModel->nodes, point, endPoint) == false ? 0.0f : 100 * cr::sqrtf (cr::min (75.0f, static_cast <float> (m_point.avg ())) / 75.0f); // it's depends if we're are on dedicated or on listenserver
auto recursiveCheck = [&] (void) -> bool {
if (!engine.isDedicated () || (g_gameFlags & GAME_XASH_ENGINE)) {
return recursiveLightPoint <msurface_hw_t, mnode_hw_t> (reinterpret_cast <mnode_hw_t *> (m_worldModel->nodes), point, endPoint);
}
return recursiveLightPoint <msurface_t, mnode_t> (m_worldModel->nodes, point, endPoint);
};
return !recursiveCheck () ? 0.0f : 100 * cr::sqrtf (cr::min (75.0f, static_cast <float> (m_point.avg ())) / 75.0f);
}
float LightMeasure::getSkiesColor (void) {
return sv_skycolor_r.flt () + sv_skycolor_g.flt () + sv_skycolor_b.flt ();
} }

View file

@ -201,6 +201,11 @@ int handleBotCommands (edict_t *ent, const char *arg0, const char *arg1, const c
engine.centerPrint ("You're dead, and have no access to this menu"); engine.centerPrint ("You're dead, and have no access to this menu");
} }
} }
else if (stricmp (arg0, "glp") == 0) {
for (int i = 0; i < waypoints.length (); i++) {
engine.print ("%d - %f - %f", i, waypoints.getLightLevel (i), illum.getSkiesColor ());
}
}
// waypoint manimupulation (really obsolete, can be edited through menu) (supported only on listen server) // waypoint manimupulation (really obsolete, can be edited through menu) (supported only on listen server)
else if (stricmp (arg0, "waypoint") == 0 || stricmp (arg0, "wp") == 0 || stricmp (arg0, "wpt") == 0) { else if (stricmp (arg0, "waypoint") == 0 || stricmp (arg0, "wp") == 0 || stricmp (arg0, "wpt") == 0) {
@ -353,18 +358,6 @@ int handleBotCommands (edict_t *ent, const char *arg0, const char *arg1, const c
waypoints.cachePoint (); waypoints.cachePoint ();
} }
else if (stricmp (arg1, "glp") == 0) {
for (int i = 0; i < waypoints.length (); i++) {
engine.print ("%d - %f", i, waypoints.getLightLevel (i));
}
}
// do a cleanup // do a cleanup
else if (stricmp (arg1, "clean") == 0) { else if (stricmp (arg1, "clean") == 0) {
if (!isEmptyStr (arg2)) { if (!isEmptyStr (arg2)) {

View file

@ -1370,10 +1370,6 @@ void Waypoint::initVisibility (void) {
void Waypoint::initLightLevels (void) { void Waypoint::initLightLevels (void) {
// this function get's the light level for each waypoin on the map // this function get's the light level for each waypoin on the map
// @todo: re-enable when working on flashlights
illum.enableAnimation (false);
return;
#if 0
// no waypoints ? no light levels, and only one-time init // no waypoints ? no light levels, and only one-time init
if (!m_numWaypoints || !cr::fzero (m_waypointLightLevel[0])) { if (!m_numWaypoints || !cr::fzero (m_waypointLightLevel[0])) {
return; return;
@ -1385,7 +1381,6 @@ void Waypoint::initLightLevels (void) {
} }
// disable lightstyle animations on finish (will be auto-enabled on mapchange) // disable lightstyle animations on finish (will be auto-enabled on mapchange)
illum.enableAnimation (false); illum.enableAnimation (false);
#endif
} }
void Waypoint::initTypes (void) { void Waypoint::initTypes (void) {