light: expose faceextents_t in header

This commit is contained in:
Eric Wasylishen 2017-02-21 22:59:40 -07:00
parent 64dba663e0
commit cafadddb62
2 changed files with 120 additions and 106 deletions

View File

@ -23,6 +23,7 @@
#include <common/cmdlib.hh>
#include <common/mathlib.hh>
#include <common/bspfile.hh>
#include <common/bsputils.hh>
#include <common/log.hh>
#include <common/threads.hh>
#include <common/polylib.hh>
@ -32,4 +33,29 @@
glm::vec2 WorldToTexCoord_HighPrecision(const bsp2_t *bsp, const bsp2_dface_t *face, const glm::vec3 &world);
void LightBatch(bsp2_t *bsp, const batch_t &batch, const all_contrib_faces_t &all_contrib_faces);
class faceextents_t {
private:
glm::ivec2 m_texmins;
glm::ivec2 m_texsize;
float m_lightmapscale;
glm::mat4x4 m_worldToTexCoord;
glm::mat4x4 m_texCoordToWorld;
public:
faceextents_t() = default;
faceextents_t(const bsp2_dface_t *face, const bsp2_t *bsp, float lmscale);
int width() const;
int height() const;
int numsamples() const;
glm::ivec2 texsize() const;
int indexOf(const glm::ivec2 &lm) const;
glm::ivec2 intCoordsFromIndex(int index) const;
glm::vec2 LMCoordToTexCoord(const glm::vec2 &LMCoord) const;
glm::vec2 TexCoordToLMCoord(const glm::vec2 &tc) const;
glm::vec2 worldToTexCoord(glm::vec3 world) const;
glm::vec3 texCoordToWorld(glm::vec2 tc) const;
glm::vec2 worldToLMCoord(glm::vec3 world) const;
glm::vec3 LMCoordToWorld(glm::vec2 lm) const;
};
#endif /* __LIGHT_LTFACE2_H__ */

View File

