Fix bug in bitangent calculation - thank you AlexP
Allow `calc_sides` to skip writing outputs if they are not required, & return counts since they are constant sized
This commit is contained in:
parent
02a4463d00
commit
0cca14d1b2
|
|
@ -57,6 +57,7 @@ enum side_t : int8_t
|
|||
SIDE_FRONT,
|
||||
SIDE_BACK,
|
||||
SIDE_ON,
|
||||
SIDE_TOTAL,
|
||||
|
||||
SIDE_CROSS = -2
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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<size_t, SIDE_TOTAL> calc_sides(const qplane3d &plane, vec_t *dists, side_t *sides,
|
||||
const vec_t &on_epsilon = DEFAULT_ON_EPSILON) const
|
||||
{
|
||||
std::array<size_t, SIDE_TOTAL> 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<size_t, SIDE_TOTAL> counts = calc_sides(plane, dists, sides, on_epsilon);
|
||||
|
||||
if (keepon && !counts[SIDE_FRONT] && !counts[SIDE_BACK])
|
||||
return {*this, std::nullopt};
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ void CalculateVertexNormals(const mbsp_t *bsp)
|
|||
|
||||
// face tangent
|
||||
auto t1 = TexSpaceToWorld(bsp, &f);
|
||||
std::tuple<qvec3f, qvec3f> tangents(t1.col(0).xyz(), qv::normalize(qv::cross(f_norm, t1.col(0).xyz())));
|
||||
std::tuple<qvec3f, qvec3f> tangents(t1.col(0).xyz(), qv::normalize(t1.col(1).xyz()));
|
||||
|
||||
// gather up f and neighboursToSmooth
|
||||
std::vector<const mface_t *> fPlusNeighbours;
|
||||
|
|
@ -573,7 +573,7 @@ void CalculateVertexNormals(const mbsp_t *bsp)
|
|||
|
||||
// f2 face tangent
|
||||
auto t2 = TexSpaceToWorld(bsp, f2);
|
||||
std::tuple<qvec3f, qvec3f> f2_tangents(t2.col(0).xyz(), qv::normalize(qv::cross(f2_norm, t2.col(0).xyz())));
|
||||
std::tuple<qvec3f, qvec3f> 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++) {
|
||||
|
|
|
|||
13
qbsp/csg4.cc
13
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<size_t, SIDE_TOTAL> 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<vec_t> dists;
|
||||
std::vector<side_t> 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<size_t, SIDE_TOTAL> counts = face->w.calc_sides(splitplane, nullptr, nullptr, ON_EPSILON);
|
||||
|
||||
if (counts[SIDE_ON] && !counts[SIDE_FRONT] && !counts[SIDE_BACK]) {
|
||||
spurious_onplane = true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue