forked from osresearch/papercraft
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtri.h
165 lines (136 loc) · 3.11 KB
/
tri.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* Triangle manipulations
*/
#ifndef _tri_h_
#define _tri_h_
#include "v3.h"
#include "seg.h"
#include "svg.h"
extern int tri_debug;
typedef struct _tri_t tri_t;
struct _tri_t
{
v3_t p[3]; // camera space
v3_t normal; // camera space
v3_t normal_xyz; // original xyz space
v3_t min; // camera space
v3_t max; // camera space
tri_t * next;
tri_t ** prev;
};
tri_t *
tri_new(
const v3_t * p_cam,
const v3_t * p_xyz
);
// insert a triangle into our z-sorted list
void
tri_insert(
tri_t ** zlist,
tri_t * t
);
void
tri_delete(tri_t * t);
// Compute the 2D area of a triangle in screen space
// using Heron's formula
float
tri_area_2d(
const tri_t * const t
);
void
tri_print(
const tri_t * const t
);
/* Check if two triangles are coplanar and share an edge.
*
* Returns -1 if not coplanar, 0-2 for the edge in t0 that they share.
*/
int
tri_coplanar(
const tri_t * const t0,
const tri_t * const t1,
const float coplanar_eps
);
/*
* Find the Z point of an XY coordinate in a triangle.
*
* p can be written as a combination of t01 and t02,
* p - t0 = a * (t1 - t0) + b * (t2 - t0)
* setting t0 to 0, this becomes:
* p = a * t1 + b * t2
* which is two equations with two unknowns
*
* Returns true if the point is inside the triangle
*/
int
tri_find_z(
const tri_t * const t,
const v3_t * const p,
float * const zout
);
/** Compute the points of intersection for two segments in 2d, and z points.
*
* This is a specialized ray intersection algorithm for the
* hidden wire-frame removal code that computes the intersection
* points for two rays (in 2D, "orthographic") and then computes
* the Z depth for the intersections along each of the segments.
*
* Returns -1 for non-intersecting, otherwise a ratio of how far
* along the intersection is on the l0.
*/
float
hidden_intersect(
const v3_t * const p0,
const v3_t * const p1,
const v3_t * const p2,
const v3_t * const p3,
v3_t * const l0_int,
v3_t * const l1_int
);
/*
* Given a line segment and a list of triangles,
* find if the line segment crosses any triangle.
* If it crosses a triangle the segment will be shortened
* and an additional one might be created.
* Recusively try intersecting the new segment (starting at the same triangle)
* and then continue trying the shortened segment.
*
* Line segments will be added to the visible list.
* Returns the number of new elements created
*/
int
tri_seg_hidden(
const tri_t * zlist,
seg_t * s,
seg_t ** slist_visible
);
/*
* Fast check to see if t2 is entire occluded by t.
*/
int
tri_behind(
const tri_t * const t,
const tri_t * const t2
);
/*
* There are four possible line/triangle intersections.
*/
typedef enum {
tri_no_intersection, // nothing changed
tri_infront, // segment is in front of the triangle
tri_hidden, // segment is completely occluded
tri_clipped, // segment is partially occluded on one end
tri_split, // segment is partially occluded in the middle
} tri_intersect_t;
tri_intersect_t
tri_seg_intersect(
const tri_t * tri,
seg_t * s,
seg_t ** new_seg // only if tri_split
);
v3_t
tri_bary_coord(
const tri_t * const t,
const v3_t * const p
);
#endif