@ -71,125 +71,113 @@ glm::vec2 WorldToTexCoord_HighPrecision(const bsp2_t *bsp, const bsp2_dface_t *f
return coord;
}
class faceextents_t {
private:
glm::ivec2 m_texmins;
glm::ivec2 m_texsize;
float m_lightmapscale;
glm::mat4x4 m_worldToTexCoord;
glm::mat4x4 m_texCoordToWorld;
public:
faceextents_t() = default;
faceextents_t(const bsp2_dface_t *face, const bsp2_t *bsp, float lmscale)
faceextents_t::faceextents_t(const bsp2_dface_t *face, const bsp2_t *bsp, float lmscale)
: m_lightmapscale(lmscale)
{
m_worldToTexCoord = WorldToTexSpace(bsp, face);
m_texCoordToWorld = TexSpaceToWorld(bsp, face);
{
m_worldToTexCoord = WorldToTexSpace(bsp, face);
m_texCoordToWorld = TexSpaceToWorld(bsp, face);
glm::vec2 mins(VECT_MAX, VECT_MAX);
glm::vec2 maxs(-VECT_MAX, -VECT_MAX);
for (int i = 0; i < face->numedges; i++) {
const glm::vec3 worldpoint = Face_PointAtIndex_E(bsp, face, i);
const glm::vec2 texcoord = WorldToTexCoord_HighPrecision(bsp, face, worldpoint);
glm::vec2 mins(VECT_MAX, VECT_MAX);
glm::vec2 maxs(-VECT_MAX, -VECT_MAX);
// self test
auto texcoordRT = this->worldToTexCoord(worldpoint);
auto worldpointRT = this->texCoordToWorld(texcoord);
Q_assert(glm::bvec2(true, true) == glm::epsilonEqual(texcoordRT, texcoord, 0.1f));
Q_assert(glm::bvec3(true, true, true) == glm::epsilonEqual(worldpointRT, worldpoint, 0.1f));
// end self test
for (int i = 0; i < face->numedges; i++) {
const glm::vec3 worldpoint = Face_PointAtIndex_E(bsp, face, i);
const glm::vec2 texcoord = WorldToTexCoord_HighPrecision(bsp, face, worldpoint);
// self test
auto texcoordRT = this->worldToTexCoord(worldpoint);
auto worldpointRT = this->texCoordToWorld(texcoord);
Q_assert(glm::bvec2(true, true) == glm::epsilonEqual(texcoordRT, texcoord, 0.1f));
Q_assert(glm::bvec3(true, true, true) == glm::epsilonEqual(worldpointRT, worldpoint, 0.1f));
// end self test
for (int j = 0; j < 2; j++) {
if (texcoord[j] < mins[j])
mins[j] = texcoord[j];
if (texcoord[j] > maxs[j])
maxs[j] = texcoord[j];
}
}
for (int i = 0; i < 2; i++) {
mins[i] = floor(mins[i] / m_lightmapscale);
maxs[i] = ceil(maxs[i] / m_lightmapscale);
m_texmins[i] = static_cast<int>(mins[i]);
m_texsize[i] = static_cast<int>(maxs[i] - mins[i]);
if (m_texsize[i] >= MAXDIMENSION) {
const plane_t plane = Face_Plane(bsp, face);
const glm::vec3 point = Face_PointAtIndex_E(bsp, face, 0); // grab first vert
const char *texname = Face_TextureName(bsp, face);
Error("Bad surface extents:\n"
" surface %d, %s extents = %d, scale = %g\n"
" texture %s at (%s)\n"
" surface normal (%s)\n",
Face_GetNum(bsp, face), i ? "t" : "s", m_texsize[i], m_lightmapscale,
texname, glm::to_string(point).c_str(),
VecStrf(plane.normal));
}
for (int j = 0; j < 2; j++) {
if (texcoord[j] < mins[j])
mins[j] = texcoord[j];
if (texcoord[j] > maxs[j])
maxs[j] = texcoord[j];
}
}
int width() const { return m_texsize[0] + 1; }
int height() const { return m_texsize[1] + 1; }
int numsamples() const { return width() * height(); }
glm::ivec2 texsize() const { return glm::ivec2(width(), height()); }
int indexOf(const glm::ivec2 &lm) const {
Q_assert(lm.x >= 0 && lm.x < width());
Q_assert(lm.y >= 0 && lm.y < height());
return lm.x + (width() * lm.y);
}
glm::ivec2 intCoordsFromIndex(int index) const {
Q_assert(index >= 0);
Q_assert(index < numsamples());
for (int i = 0; i < 2; i++) {
mins[i] = floor(mins[i] / m_lightmapscale);
maxs[i] = ceil(maxs[i] / m_lightmapscale);
m_texmins[i] = static_cast<int>(mins[i]);
m_texsize[i] = static_cast<int>(maxs[i] - mins[i]);
glm::ivec2 res(index % width(), index / width());
Q_assert(indexOf(res) == index);
return res;
if (m_texsize[i] >= MAXDIMENSION) {
const plane_t plane = Face_Plane(bsp, face);
const glm::vec3 point = Face_PointAtIndex_E(bsp, face, 0); // grab first vert
const char *texname = Face_TextureName(bsp, face);
Error("Bad surface extents:\n"
" surface %d, %s extents = %d, scale = %g\n"
" texture %s at (%s)\n"
" surface normal (%s)\n",
Face_GetNum(bsp, face), i ? "t" : "s", m_texsize[i], m_lightmapscale,
texname, glm::to_string(point).c_str(),
VecStrf(plane.normal));
}
}
}
int faceextents_t::width() const { return m_texsize[0] + 1; }
int faceextents_t::height() const { return m_texsize[1] + 1; }
int faceextents_t::numsamples() const { return width() * height(); }
glm::ivec2 faceextents_t::texsize() const { return glm::ivec2(width(), height()); }
int faceextents_t::indexOf(const glm::ivec2 &lm) const {
Q_assert(lm.x >= 0 && lm.x < width());
Q_assert(lm.y >= 0 && lm.y < height());
return lm.x + (width() * lm.y);
}
glm::ivec2 faceextents_t::intCoordsFromIndex(int index) const {
Q_assert(index >= 0);
Q_assert(index < numsamples());
glm::vec2 LMCoordToTexCoord(const glm::vec2 &LMCoord) const {
const glm::vec2 res(m_lightmapscale * (m_texmins[0] + LMCoord.x),
m_lightmapscale * (m_texmins[1] + LMCoord.y));
return res;
}
glm::ivec2 res(index % width(), index / width());
Q_assert(indexOf(res) == index);
return res;
}
glm::vec2 faceextents_t::LMCoordToTexCoord(const glm::vec2 &LMCoord) const {
const glm::vec2 res(m_lightmapscale * (m_texmins[0] + LMCoord.x),
m_lightmapscale * (m_texmins[1] + LMCoord.y));
return res;
}
glm::vec2 faceextents_t::TexCoordToLMCoord(const glm::vec2 &tc) const {
const glm::vec2 res((tc.x / m_lightmapscale) - m_texmins[0],
(tc.y / m_lightmapscale) - m_texmins[1]);
return res;
}
glm::vec2 faceextents_t::worldToTexCoord(glm::vec3 world) const {
const glm::vec4 worldPadded(world[0], world[1], world[2], 1.0f);
const glm::vec4 res = m_worldToTexCoord * worldPadded;
glm::vec2 TexCoordToLMCoord(const glm::vec2 &tc) const {
const glm::vec2 res((tc.x / m_lightmapscale) - m_texmins[0],
(tc.y / m_lightmapscale) - m_texmins[1]);
return res;
}
Q_assert(res[3] == 1.0f);
glm::vec2 worldToTexCoord(glm::vec3 world) const {
const glm::vec4 worldPadded(world[0], world[1], world[2], 1.0f);
const glm::vec4 res = m_worldToTexCoord * worldPadded;
Q_assert(res[3] == 1.0f);
return glm::vec2( res[0], res[1] );
}
return glm::vec2( res[0], res[1] );
}
glm::vec3 faceextents_t::texCoordToWorld(glm::vec2 tc) const {
const glm::vec4 tcPadded(tc[0], tc[1], 0.0f, 1.0f);
const glm::vec4 res = m_texCoordToWorld * tcPadded;
glm::vec3 texCoordToWorld(glm::vec2 tc) const {
const glm::vec4 tcPadded(tc[0], tc[1], 0.0f, 1.0f);
const glm::vec4 res = m_texCoordToWorld * tcPadded;
Q_assert(fabs(res[3] - 1.0f) < 0.01f);
return glm::vec3( res[0], res[1], res[2] );
}
Q_assert(fabs(res[3] - 1.0f) < 0.01f);
glm::vec2 worldToLMCoord(glm::vec3 world) const {
return TexCoordToLMCoord(worldToTexCoord(world));
}
glm::vec3 LMCoordToWorld(glm::vec2 lm) const {
return texCoordToWorld(LMCoordToTexCoord(lm));
}
};
return glm::vec3( res[0], res[1], res[2] );
}
glm::vec2 faceextents_t::worldToLMCoord(glm::vec3 world) const {
return TexCoordToLMCoord(worldToTexCoord(world));
}
glm::vec3 faceextents_t::LMCoordToWorld(glm::vec2 lm) const {
return texCoordToWorld(LMCoordToTexCoord(lm));
}
class sample_t {
private: