From fbd42b92d1f940b3bc07f9857a998ee60b2bf593 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 10 May 2019 13:51:09 +0300 Subject: [PATCH] Fixes to light-level detection code. --- include/corelib.h | 6 ++- include/engine.h | 6 ++- include/engine/model.h | 90 +++++++++++++++++++++++++++--------------- source/engine.cpp | 29 ++++++++++---- source/interface.cpp | 17 +++----- source/waypoint.cpp | 5 --- 6 files changed, 96 insertions(+), 57 deletions(-) diff --git a/include/corelib.h b/include/corelib.h index 12b3216..e121a33 100644 --- a/include/corelib.h +++ b/include/corelib.h @@ -371,7 +371,11 @@ public: } 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; } }; diff --git a/include/engine.h b/include/engine.h index e2dc3a9..a6b9bb3 100644 --- a/include/engine.h +++ b/include/engine.h @@ -409,6 +409,7 @@ private: public: LightMeasure (void) : m_doAnimation (false), m_worldModel (nullptr) { initializeLightstyles (); + m_point.reset (); } @@ -416,8 +417,11 @@ public: void initializeLightstyles (void); void animateLight (void); - bool recursiveLightPoint (const mnode_t *node, const Vector &start, const Vector &end); float getLightLevel (const Vector &point); + float getSkiesColor (void); + +private: + template bool recursiveLightPoint (const M *node, const Vector &start, const Vector &end); public: inline void resetWorldModel (void) { diff --git a/include/engine/model.h b/include/engine/model.h index cf55458..006be1d 100644 --- a/include/engine/model.h +++ b/include/engine/model.h @@ -50,17 +50,28 @@ typedef struct { typedef struct { float vecs[2][4]; // [s/t] unit vectors in world space [i][3] is the s/t offset relative to the origin s or t = dot( 3Dpoint, vecs[i] ) + vecs[i][3] float mipadjust; // mipmap limits for very small surfaces - struct texture_t* texture; + struct texture_t *texture; int flags; // sky or slime, no lightmap or 256 subdivision } mtexinfo_t; +typedef struct mnode_hw_s { + int contents; // 0, to differentiate from leafs + int visframe; // node needs to be traversed if current + float 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_hw_t; + typedef struct mnode_s { int contents; // 0, to differentiate from leafs int visframe; // node needs to be traversed if current - float minmaxs[6]; // for bounding box culling - struct mnode_s* parent; - mplane_t* plane; - struct mnode_s* children[2]; + 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; @@ -69,26 +80,43 @@ typedef struct { byte r, g, b; } color24; -typedef struct msurface_s { +typedef struct msurface_hw_s { 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 firstedge; // look up in model->surfedges[], negative numbers int numedges; // are backwards edges short texturemins[2]; short extents[2]; int light_s, light_t; // gl lightmap coordinates - struct glpoly_t* polys; // multiple if warped - struct msurface_s* texturechain; - mtexinfo_t* texinfo; + struct glpoly_t *polys; // multiple if warped + struct msurface_s *texturechain; + mtexinfo_t *texinfo; 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. int lightmaptexturenum; byte styles[MAXLIGHTMAPS]; int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap - msurface_s* lightmapchain; // for new dlights rendering (was cached_dlight) - color24* samples; // note: this is the actual lightmap data for this surface - struct decal_t* pdecals; + qboolean cached_dlight; // true if dynamic light in cache + color24 *samples; // note: this is the actual lightmap data for this surface + 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; typedef struct cache_user_s { @@ -96,8 +124,8 @@ typedef struct cache_user_s { } cache_user_t; typedef struct hull_s { - struct dclipnode_t* clipnodes; - mplane_t* planes; + struct dclipnode_t *clipnodes; + mplane_t *planes; int firstclipnode; int lastclipnode; vec3_t clip_mins; @@ -109,40 +137,40 @@ typedef struct model_s { qboolean needload; // bmodels and sprites don't cache normally int type; // model type int numframes; // sprite's framecount - byte* mempool; // private mempool (was synctype) + byte *mempool; // private mempool (was synctype) int flags; // hl compatibility vec3_t mins, maxs; // bounding box at angles '0 0 0' float radius; int firstmodelsurface; int nummodelsurfaces; int numsubmodels; - struct dmodel_t* submodels; // or studio animations + struct dmodel_t *submodels; // or studio animations int numplanes; - mplane_t* planes; + mplane_t *planes; int numleafs; // number of visible leafs, not counting 0 - struct mleaf_t* leafs; + struct mleaf_t *leafs; int numvertexes; - mvertex_t* vertexes; + mvertex_t *vertexes; int numedges; - struct medge_t* edges; + struct medge_t *edges; int numnodes; - mnode_t* nodes; + mnode_t *nodes; int numtexinfo; - mtexinfo_t* texinfo; + mtexinfo_t *texinfo; int numsurfaces; - msurface_t* surfaces; + msurface_t *surfaces; int numsurfedges; - int* surfedges; + int *surfedges; int numclipnodes; - struct dclipnode_t* clipnodes; + struct dclipnode_t *clipnodes; int nummarksurfaces; - msurface_t** marksurfaces; + msurface_t **marksurfaces; hull_t hulls[MAX_MAP_HULLS]; int numtextures; - texture_t** textures; - byte* visdata; - color24* lightdata; - char* entities; + texture_t **textures; + byte *visdata; + color24 *lightdata; + char *entities; cache_user_t cache; // only access through Mod_Extradata } model_t; diff --git a/source/engine.cpp b/source/engine.cpp index 8fd3bfe..e620044 100644 --- a/source/engine.cpp +++ b/source/engine.cpp @@ -9,6 +9,10 @@ #include +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) { m_startEntity = 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 bool LightMeasure::recursiveLightPoint (const M *node, const Vector &start, const Vector &end) { if (node->contents < 0) { 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 ((back < 0.0f) == side) { - return recursiveLightPoint (node->children[side], start, end); + return recursiveLightPoint (reinterpret_cast (node->children[side]), start, end); } // calculate mid point @@ -1161,7 +1165,7 @@ inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector auto mid = start + (end - start) * frac; // go down front side - if (recursiveLightPoint (node->children[side], start, mid)) { + if (recursiveLightPoint (reinterpret_cast (node->children[side]), start, mid)) { return true; // hit something } @@ -1173,7 +1177,7 @@ inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector // check for impact on this node // lightspot = mid; // lightplane = plane; - auto surf = reinterpret_cast (m_worldModel->surfaces) + node->firstsurface; + auto surf = reinterpret_cast (m_worldModel->surfaces) + node->firstsurface; for (int i = 0; i < node->numsurfaces; i++, surf++) { if (surf->flags & SURF_DRAWTILED) { @@ -1228,7 +1232,7 @@ inline bool LightMeasure::recursiveLightPoint (const mnode_t *node, const Vector return true; } - return recursiveLightPoint (node->children[!side], mid, end); // go down back side + return recursiveLightPoint (reinterpret_cast (node->children[!side]), mid, end); // go down back side } float LightMeasure::getLightLevel (const Vector &point) { @@ -1243,5 +1247,16 @@ float LightMeasure::getLightLevel (const Vector &point) { Vector endPoint (point); endPoint.z -= 2048.0f; - return recursiveLightPoint (m_worldModel->nodes, point, endPoint) == false ? 0.0f : 100 * cr::sqrtf (cr::min (75.0f, static_cast (m_point.avg ())) / 75.0f); -} \ No newline at end of file + // 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 (reinterpret_cast (m_worldModel->nodes), point, endPoint); + } + return recursiveLightPoint (m_worldModel->nodes, point, endPoint); + }; + return !recursiveCheck () ? 0.0f : 100 * cr::sqrtf (cr::min (75.0f, static_cast (m_point.avg ())) / 75.0f); +} + +float LightMeasure::getSkiesColor (void) { + return sv_skycolor_r.flt () + sv_skycolor_g.flt () + sv_skycolor_b.flt (); +} diff --git a/source/interface.cpp b/source/interface.cpp index ef6ab2c..5dd05d1 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -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"); } } + 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) 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 (); } - 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 else if (stricmp (arg1, "clean") == 0) { if (!isEmptyStr (arg2)) { diff --git a/source/waypoint.cpp b/source/waypoint.cpp index 95ea263..080b9da 100644 --- a/source/waypoint.cpp +++ b/source/waypoint.cpp @@ -1370,10 +1370,6 @@ void Waypoint::initVisibility (void) { void Waypoint::initLightLevels (void) { // 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 if (!m_numWaypoints || !cr::fzero (m_waypointLightLevel[0])) { return; @@ -1385,7 +1381,6 @@ void Waypoint::initLightLevels (void) { } // disable lightstyle animations on finish (will be auto-enabled on mapchange) illum.enableAnimation (false); -#endif } void Waypoint::initTypes (void) {