normals are now a special tuple-ish type, so that we can calculate tangents and bitangents for Q2RTX if requested (currently it always does it, but we can fix that later)
always emit texinfo for q2 brush sides
This commit is contained in:
parent
33a454c700
commit
1b1679fa22
|
|
@ -598,7 +598,7 @@ std::pair<int, qvec3f> GLM_ClosestPointOnPolyBoundary(const std::vector<qvec3f>
|
|||
}
|
||||
|
||||
std::pair<bool, qvec3f> GLM_InterpolateNormal(
|
||||
const std::vector<qvec3f> &points, const std::vector<qvec3f> &normals, const qvec3f &point)
|
||||
const std::vector<qvec3f> &points, const std::vector<face_normal_t> &normals, const qvec3f &point)
|
||||
{
|
||||
Q_assert(points.size() == normals.size());
|
||||
|
||||
|
|
@ -608,14 +608,14 @@ std::pair<bool, qvec3f> GLM_InterpolateNormal(
|
|||
// Step through the triangles, being careful to handle zero-size ones
|
||||
|
||||
const qvec3f &p0 = points.at(0);
|
||||
const qvec3f &n0 = normals.at(0);
|
||||
const qvec3f &n0 = normals.at(0).normal;
|
||||
|
||||
const int N = points.size();
|
||||
for (int i = 2; i < N; i++) {
|
||||
const qvec3f &p1 = points.at(i - 1);
|
||||
const qvec3f &n1 = normals.at(i - 1);
|
||||
const qvec3f &n1 = normals.at(i - 1).normal;
|
||||
const qvec3f &p2 = points.at(i);
|
||||
const qvec3f &n2 = normals.at(i);
|
||||
const qvec3f &n2 = normals.at(i).normal;
|
||||
|
||||
const auto edgeplanes = GLM_MakeInwardFacingEdgePlanes({p0, p1, p2});
|
||||
if (edgeplanes.size() != 3)
|
||||
|
|
|
|||
|
|
@ -241,6 +241,12 @@ inline vec_t GetDir(const Tstart &start, const Tstop &stop, Tdir &dir)
|
|||
return VectorNormalize(dir);
|
||||
}
|
||||
|
||||
// Stores a normal, tangent and bitangents
|
||||
struct face_normal_t
|
||||
{
|
||||
qvec3f normal, tangent, bitangent;
|
||||
};
|
||||
|
||||
bool SetPlanePts(const std::array<qvec3d, 3> &planepts, qvec3d &normal, vec_t &dist);
|
||||
|
||||
// Maps uniform random variables U and V in [0, 1] to uniformly distributed points on a sphere
|
||||
|
|
@ -297,7 +303,7 @@ qvec4f GLM_PolyPlane(const std::vector<qvec3f> &points);
|
|||
std::pair<int, qvec3f> GLM_ClosestPointOnPolyBoundary(const std::vector<qvec3f> &poly, const qvec3f &point);
|
||||
/// Returns `true` and the interpolated normal if `point` is in the polygon, otherwise returns false.
|
||||
std::pair<bool, qvec3f> GLM_InterpolateNormal(
|
||||
const std::vector<qvec3f> &points, const std::vector<qvec3f> &normals, const qvec3f &point);
|
||||
const std::vector<qvec3f> &points, const std::vector<face_normal_t> &normals, const qvec3f &point);
|
||||
std::vector<qvec3f> GLM_ShrinkPoly(const std::vector<qvec3f> &poly, const float amount);
|
||||
/// Returns (front part, back part)
|
||||
std::pair<std::vector<qvec3f>, std::vector<qvec3f>> GLM_ClipPoly(const std::vector<qvec3f> &poly, const qvec4f &plane);
|
||||
|
|
|
|||
|
|
@ -44,11 +44,10 @@ public:
|
|||
};
|
||||
|
||||
void CalculateVertexNormals(const mbsp_t *bsp);
|
||||
const qvec3f GetSurfaceVertexNormal(const mbsp_t *bsp, const mface_t *f, const int vertindex);
|
||||
const face_normal_t &GetSurfaceVertexNormal(const mbsp_t *bsp, const mface_t *f, const int vertindex);
|
||||
bool FacesSmoothed(const mface_t *f1, const mface_t *f2);
|
||||
const std::set<const mface_t *> &GetSmoothFaces(const mface_t *face);
|
||||
const std::vector<const mface_t *> &GetPlaneFaces(const mface_t *face);
|
||||
const qvec3f GetSurfaceVertexNormal(const mbsp_t *bsp, const mface_t *f, const int v);
|
||||
const mface_t *Face_EdgeIndexSmoothed(const mbsp_t *bsp, const mface_t *f, const int edgeindex);
|
||||
|
||||
/// a directed edge can be used by more than one face, e.g. two cube touching just along an edge
|
||||
|
|
@ -62,27 +61,22 @@ class face_cache_t
|
|||
{
|
||||
private:
|
||||
std::vector<qvec3f> m_points;
|
||||
std::vector<qvec3f> m_normals;
|
||||
std::vector<qvec3f> m_tangents;
|
||||
std::vector<qvec3f> m_bitangents;
|
||||
std::vector<face_normal_t> m_normals;
|
||||
qvec4f m_plane;
|
||||
std::vector<qvec4f> m_edgePlanes;
|
||||
std::vector<qvec3f> m_pointsShrunkBy1Unit;
|
||||
std::vector<neighbour_t> m_neighbours;
|
||||
|
||||
public:
|
||||
face_cache_t(const mbsp_t *bsp, const mface_t *face, const std::vector<qvec3f> &normals,
|
||||
const std::vector<qvec3f> &tangents, const std::vector<qvec3f> &bitangents)
|
||||
: m_points(GLM_FacePoints(bsp, face)), m_normals(normals), m_tangents(tangents), m_bitangents(bitangents),
|
||||
face_cache_t(const mbsp_t *bsp, const mface_t *face, const std::vector<face_normal_t> &normals)
|
||||
: m_points(GLM_FacePoints(bsp, face)), m_normals(normals),
|
||||
m_plane(Face_Plane(bsp, face).vec4()), m_edgePlanes(GLM_MakeInwardFacingEdgePlanes(m_points)),
|
||||
m_pointsShrunkBy1Unit(GLM_ShrinkPoly(m_points, 1.0f)), m_neighbours(NeighbouringFaces_new(bsp, face))
|
||||
{
|
||||
}
|
||||
|
||||
const std::vector<qvec3f> &points() const { return m_points; }
|
||||
const std::vector<qvec3f> &normals() const { return m_normals; }
|
||||
const std::vector<qvec3f> &tangents() const { return m_tangents; }
|
||||
const std::vector<qvec3f> &bitangents() const { return m_bitangents; }
|
||||
const std::vector<face_normal_t> &normals() const { return m_normals; }
|
||||
const qvec4f &plane() const { return m_plane; }
|
||||
const qvec3f normal() const { return m_plane; }
|
||||
const std::vector<qvec4f> &edgePlanes() const { return m_edgePlanes; }
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ static void ExportObjFace(std::ofstream &f, const mbsp_t *bsp, const mface_t *fa
|
|||
// export the vertices and uvs
|
||||
for (int i = 0; i < face->numedges; i++) {
|
||||
const int vertnum = Face_VertexAtIndex(bsp, face, i);
|
||||
const qvec3f normal = GetSurfaceVertexNormal(bsp, face, i);
|
||||
const qvec3f normal = GetSurfaceVertexNormal(bsp, face, i).normal;
|
||||
const qvec3f &pos = bsp->dvertexes[vertnum];
|
||||
fmt::print(f, "v {:.9} {:.9} {:.9}\n", pos[0], pos[1], pos[2]);
|
||||
fmt::print(f, "vn {:.9} {:.9} {:.9}\n", normal[0], normal[1], normal[2]);
|
||||
|
|
@ -903,10 +903,12 @@ static inline void WriteNormals(const mbsp_t &bsp, bspdata_t &bspdata)
|
|||
|
||||
for (auto &face : bsp.dfaces) {
|
||||
auto &cache = FaceCacheForFNum(&face - bsp.dfaces.data());
|
||||
unique_normals.insert(cache.normals().begin(), cache.normals().end());
|
||||
unique_normals.insert(cache.tangents().begin(), cache.tangents().end());
|
||||
unique_normals.insert(cache.bitangents().begin(), cache.bitangents().end());
|
||||
num_normals += cache.normals().size() + cache.tangents().size() + cache.bitangents().size();
|
||||
for (auto &normals : cache.normals()) {
|
||||
unique_normals.insert(normals.normal);
|
||||
unique_normals.insert(normals.tangent);
|
||||
unique_normals.insert(normals.bitangent);
|
||||
num_normals += 3;
|
||||
}
|
||||
}
|
||||
|
||||
size_t data_size = sizeof(uint32_t) + (sizeof(qvec3f) * unique_normals.size()) + (sizeof(uint32_t) * num_normals);
|
||||
|
|
@ -916,23 +918,20 @@ static inline void WriteNormals(const mbsp_t &bsp, bspdata_t &bspdata)
|
|||
stream << endianness<std::endian::little>;
|
||||
stream <= numeric_cast<uint32_t>(unique_normals.size());
|
||||
|
||||
std::map<qvec3f, size_t> mapped_normals;
|
||||
|
||||
for (auto &n : unique_normals) {
|
||||
stream <= std::tie(n[0], n[1], n[2]);
|
||||
mapped_normals.emplace(n, mapped_normals.size());
|
||||
}
|
||||
|
||||
for (auto &face : bsp.dfaces) {
|
||||
auto &cache = FaceCacheForFNum(&face - bsp.dfaces.data());
|
||||
|
||||
for (auto &n : cache.normals()) {
|
||||
stream <= numeric_cast<uint32_t>(std::distance(unique_normals.begin(), unique_normals.find(n)));
|
||||
}
|
||||
|
||||
for (auto &n : cache.tangents()) {
|
||||
stream <= numeric_cast<uint32_t>(std::distance(unique_normals.begin(), unique_normals.find(n)));
|
||||
}
|
||||
|
||||
for (auto &n : cache.bitangents()) {
|
||||
stream <= numeric_cast<uint32_t>(std::distance(unique_normals.begin(), unique_normals.find(n)));
|
||||
stream <= numeric_cast<uint32_t>(mapped_normals[n.normal]);
|
||||
stream <= numeric_cast<uint32_t>(mapped_normals[n.tangent]);
|
||||
stream <= numeric_cast<uint32_t>(mapped_normals[n.bitangent]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ void PrintFaceInfo(const mface_t *face, const mbsp_t *bsp)
|
|||
int edge = bsp->dsurfedges[face->firstedge + i];
|
||||
int vert = Face_VertexAtIndex(bsp, face, i);
|
||||
const qvec3f &point = GetSurfaceVertexPoint(bsp, face, i);
|
||||
const qvec3f norm = GetSurfaceVertexNormal(bsp, face, i);
|
||||
const qvec3f norm = GetSurfaceVertexNormal(bsp, face, i).normal;
|
||||
LogPrint("{} {:3} ({:3.3}, {:3.3}, {:3.3}) :: normal ({:3.3}, {:3.3}, {:3.3}) :: edge {}\n",
|
||||
i ? " " : " verts ", vert, point[0], point[1], point[2], norm[0], norm[1], norm[2], edge);
|
||||
}
|
||||
|
|
|
|||
168
light/phong.cc
168
light/phong.cc
|
|
@ -170,9 +170,7 @@ static float AngleBetweenPoints(const qvec3f &p1, const qvec3f &p2, const qvec3f
|
|||
}
|
||||
|
||||
static bool s_builtPhongCaches;
|
||||
static std::map<const mface_t *, std::vector<qvec3f>> vertex_normals;
|
||||
static std::map<const mface_t *, std::vector<qvec3f>> vertex_tangents;
|
||||
static std::map<const mface_t *, std::vector<qvec3f>> vertex_bitangents;
|
||||
static std::map<const mface_t *, std::vector<face_normal_t>> vertex_normals;
|
||||
static std::set<int> interior_verts;
|
||||
static map<const mface_t *, set<const mface_t *>> smoothFaces;
|
||||
static map<int, vector<const mface_t *>> vertsToFaces;
|
||||
|
|
@ -240,7 +238,7 @@ const std::vector<const mface_t *> &GetPlaneFaces(const mface_t *face)
|
|||
|
||||
// Adapted from https://github.com/NVIDIAGameWorks/donut/blob/main/src/engine/GltfImporter.cpp#L684
|
||||
std::tuple<qvec3f, qvec3f> compute_tangents(
|
||||
const std::array<qvec3f, 3> &positions, const std::array<qvec2f, 3> &tex_coords, const qvec3f &normal)
|
||||
const std::array<qvec3f, 3> &positions, const std::array<qvec2f, 3> &tex_coords)
|
||||
{
|
||||
qvec3f dPds = positions[1] - positions[0];
|
||||
qvec3f dPdt = positions[2] - positions[0];
|
||||
|
|
@ -255,16 +253,15 @@ std::tuple<qvec3f, qvec3f> compute_tangents(
|
|||
return {qv::normalize(tangent), qv::normalize(bitangent)};
|
||||
}
|
||||
|
||||
constexpr qvec2d uvs(const texvecf &vecs, const qvec3d &pos, const int32_t &width, const int32_t &height)
|
||||
constexpr qvec2f uvs(const texvecf &vecs, const qvec3f &pos, const int32_t &width, const int32_t &height)
|
||||
{
|
||||
return {(pos[0] * vecs[0][0] + pos[1] * vecs[0][1] + pos[2] * vecs[0][2] + vecs[0][3]) / width,
|
||||
(pos[0] * vecs[1][0] + pos[1] * vecs[1][1] + pos[2] * vecs[1][2] + vecs[1][3]) / height};
|
||||
(pos[0] * vecs[1][0] + pos[1] * vecs[1][1] + pos[2] * vecs[1][2] + vecs[1][3]) / height};
|
||||
}
|
||||
|
||||
/* given a triangle, just adds the contribution from the triangle to the given vertexes normals, based upon angles at
|
||||
* the verts. v1, v2, v3 are global vertex indices */
|
||||
static void AddTriangleNormals(std::map<int, qvec3f> &smoothed_normals, std::map<int, qvec3f> &smoothed_tangents,
|
||||
std::map<int, qvec3f> &smoothed_bitangents, const gtexinfo_t *texinfo, const rgba_miptex_t *miptex,
|
||||
static void AddTriangleNormals(std::map<int, face_normal_t> &smoothed_normals, const gtexinfo_t *texinfo, const rgba_miptex_t *miptex,
|
||||
const qvec3d &norm, const mbsp_t *bsp, int v1, int v2, int v3)
|
||||
{
|
||||
const qvec3f &p1 = Vertex_GetPos(bsp, v1);
|
||||
|
|
@ -281,69 +278,45 @@ static void AddTriangleNormals(std::map<int, qvec3f> &smoothed_normals, std::map
|
|||
auto uv2 = uvs(texinfo->vecs, p2, miptex->width, miptex->height);
|
||||
auto uv3 = uvs(texinfo->vecs, p3, miptex->width, miptex->height);
|
||||
|
||||
auto tangent = compute_tangents({p1, p2, p3}, {uv1, uv2, uv3}, norm);
|
||||
auto tangent = compute_tangents({p1, p2, p3}, {uv1, uv2, uv3});
|
||||
|
||||
weight = AngleBetweenPoints(p2, p1, p3);
|
||||
weight *= areaweight;
|
||||
smoothed_normals[v1] += norm * weight;
|
||||
smoothed_tangents[v1] += std::get<0>(tangent) * weight;
|
||||
smoothed_bitangents[v1] += std::get<1>(tangent) * weight;
|
||||
auto &n1 = smoothed_normals[v1];
|
||||
n1.normal += norm * weight;
|
||||
n1.tangent += std::get<0>(tangent) * weight;
|
||||
n1.bitangent += std::get<1>(tangent) * weight;
|
||||
|
||||
weight = AngleBetweenPoints(p1, p2, p3);
|
||||
weight *= areaweight;
|
||||
smoothed_normals[v2] += norm * weight;
|
||||
smoothed_tangents[v2] += std::get<0>(tangent) * weight;
|
||||
smoothed_bitangents[v2] += std::get<1>(tangent) * weight;
|
||||
auto &n2 = smoothed_normals[v2];
|
||||
n2.normal += norm * weight;
|
||||
n2.tangent += std::get<0>(tangent) * weight;
|
||||
n2.bitangent += std::get<1>(tangent) * weight;
|
||||
|
||||
weight = AngleBetweenPoints(p1, p3, p2);
|
||||
weight *= areaweight;
|
||||
smoothed_normals[v3] += norm * weight;
|
||||
smoothed_tangents[v3] += std::get<0>(tangent) * weight;
|
||||
smoothed_bitangents[v3] += std::get<1>(tangent) * weight;
|
||||
auto &n3 = smoothed_normals[v3];
|
||||
n3.normal += norm * weight;
|
||||
n3.tangent += std::get<0>(tangent) * weight;
|
||||
n3.bitangent += std::get<1>(tangent) * weight;
|
||||
}
|
||||
|
||||
/* access the final phong-shaded vertex normal */
|
||||
const qvec3f GetSurfaceVertexNormal(const mbsp_t *bsp, const mface_t *f, const int vertindex)
|
||||
const face_normal_t &GetSurfaceVertexNormal(const mbsp_t *bsp, const mface_t *f, const int vertindex)
|
||||
{
|
||||
Q_assert(s_builtPhongCaches);
|
||||
|
||||
// handle degenerate faces
|
||||
const auto it = vertex_normals.find(f);
|
||||
if (it == vertex_normals.end()) {
|
||||
return {};
|
||||
static const face_normal_t empty {};
|
||||
return empty;
|
||||
}
|
||||
const auto &face_normals_vec = it->second;
|
||||
return face_normals_vec.at(vertindex);
|
||||
}
|
||||
|
||||
/* access the final phong-shaded vertex tangent */
|
||||
static const qvec3f GetSurfaceVertexTangent(const mbsp_t *bsp, const mface_t *f, const int vertindex)
|
||||
{
|
||||
Q_assert(s_builtPhongCaches);
|
||||
|
||||
// handle degenerate faces
|
||||
const auto it = vertex_tangents.find(f);
|
||||
if (it == vertex_tangents.end()) {
|
||||
return {};
|
||||
}
|
||||
const auto &face_tangents_vec = it->second;
|
||||
return face_tangents_vec.at(vertindex);
|
||||
}
|
||||
|
||||
/* access the final phong-shaded vertex tangent */
|
||||
static const qvec3f GetSurfaceVertexBitangent(const mbsp_t *bsp, const mface_t *f, const int vertindex)
|
||||
{
|
||||
Q_assert(s_builtPhongCaches);
|
||||
|
||||
// handle degenerate faces
|
||||
const auto it = vertex_bitangents.find(f);
|
||||
if (it == vertex_bitangents.end()) {
|
||||
return {};
|
||||
}
|
||||
const auto &face_bitangents_vec = it->second;
|
||||
return face_bitangents_vec.at(vertindex);
|
||||
}
|
||||
|
||||
static bool FacesOnSamePlane(const std::vector<const mface_t *> &faces)
|
||||
{
|
||||
if (faces.empty()) {
|
||||
|
|
@ -439,39 +412,20 @@ static edgeToFaceMap_t MakeEdgeToFaceMap(const mbsp_t *bsp)
|
|||
return result;
|
||||
}
|
||||
|
||||
static vector<qvec3f> Face_VertexNormals(const mbsp_t *bsp, const mface_t *face)
|
||||
static vector<face_normal_t> Face_VertexNormals(const mbsp_t *bsp, const mface_t *face)
|
||||
{
|
||||
vector<qvec3f> normals;
|
||||
vector<face_normal_t> normals;
|
||||
for (int i = 0; i < face->numedges; i++) {
|
||||
normals.push_back(GetSurfaceVertexNormal(bsp, face, i));
|
||||
normals.emplace_back(GetSurfaceVertexNormal(bsp, face, i));
|
||||
}
|
||||
return normals;
|
||||
}
|
||||
|
||||
static vector<qvec3f> Face_VertexTangents(const mbsp_t *bsp, const mface_t *face)
|
||||
{
|
||||
vector<qvec3f> tangents;
|
||||
for (int i = 0; i < face->numedges; i++) {
|
||||
tangents.push_back(GetSurfaceVertexTangent(bsp, face, i));
|
||||
}
|
||||
return tangents;
|
||||
}
|
||||
|
||||
static vector<qvec3f> Face_VertexBitangents(const mbsp_t *bsp, const mface_t *face)
|
||||
{
|
||||
vector<qvec3f> tangents;
|
||||
for (int i = 0; i < face->numedges; i++) {
|
||||
tangents.push_back(GetSurfaceVertexBitangent(bsp, face, i));
|
||||
}
|
||||
return tangents;
|
||||
}
|
||||
|
||||
static vector<face_cache_t> MakeFaceCache(const mbsp_t *bsp)
|
||||
{
|
||||
vector<face_cache_t> result;
|
||||
for (auto &face : bsp->dfaces) {
|
||||
result.emplace_back(bsp, &face, Face_VertexNormals(bsp, &face), Face_VertexTangents(bsp, &face),
|
||||
Face_VertexBitangents(bsp, &face));
|
||||
result.emplace_back(bsp, &face, Face_VertexNormals(bsp, &face));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -639,7 +593,7 @@ void CalculateVertexNormals(const mbsp_t *bsp)
|
|||
auto uv2 = uvs(texinfo->vecs, p2, miptex->width, miptex->height);
|
||||
auto uv3 = uvs(texinfo->vecs, p3, miptex->width, miptex->height);
|
||||
|
||||
auto tangents = compute_tangents({p1, p2, p3}, {uv1, uv2, uv3}, f_norm);
|
||||
auto tangents = compute_tangents({p1, p2, p3}, {uv1, uv2, uv3});
|
||||
|
||||
// gather up f and neighboursToSmooth
|
||||
std::vector<const mface_t *> fPlusNeighbours;
|
||||
|
|
@ -647,7 +601,7 @@ void CalculateVertexNormals(const mbsp_t *bsp)
|
|||
std::copy(neighboursToSmooth.begin(), neighboursToSmooth.end(), std::back_inserter(fPlusNeighbours));
|
||||
|
||||
// global vertex index -> smoothed normal
|
||||
std::map<int, qvec3f> smoothedNormals, smoothedTangents, smoothedBitangents;
|
||||
std::map<int, face_normal_t> smoothedNormals;
|
||||
|
||||
// walk fPlusNeighbours
|
||||
for (auto f2 : fPlusNeighbours) {
|
||||
|
|
@ -659,7 +613,7 @@ void CalculateVertexNormals(const mbsp_t *bsp)
|
|||
v2 = Face_VertexAtIndex(bsp, f2, 1);
|
||||
for (int j = 2; j < f2->numedges; j++) {
|
||||
v3 = Face_VertexAtIndex(bsp, f2, j);
|
||||
AddTriangleNormals(smoothedNormals, smoothedTangents, smoothedBitangents,
|
||||
AddTriangleNormals(smoothedNormals,
|
||||
BSP_GetTexinfo(bsp, f2->texinfo), Face_RgbaMiptex(bsp, f2), f2_norm, bsp, v1, v2, v3);
|
||||
v2 = v3;
|
||||
}
|
||||
|
|
@ -668,8 +622,8 @@ void CalculateVertexNormals(const mbsp_t *bsp)
|
|||
// normalize vertex normals (NOTE: updates smoothedNormals map)
|
||||
for (auto &pair : smoothedNormals) {
|
||||
const int vertIndex = pair.first;
|
||||
const qvec3f vertNormal = pair.second;
|
||||
if (0 == qv::length(vertNormal)) {
|
||||
face_normal_t &vertNormal = pair.second;
|
||||
if (0 == qv::length(vertNormal.normal)) {
|
||||
// this happens when there are colinear vertices, which give zero-area triangles,
|
||||
// so there is no contribution to the normal of the triangle in the middle of the
|
||||
// line. Not really an error, just set it to use the face normal.
|
||||
|
|
@ -680,58 +634,30 @@ void CalculateVertexNormals(const mbsp_t *bsp)
|
|||
bsp->dvertexes[vertIndex].point[1],
|
||||
bsp->dvertexes[vertIndex].point[2]);
|
||||
#endif
|
||||
pair.second = f_norm;
|
||||
vertNormal = { f_norm, std::get<0>(tangents), std::get<1>(tangents) };
|
||||
} else {
|
||||
pair.second = qv::normalize(vertNormal);
|
||||
vertNormal = { qv::normalize(vertNormal.normal), qv::normalize(vertNormal.tangent), qv::normalize(vertNormal.bitangent) };
|
||||
}
|
||||
}
|
||||
|
||||
// normalize vertex tangents (NOTE: updates smoothedTangents map)
|
||||
for (auto &pair : smoothedTangents) {
|
||||
const int vertIndex = pair.first;
|
||||
const qvec3f vertTangent = pair.second;
|
||||
if (0 == qv::length(vertTangent)) {
|
||||
// this happens when there are colinear vertices, which give zero-area triangles,
|
||||
// so there is no contribution to the normal of the triangle in the middle of the
|
||||
// line. Not really an error, just set it to use the face normal.
|
||||
#if 0
|
||||
LogPrint("Failed to calculate normal for vertex {} at ({} {} {})\n",
|
||||
vertIndex,
|
||||
bsp->dvertexes[vertIndex].point[0],
|
||||
bsp->dvertexes[vertIndex].point[1],
|
||||
bsp->dvertexes[vertIndex].point[2]);
|
||||
#endif
|
||||
pair.second = std::get<0>(tangents);
|
||||
} else {
|
||||
pair.second = qv::normalize(vertTangent);
|
||||
|
||||
// FIXME: why
|
||||
if (std::isnan(vertNormal.tangent[0])) {
|
||||
vertNormal.tangent = std::get<0>(tangents);
|
||||
if (std::isnan(vertNormal.tangent[0])) {
|
||||
vertNormal.tangent = { 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// normalize vertex tangents (NOTE: updates smoothedTangents map)
|
||||
for (auto &pair : smoothedBitangents) {
|
||||
const int vertIndex = pair.first;
|
||||
const qvec3f vertBitangent = pair.second;
|
||||
if (0 == qv::length(vertBitangent)) {
|
||||
// this happens when there are colinear vertices, which give zero-area triangles,
|
||||
// so there is no contribution to the normal of the triangle in the middle of the
|
||||
// line. Not really an error, just set it to use the face normal.
|
||||
#if 0
|
||||
LogPrint("Failed to calculate normal for vertex {} at ({} {} {})\n",
|
||||
vertIndex,
|
||||
bsp->dvertexes[vertIndex].point[0],
|
||||
bsp->dvertexes[vertIndex].point[1],
|
||||
bsp->dvertexes[vertIndex].point[2]);
|
||||
#endif
|
||||
pair.second = std::get<1>(tangents);
|
||||
} else {
|
||||
pair.second = qv::normalize(vertBitangent);
|
||||
if (std::isnan(vertNormal.bitangent[0])) {
|
||||
vertNormal.bitangent = std::get<1>(tangents);
|
||||
if (std::isnan(vertNormal.bitangent[0])) {
|
||||
vertNormal.bitangent = { 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if (!neighboursToSmooth.size()) {
|
||||
for (auto vertIndexNormalPair : smoothedNormals) {
|
||||
Q_assert(qv::epsilonEqual(vertIndexNormalPair.second, f_norm, (float)EQUAL_EPSILON));
|
||||
Q_assert(qv::epsilonEqual(vertIndexNormalPair.second.normal, f_norm, (float)EQUAL_EPSILON));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -739,12 +665,8 @@ void CalculateVertexNormals(const mbsp_t *bsp)
|
|||
for (int j = 0; j < f.numedges; j++) {
|
||||
int v = Face_VertexAtIndex(bsp, &f, j);
|
||||
Q_assert(smoothedNormals.find(v) != smoothedNormals.end());
|
||||
Q_assert(smoothedTangents.find(v) != smoothedTangents.end());
|
||||
Q_assert(smoothedBitangents.find(v) != smoothedBitangents.end());
|
||||
|
||||
vertex_normals[&f].push_back(smoothedNormals[v]);
|
||||
vertex_tangents[&f].push_back(smoothedTangents[v]);
|
||||
vertex_bitangents[&f].push_back(smoothedBitangents[v]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ static void ExportBrushList(const mapentity_t *entity, node_t *node, uint32_t &b
|
|||
|
||||
for (auto &plane : bevels) {
|
||||
map.bsp.dbrushsides.push_back(
|
||||
{(uint32_t)std::get<0>(plane), (int32_t)map.mtexinfos[b->faces->texinfo].outputnum.value_or(-1)});
|
||||
{(uint32_t)std::get<0>(plane), (int32_t)ExportMapTexinfo(b->faces->texinfo)});
|
||||
brush.numsides++;
|
||||
brush_state.total_brush_sides++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue