remove vertex rounding
fix vertex hash not including negative axis points use angle instead of zero-area triangle
This commit is contained in:
parent
cfb1bf0d2c
commit
d9dc54d267
|
|
@ -35,7 +35,9 @@ struct face_t;
|
|||
class mapentity_t;
|
||||
struct tree_t;
|
||||
|
||||
bool WindingIsTiny(const winding_t &w, double size = 0.2);
|
||||
constexpr vec_t EDGE_LENGTH_EPSILON = 0.2;
|
||||
|
||||
bool WindingIsTiny(const winding_t &w, double size = EDGE_LENGTH_EPSILON);
|
||||
std::unique_ptr<bspbrush_t> BrushFromBounds(const aabb3d &bounds);
|
||||
std::unique_ptr<tree_t> BrushBSP(std::vector<std::unique_ptr<bspbrush_t>> brushlist);
|
||||
|
||||
|
|
|
|||
|
|
@ -177,10 +177,10 @@ struct mapdata_t
|
|||
{
|
||||
// insert each vert at floor(pos[axis]) and floor(pos[axis]) + 1 (for each axis)
|
||||
// so e.g. a vert at (0.99, 0.99, 0.99) shows up if we search at (1.01, 1.01, 1.01)
|
||||
// this is a bit wasteful, since it inserts 8 copies of each vert.
|
||||
for (int32_t x = 0; x <= 1; x++) {
|
||||
for (int32_t y = 0; y <= 1; y++) {
|
||||
for (int32_t z = 0; z <= 1; z++) {
|
||||
// this is a bit wasteful..
|
||||
for (int32_t x = -1; x <= 1; x++) {
|
||||
for (int32_t y = -1; y <= 1; y++) {
|
||||
for (int32_t z = -1; z <= 1; z++) {
|
||||
const qvec3i h{floor(point[0]) + x, floor(point[1]) + y, floor(point[2]) + z};
|
||||
hashverts[h].push_front({ point, num });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,12 +355,8 @@ Returns true if the winding would be crunched out of
|
|||
existance by the vertex snapping.
|
||||
================
|
||||
*/
|
||||
#define EDGE_LENGTH 0.2
|
||||
bool WindingIsTiny(const winding_t &w, double size)
|
||||
{
|
||||
#if 0
|
||||
return w.area() < size;
|
||||
#else
|
||||
int edges = 0;
|
||||
for (size_t i = 0; i < w.size(); i++) {
|
||||
size_t j = (i + 1) % w.size();
|
||||
|
|
@ -372,7 +368,6 @@ bool WindingIsTiny(const winding_t &w, double size)
|
|||
}
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -386,9 +381,10 @@ from basewinding for plane
|
|||
bool WindingIsHuge(const winding_t &w)
|
||||
{
|
||||
for (size_t i = 0; i < w.size(); i++) {
|
||||
for (size_t j = 0; j < 3; j++)
|
||||
for (size_t j = 0; j < 3; j++) {
|
||||
if (fabs(w[i][j]) > qbsp_options.worldextent.value())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,20 +54,10 @@ static void MergeNodeFaces(node_t *node)
|
|||
/*
|
||||
=============
|
||||
EmitVertex
|
||||
NOTE: modifies input to be rounded!
|
||||
=============
|
||||
*/
|
||||
inline void EmitVertex(qvec3d &vert, size_t &vert_id)
|
||||
inline void EmitVertex(const qvec3d &vert, size_t &vert_id)
|
||||
{
|
||||
// if we're extremely close to an integral point,
|
||||
// snap us to it.
|
||||
for (auto &v : vert) {
|
||||
double rounded = Q_rint(v);
|
||||
if (fabs(v - rounded) < ZERO_EPSILON) {
|
||||
v = rounded;
|
||||
}
|
||||
}
|
||||
|
||||
// already added
|
||||
if (auto v = map.find_emitted_hash_vector(vert)) {
|
||||
vert_id = *v;
|
||||
|
|
@ -80,7 +70,7 @@ inline void EmitVertex(qvec3d &vert, size_t &vert_id)
|
|||
map.bsp.dvertexes.emplace_back(vert);
|
||||
}
|
||||
|
||||
// snap windings & output final vertices
|
||||
// output final vertices
|
||||
static void EmitFaceVertices(face_t *f)
|
||||
{
|
||||
if (ShouldOmitFace(f)) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ TestEdge
|
|||
Can be recursively reentered
|
||||
==========
|
||||
*/
|
||||
inline void TestEdge (vec_t start, vec_t end, size_t p1, size_t p2, size_t startvert, const std::vector<size_t> &edge_verts, const qvec3d &edge_start, const qvec3d &edge_dir, std::vector<size_t> &superface)
|
||||
inline void TestEdge(vec_t start, vec_t end, size_t p1, size_t p2, size_t startvert, const std::vector<size_t> &edge_verts, const qvec3d &edge_start, const qvec3d &edge_dir, std::vector<size_t> &superface)
|
||||
{
|
||||
if (p1 == p2) {
|
||||
// degenerate edge
|
||||
|
|
@ -194,12 +194,27 @@ inline void SplitFaceIntoFragments(std::vector<size_t> &superface, std::vector<s
|
|||
}
|
||||
}
|
||||
|
||||
inline bool IsZeroAreaTriangle(size_t v0, size_t v1, size_t v2)
|
||||
float AngleOfTriangle(const qvec3d &a, const qvec3d &b, const qvec3d &c)
|
||||
{
|
||||
qvec3d d1 = map.bsp.dvertexes[v2] - map.bsp.dvertexes[v0];
|
||||
qvec3d d2 = map.bsp.dvertexes[v1] - map.bsp.dvertexes[v0];
|
||||
vec_t total = 0.5 * qv::length(qv::cross(d1, d2));
|
||||
return total < ZERO_TRI_AREA_EPSILON;
|
||||
vec_t num = (b[0]-a[0])*(c[0]-a[0])+(b[1]-a[1])*(c[1]-a[1])+(b[2]-a[2])*(c[2]-a[2]);
|
||||
vec_t den = sqrt(pow((b[0]-a[0]),2)+pow((b[1]-a[1]),2)+pow((b[2]-a[2]),2))*
|
||||
sqrt(pow((c[0]-a[0]),2)+pow((c[1]-a[1]),2)+pow((c[2]-a[2]),2));
|
||||
|
||||
return acos(num / den) * (180.0 / 3.141592653589793238463);
|
||||
}
|
||||
|
||||
// Check whether the given input triangle would be valid
|
||||
// on the given face and not have any other points
|
||||
// intersecting it.
|
||||
inline bool TriangleIsValid(size_t v0, size_t v1, size_t v2, const std::vector<size_t> &face, float angle_epsilon)
|
||||
{
|
||||
if (AngleOfTriangle(map.bsp.dvertexes[v0], map.bsp.dvertexes[v1], map.bsp.dvertexes[v2]) < angle_epsilon ||
|
||||
AngleOfTriangle(map.bsp.dvertexes[v1], map.bsp.dvertexes[v2], map.bsp.dvertexes[v0]) < angle_epsilon ||
|
||||
AngleOfTriangle(map.bsp.dvertexes[v2], map.bsp.dvertexes[v0], map.bsp.dvertexes[v1]) < angle_epsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -274,7 +289,7 @@ static std::vector<std::vector<size_t>> RetopologizeFace(const std::vector<size_
|
|||
end = (seed + 2) % input.size();
|
||||
auto v2 = input[end];
|
||||
|
||||
if (IsZeroAreaTriangle(v0, v1, v2)) {
|
||||
if (!TriangleIsValid(v0, v1, v2, input, 0.01)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -421,7 +436,7 @@ static void FixFaceEdges(node_t *headnode, node_t *node, face_t *f)
|
|||
}
|
||||
|
||||
// brute force rotating the start point until we find a valid winding
|
||||
// that doesn't have any zero-area triangles
|
||||
// that doesn't have any T-junctions
|
||||
size_t i = 0;
|
||||
|
||||
for (; i < superface.size(); i++) {
|
||||
|
|
@ -433,7 +448,7 @@ static void FixFaceEdges(node_t *headnode, node_t *node, face_t *f)
|
|||
auto v1 = superface[(i + x + 1) % superface.size()];
|
||||
auto v2 = superface[(i + x + 2) % superface.size()];
|
||||
|
||||
if (IsZeroAreaTriangle(v0, v1, v2)) {
|
||||
if (!TriangleIsValid(v0, v1, v2, superface, 0.01)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue