diff --git a/include/common/mathlib.hh b/include/common/mathlib.hh index b0d3bc0f..eb1fde8e 100644 --- a/include/common/mathlib.hh +++ b/include/common/mathlib.hh @@ -57,6 +57,7 @@ enum side_t : int8_t SIDE_FRONT, SIDE_BACK, SIDE_ON, + SIDE_TOTAL, SIDE_CROSS = -2 }; diff --git a/include/common/polylib.hh b/include/common/polylib.hh index 3e76f3b9..5c8c59e1 100644 --- a/include/common/polylib.hh +++ b/include/common/polylib.hh @@ -531,30 +531,46 @@ public: return result; } - // dists/sides must have (size() + 1) reserved - inline void calc_sides(const qplane3d &plane, vec_t *dists, side_t *sides, int32_t counts[3], + // dists/sides can be null, or must have (size() + 1) reserved + inline std::array calc_sides(const qplane3d &plane, vec_t *dists, side_t *sides, const vec_t &on_epsilon = DEFAULT_ON_EPSILON) const { + std::array counts {}; + /* determine sides for each point */ size_t i; for (i = 0; i < count; i++) { vec_t dot = plane.distance_to(at(i)); - dists[i] = dot; + if (dists) { + dists[i] = dot; + } + + side_t side; if (dot > on_epsilon) - sides[i] = SIDE_FRONT; + side = SIDE_FRONT; else if (dot < -on_epsilon) - sides[i] = SIDE_BACK; + side = SIDE_BACK; else - sides[i] = SIDE_ON; + side = SIDE_ON; - counts[sides[i]]++; + counts[side]++; + + if (sides) { + sides[i] = side; + } } - sides[i] = sides[SIDE_FRONT]; - dists[i] = dists[SIDE_FRONT]; + if (sides) { + sides[i] = sides[SIDE_FRONT]; + } + if (dists) { + dists[i] = dists[SIDE_FRONT]; + } + + return counts; } /* @@ -571,9 +587,8 @@ public: { vec_t *dists = (vec_t *)alloca(sizeof(vec_t) * (count + 1)); side_t *sides = (side_t *)alloca(sizeof(side_t) * (count + 1)); - int counts[3]{}; - calc_sides(plane, dists, sides, counts, on_epsilon); + std::array counts = calc_sides(plane, dists, sides, on_epsilon); if (keepon && !counts[SIDE_FRONT] && !counts[SIDE_BACK]) return {*this, std::nullopt}; diff --git a/light/phong.cc b/light/phong.cc index 98306bb8..00c5d582 100644 --- a/light/phong.cc +++ b/light/phong.cc @@ -555,7 +555,7 @@ void CalculateVertexNormals(const mbsp_t *bsp) // face tangent auto t1 = TexSpaceToWorld(bsp, &f); - std::tuple tangents(t1.col(0).xyz(), qv::normalize(qv::cross(f_norm, t1.col(0).xyz()))); + std::tuple tangents(t1.col(0).xyz(), qv::normalize(t1.col(1).xyz())); // gather up f and neighboursToSmooth std::vector fPlusNeighbours; @@ -573,7 +573,7 @@ void CalculateVertexNormals(const mbsp_t *bsp) // f2 face tangent auto t2 = TexSpaceToWorld(bsp, f2); - std::tuple f2_tangents(t2.col(0).xyz(), qv::normalize(qv::cross(f2_norm, t2.col(0).xyz()))); + std::tuple f2_tangents(t2.col(0).xyz(), qv::normalize(t2.col(1).xyz())); // walk the vertices of f2, and add their contribution to smoothedNormals for (int j = 0; j < f2->numedges; j++) { diff --git a/qbsp/csg4.cc b/qbsp/csg4.cc index e3173f61..bd435f65 100644 --- a/qbsp/csg4.cc +++ b/qbsp/csg4.cc @@ -110,7 +110,7 @@ void SplitFace(face_t *in, const qplane3d &split, face_t **front, face_t **back) { vec_t *dists = (vec_t *)alloca(sizeof(vec_t) * (in->w.size() + 1)); side_t *sides = (side_t *)alloca(sizeof(side_t) * (in->w.size() + 1)); - int counts[3]{}; + std::array counts { }; vec_t dot; size_t i, j; face_t *newf, *new2; @@ -128,7 +128,7 @@ void SplitFace(face_t *in, const qplane3d &split, face_t **front, face_t **back) counts[SIDE_FRONT] = 0; counts[SIDE_BACK] = 1; } else { - in->w.calc_sides(split, dists, sides, counts, ON_EPSILON); + counts = in->w.calc_sides(split, dists, sides, ON_EPSILON); } // Plane doesn't split this face after all @@ -241,6 +241,8 @@ Faces exactly on the plane will stay inside unless overdrawn by later brush */ static void ClipInside(const face_t *clipface, bool precedence, face_t **inside, face_t **outside) { + std::vector dists; + std::vector sides; face_t *face, *next, *frags[2]; const qbsp_plane_t &splitplane = map.planes[clipface->planenum]; @@ -255,12 +257,7 @@ static void ClipInside(const face_t *clipface, bool precedence, face_t **inside, */ bool spurious_onplane = false; { - vec_t *dists = (vec_t *)malloc(sizeof(vec_t) * (face->w.size() + 1)); - side_t *sides = (side_t *)malloc(sizeof(side_t) * (face->w.size() + 1)); - int counts[3]{}; - face->w.calc_sides(splitplane, dists, sides, counts, ON_EPSILON); - free(dists); - free(sides); + std::array counts = face->w.calc_sides(splitplane, nullptr, nullptr, ON_EPSILON); if (counts[SIDE_ON] && !counts[SIDE_FRONT] && !counts[SIDE_BACK]) { spurious_onplane = true;