Fixes to light-level detection code.
This commit is contained in:
parent
117db06048
commit
fbd42b92d1
6 changed files with 96 additions and 57 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -50,17 +50,28 @@ typedef struct {
|
||||||
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 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
|
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
|
int flags; // sky or slime, no lightmap or 256 subdivision
|
||||||
} mtexinfo_t;
|
} 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 {
|
typedef struct mnode_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
|
short minmaxs[6]; // for bounding box culling
|
||||||
struct mnode_s* parent;
|
struct mnode_s *parent;
|
||||||
mplane_t* plane;
|
mplane_t *plane;
|
||||||
struct mnode_s* children[2];
|
struct mnode_s *children[2];
|
||||||
unsigned short firstsurface;
|
unsigned short firstsurface;
|
||||||
unsigned short numsurfaces;
|
unsigned short numsurfaces;
|
||||||
} mnode_t;
|
} mnode_t;
|
||||||
|
|
@ -69,26 +80,43 @@ 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
|
||||||
int firstedge; // look up in model->surfedges[], negative numbers
|
int firstedge; // look up in model->surfedges[], negative numbers
|
||||||
int numedges; // are backwards edges
|
int numedges; // are backwards edges
|
||||||
short texturemins[2];
|
short texturemins[2];
|
||||||
short extents[2];
|
short extents[2];
|
||||||
int light_s, light_t; // gl lightmap coordinates
|
int light_s, light_t; // gl lightmap coordinates
|
||||||
struct glpoly_t* polys; // multiple if warped
|
struct glpoly_t *polys; // multiple if warped
|
||||||
struct msurface_s* texturechain;
|
struct msurface_s *texturechain;
|
||||||
mtexinfo_t* texinfo;
|
mtexinfo_t *texinfo;
|
||||||
int dlightframe; // last frame the surface was checked by an animated light
|
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 dlightbits; // dynamically generated. Indicates if the surface illumination is modified by an animated light.
|
||||||
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 {
|
||||||
|
|
@ -96,8 +124,8 @@ typedef struct cache_user_s {
|
||||||
} cache_user_t;
|
} cache_user_t;
|
||||||
|
|
||||||
typedef struct hull_s {
|
typedef struct hull_s {
|
||||||
struct dclipnode_t* clipnodes;
|
struct dclipnode_t *clipnodes;
|
||||||
mplane_t* planes;
|
mplane_t *planes;
|
||||||
int firstclipnode;
|
int firstclipnode;
|
||||||
int lastclipnode;
|
int lastclipnode;
|
||||||
vec3_t clip_mins;
|
vec3_t clip_mins;
|
||||||
|
|
@ -109,40 +137,40 @@ typedef struct model_s {
|
||||||
qboolean needload; // bmodels and sprites don't cache normally
|
qboolean needload; // bmodels and sprites don't cache normally
|
||||||
int type; // model type
|
int type; // model type
|
||||||
int numframes; // sprite's framecount
|
int numframes; // sprite's framecount
|
||||||
byte* mempool; // private mempool (was synctype)
|
byte *mempool; // private mempool (was synctype)
|
||||||
int flags; // hl compatibility
|
int flags; // hl compatibility
|
||||||
vec3_t mins, maxs; // bounding box at angles '0 0 0'
|
vec3_t mins, maxs; // bounding box at angles '0 0 0'
|
||||||
float radius;
|
float radius;
|
||||||
int firstmodelsurface;
|
int firstmodelsurface;
|
||||||
int nummodelsurfaces;
|
int nummodelsurfaces;
|
||||||
int numsubmodels;
|
int numsubmodels;
|
||||||
struct dmodel_t* submodels; // or studio animations
|
struct dmodel_t *submodels; // or studio animations
|
||||||
int numplanes;
|
int numplanes;
|
||||||
mplane_t* planes;
|
mplane_t *planes;
|
||||||
int numleafs; // number of visible leafs, not counting 0
|
int numleafs; // number of visible leafs, not counting 0
|
||||||
struct mleaf_t* leafs;
|
struct mleaf_t *leafs;
|
||||||
int numvertexes;
|
int numvertexes;
|
||||||
mvertex_t* vertexes;
|
mvertex_t *vertexes;
|
||||||
int numedges;
|
int numedges;
|
||||||
struct medge_t* edges;
|
struct medge_t *edges;
|
||||||
int numnodes;
|
int numnodes;
|
||||||
mnode_t* nodes;
|
mnode_t *nodes;
|
||||||
int numtexinfo;
|
int numtexinfo;
|
||||||
mtexinfo_t* texinfo;
|
mtexinfo_t *texinfo;
|
||||||
int numsurfaces;
|
int numsurfaces;
|
||||||
msurface_t* surfaces;
|
msurface_t *surfaces;
|
||||||
int numsurfedges;
|
int numsurfedges;
|
||||||
int* surfedges;
|
int *surfedges;
|
||||||
int numclipnodes;
|
int numclipnodes;
|
||||||
struct dclipnode_t* clipnodes;
|
struct dclipnode_t *clipnodes;
|
||||||
int nummarksurfaces;
|
int nummarksurfaces;
|
||||||
msurface_t** marksurfaces;
|
msurface_t **marksurfaces;
|
||||||
hull_t hulls[MAX_MAP_HULLS];
|
hull_t hulls[MAX_MAP_HULLS];
|
||||||
int numtextures;
|
int numtextures;
|
||||||
texture_t** textures;
|
texture_t **textures;
|
||||||
byte* visdata;
|
byte *visdata;
|
||||||
color24* lightdata;
|
color24 *lightdata;
|
||||||
char* entities;
|
char *entities;
|
||||||
cache_user_t cache; // only access through Mod_Extradata
|
cache_user_t cache; // only access through Mod_Extradata
|
||||||
} model_t;
|
} model_t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 ();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)) {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue