replaced tri_inside with tri_find_z and it works!
This commit is contained in:
parent
8e82fb44c6
commit
72634d0f11
188
hiddenwire.c
188
hiddenwire.c
@ -41,7 +41,6 @@ struct _tri_t
|
|||||||
{
|
{
|
||||||
v3_t p[3]; // camera space
|
v3_t p[3]; // camera space
|
||||||
v3_t normal; // camera space
|
v3_t normal; // camera space
|
||||||
v3_t p_xyz[3]; // original xyz space
|
|
||||||
v3_t normal_xyz; // original xyz space
|
v3_t normal_xyz; // original xyz space
|
||||||
float min[3]; // camera space
|
float min[3]; // camera space
|
||||||
float max[3]; // camera space
|
float max[3]; // camera space
|
||||||
@ -205,77 +204,6 @@ if(0) fprintf(stderr, "collision: %.0f,%.0f,%.0f->%.0f,%.0f,%.0f %.0f,%.0f,%.0f-
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
tri_inside(
|
|
||||||
const tri_t * const t,
|
|
||||||
const v3_t * const p,
|
|
||||||
v3_t * const bary
|
|
||||||
)
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
const float p0x = t->p[0].p[0];
|
|
||||||
const float p0y = t->p[0].p[1];
|
|
||||||
const float p1x = t->p[1].p[0];
|
|
||||||
const float p1y = t->p[1].p[1];
|
|
||||||
const float p2x = t->p[2].p[0];
|
|
||||||
const float p2y = t->p[2].p[1];
|
|
||||||
|
|
||||||
const float px = p->p[0];
|
|
||||||
const float py = p->p[1];
|
|
||||||
|
|
||||||
// compute the barycentric coordinates of p in triangle t
|
|
||||||
const float a = (p1y - p2y)*(p0x - p2x) + (p2x - p1x)*(p0y - p2y);
|
|
||||||
//fprintf(stderr, "a=%f\n", a);
|
|
||||||
if (a < EPS)
|
|
||||||
{
|
|
||||||
// triangle is too small or has negative area
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float alpha = ((p1y - p2y)*(px - p2x) + (p2x - p1x)*(py - p2y));
|
|
||||||
const float beta = ((p2y - p0y)*(px - p2x) + (p0x - p2x)*(py - p2y));
|
|
||||||
const float gamma = a - alpha - beta;
|
|
||||||
|
|
||||||
if (bary)
|
|
||||||
*bary = (v3_t) {{ alpha, beta, gamma }};
|
|
||||||
|
|
||||||
if(0) fprintf(stderr, "a=%f b=%f g=%f\n", alpha, beta, gamma);
|
|
||||||
if (alpha < 0 || beta < 0 || gamma < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// inside!
|
|
||||||
if(0) fprintf(stderr, "%p: %f,%f inside %f,%f %f,%f %f,%f\n",
|
|
||||||
t,
|
|
||||||
px, py,
|
|
||||||
p0x, p0y,
|
|
||||||
p1x, p1y,
|
|
||||||
p2x, p2y
|
|
||||||
);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
const v3_t v1 = v3_sub(t->p[2], t->p[0]);
|
|
||||||
const v3_t v2 = v3_sub(t->p[1], t->p[0]);
|
|
||||||
const v3_t v = v3_sub(*p, t->p[0]);
|
|
||||||
|
|
||||||
const float d = det(v1,v2);
|
|
||||||
const float a = (det(*p,v2) - det(t->p[0], v2)) / +d;
|
|
||||||
const float b = (det(*p,v1) - det(t->p[0], v1)) / -d;
|
|
||||||
//const float a = +det(v,v2) / d;
|
|
||||||
//const float b = -det(v,v1) / d;
|
|
||||||
|
|
||||||
fprintf(stderr, "a=%f b=%f d=%f\n", a, b, d);
|
|
||||||
if (a < 0 || b < 0)
|
|
||||||
return 0;
|
|
||||||
if (a + b > 1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tri_t *
|
tri_t *
|
||||||
tri_new(
|
tri_new(
|
||||||
@ -287,10 +215,7 @@ tri_new(
|
|||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return NULL;
|
||||||
for(int i = 0 ; i < 3 ; i++)
|
for(int i = 0 ; i < 3 ; i++)
|
||||||
{
|
|
||||||
t->p[i] = p_cam[i];
|
t->p[i] = p_cam[i];
|
||||||
t->p_xyz[i] = p_xyz[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// precompute the normals
|
// precompute the normals
|
||||||
t->normal = v3_norm(v3_cross(
|
t->normal = v3_norm(v3_cross(
|
||||||
@ -298,8 +223,8 @@ tri_new(
|
|||||||
v3_sub(t->p[2], t->p[1])
|
v3_sub(t->p[2], t->p[1])
|
||||||
));
|
));
|
||||||
t->normal_xyz = v3_norm(v3_cross(
|
t->normal_xyz = v3_norm(v3_cross(
|
||||||
v3_sub(t->p_xyz[1], t->p_xyz[0]),
|
v3_sub(p_xyz[1], p_xyz[0]),
|
||||||
v3_sub(t->p_xyz[2], t->p_xyz[1])
|
v3_sub(p_xyz[2], p_xyz[1])
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
@ -461,40 +386,6 @@ tri_coplanar(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Find the Z point of a given xy point along the segment from p0 to p1.
|
|
||||||
*
|
|
||||||
* Returns -1 if there is no known Z point.
|
|
||||||
*/
|
|
||||||
float
|
|
||||||
find_z(
|
|
||||||
const v3_t * const p0,
|
|
||||||
const v3_t * const p1,
|
|
||||||
const float x,
|
|
||||||
const float y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const float dx = p1->p[0] - p0->p[0];
|
|
||||||
const float dy = p1->p[1] - p0->p[1];
|
|
||||||
const float dz = p1->p[2] - p0->p[2];
|
|
||||||
|
|
||||||
// find the z value of the intersection point
|
|
||||||
// on the segment. we don't care about the triangle
|
|
||||||
float ratio = 0;
|
|
||||||
if (dx != 0)
|
|
||||||
{
|
|
||||||
ratio = (x - p0->p[0]) / dx;
|
|
||||||
} else
|
|
||||||
if (dy != 0)
|
|
||||||
{
|
|
||||||
ratio = (y - p0->p[1]) / dy;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "uh, dx and dy both zero?\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p0->p[2] + dz * ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the Z point of an XY coordinate in a triangle.
|
* Find the Z point of an XY coordinate in a triangle.
|
||||||
@ -505,10 +396,11 @@ find_z(
|
|||||||
* p = a * t1 + b * t2
|
* p = a * t1 + b * t2
|
||||||
* which is two equations with two unknowns
|
* which is two equations with two unknowns
|
||||||
*/
|
*/
|
||||||
float
|
int
|
||||||
tri_find_z(
|
tri_find_z(
|
||||||
const tri_t * const t,
|
const tri_t * const t,
|
||||||
const v3_t * const p
|
const v3_t * const p,
|
||||||
|
float * const zout
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const float t1x = t->p[1].p[0] - t->p[0].p[0];
|
const float t1x = t->p[1].p[0] - t->p[0].p[0];
|
||||||
@ -525,7 +417,10 @@ tri_find_z(
|
|||||||
|
|
||||||
const float z = t->p[0].p[2] + a * t1z + b * t2z;
|
const float z = t->p[0].p[2] + a * t1z + b * t2z;
|
||||||
|
|
||||||
return z;
|
if (zout)
|
||||||
|
*zout = z;
|
||||||
|
|
||||||
|
return 0 <= a && 0 <= b && a + b <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -615,20 +510,19 @@ fprintf(stderr, "%d: processing segment ", recursive++); seg_print(s);
|
|||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
v3_t bary[2] = {};
|
float z0, z1;
|
||||||
int inside0 = tri_inside(t, &s->p[0], &bary[0]);
|
int inside0 = tri_find_z(t, &s->p[0], &z0);
|
||||||
int inside1 = tri_inside(t, &s->p[1], &bary[1]);
|
int inside1 = tri_find_z(t, &s->p[1], &z1);
|
||||||
|
|
||||||
// if both are inside and the triangle is behind
|
// if both are inside but the segment is infront of the
|
||||||
// this segment, then we discard this segment
|
// triangle, then we retain the segment.
|
||||||
|
// otherwies we discard the segment
|
||||||
if (inside0 && inside1)
|
if (inside0 && inside1)
|
||||||
{
|
{
|
||||||
float p0_tri_z = tri_find_z(t, &s->p[0]);
|
if (s->p[0].p[2] <= z0)
|
||||||
if (s->p[0].p[2] <= p0_tri_z)
|
continue;
|
||||||
|
if (s->p[1].p[2] <= z1)
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr, "z=%.3f ", p0_tri_z);
|
|
||||||
seg_print(s);
|
|
||||||
tri_print(t);
|
|
||||||
|
|
||||||
//svg_line("#0000FF", s->p[0].p, s->p[1].p, 0);
|
//svg_line("#0000FF", s->p[0].p, s->p[1].p, 0);
|
||||||
//svg_line("#00FF00", t->p[0].p, t->p[1].p, 0);
|
//svg_line("#00FF00", t->p[0].p, t->p[1].p, 0);
|
||||||
@ -638,8 +532,6 @@ if(0) {
|
|||||||
fprintf(stderr, "BOTH INSIDE\n");
|
fprintf(stderr, "BOTH INSIDE\n");
|
||||||
tri_print(t);
|
tri_print(t);
|
||||||
seg_print(s);
|
seg_print(s);
|
||||||
fprintf(stderr, "bary0 %f,%f,%f\n", bary[0].p[0], bary[0].p[1], bary[0].p[2]);
|
|
||||||
fprintf(stderr, "bary1 %f,%f,%f\n", bary[1].p[0], bary[1].p[1], bary[1].p[2]);
|
|
||||||
}
|
}
|
||||||
//svg_line("#00FF00", s->p[0].p, s->p[1].p, 10);
|
//svg_line("#00FF00", s->p[0].p, s->p[1].p, 10);
|
||||||
//svg_line("#0000FF", t->p[0].p, t->p[1].p, 2);
|
//svg_line("#0000FF", t->p[0].p, t->p[1].p, 2);
|
||||||
@ -708,25 +600,7 @@ svg_line("#00FF00", s->p[0].p, s->p[1].p, 10);
|
|||||||
|
|
||||||
if (intersections == 2)
|
if (intersections == 2)
|
||||||
{
|
{
|
||||||
// if the segment intersection is closer than the triangle,
|
// figure out how far it is to each of the intersections
|
||||||
// then we do nothing. degenerate cases are not handled
|
|
||||||
if (is[0].p[2] <= it[0].p[2]
|
|
||||||
|| is[1].p[2] <= it[1].p[2])
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
fprintf(stderr, "ignoring collision since z %f < %f || %f < %f\n",
|
|
||||||
is[0].p[2], it[0].p[2],
|
|
||||||
is[1].p[2], it[1].p[2]);
|
|
||||||
*/
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// segment is behind the triangle,
|
|
||||||
// we have to create a new segment
|
|
||||||
// and shorten the existing segment
|
|
||||||
// find the two intersections that we have
|
|
||||||
// update the src field
|
|
||||||
const float d00 = v3_len(&s->p[0], &is[0]);
|
const float d00 = v3_len(&s->p[0], &is[0]);
|
||||||
const float d01 = v3_len(&s->p[0], &is[1]);
|
const float d01 = v3_len(&s->p[0], &is[1]);
|
||||||
const float d10 = v3_len(&s->p[1], &is[0]);
|
const float d10 = v3_len(&s->p[1], &is[0]);
|
||||||
@ -747,6 +621,23 @@ fprintf(stderr, "ignoring collision since z %f < %f || %f < %f\n",
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the segment intersection is closer than the triangle,
|
||||||
|
// then we do nothing. degenerate cases are not handled
|
||||||
|
if (d00 <= d01
|
||||||
|
&& is[0].p[2] <= it[0].p[2]
|
||||||
|
&& is[1].p[2] <= it[1].p[2])
|
||||||
|
continue;
|
||||||
|
if (d00 > d01
|
||||||
|
&& is[1].p[2] <= it[0].p[2]
|
||||||
|
&& is[0].p[2] <= it[1].p[2])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// segment is behind the triangle,
|
||||||
|
// we have to create a new segment
|
||||||
|
// and shorten the existing segment
|
||||||
|
// find the two intersections that we have
|
||||||
|
// update the src field
|
||||||
|
|
||||||
// we need to create a new segment
|
// we need to create a new segment
|
||||||
seg_t * news;
|
seg_t * news;
|
||||||
if (d00 < d01)
|
if (d00 < d01)
|
||||||
@ -785,8 +676,12 @@ seg_print(news);
|
|||||||
// is closer than the triangle intercept, then no problem.
|
// is closer than the triangle intercept, then no problem.
|
||||||
// we do not bother with degenerate cases of intersecting
|
// we do not bother with degenerate cases of intersecting
|
||||||
// triangles
|
// triangles
|
||||||
if (is[0].p[2] <= it[0].p[2])
|
if (is[0].p[2] <= it[0].p[2]
|
||||||
|
&& is[1].p[2] <= it[0].p[2])
|
||||||
|
{
|
||||||
|
//svg_line("#00FF00", s->p[0].p, s->p[1].p, 10);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// due to floating point issues, one of these might
|
// due to floating point issues, one of these might
|
||||||
@ -827,6 +722,7 @@ seg_print(news);
|
|||||||
news->src[1] = s->src[1];
|
news->src[1] = s->src[1];
|
||||||
s->p[0] = is[0];
|
s->p[0] = is[0];
|
||||||
tri_seg_intersect(zlist->next, news, slist_visible);
|
tri_seg_intersect(zlist->next, news, slist_visible);
|
||||||
|
//svg_line("#00FF00", s->p[0].p, s->p[1].p, 10);
|
||||||
//fprintf(stderr, "%d -----\n", --recursive);
|
//fprintf(stderr, "%d -----\n", --recursive);
|
||||||
|
|
||||||
// continue splitting our current segment
|
// continue splitting our current segment
|
||||||
|
Loading…
Reference in New Issue
Block a user