]>
Dogcows Code - chaz/rasterize/blob - tri.h
3 * CS5600 University of Utah
5 * mcgarvey@eng.utah.edu
17 * A triangle is a polygon of three vertices.
25 typedef struct tri tri_t
;
28 * Initialize a triangle.
31 void tri_init(tri_t
* t
, vert_t a
, vert_t b
, vert_t c
)
40 * Create a new triangle.
43 tri_t
tri_new(vert_t a
, vert_t b
, vert_t c
)
46 tri_init(&t
, a
, b
, c
);
50 #define TRI_ZERO tri_new(VERT_ZERO, VERT_ZERO, VERT_ZERO)
54 * Create a new triangle on the heap.
57 tri_t
* tri_alloc(vert_t a
, vert_t b
, vert_t c
)
59 tri_t
* t
= (tri_t
*)mem_alloc(sizeof(tri_t
));
66 * Apply a transformation matrix to alter the triangle geometry.
69 tri_t
tri_transform(tri_t t
, mat_t m
)
71 t
.a
.v
= mat_apply(m
, t
.a
.v
);
72 t
.b
.v
= mat_apply(m
, t
.b
.v
);
73 t
.c
.v
= mat_apply(m
, t
.c
.v
);
74 t
.a
.n
.w
= t
.b
.n
.w
= t
.c
.n
.w
= S(0.0);
75 t
.a
.n
= vec_normalize(mat_apply(m
, t
.a
.n
));
76 t
.b
.n
= vec_normalize(mat_apply(m
, t
.b
.n
));
77 t
.c
.n
= vec_normalize(mat_apply(m
, t
.c
.n
));
82 * Perform a homogeneous divide on the geometry.
85 tri_t
tri_homodiv(tri_t t
)
87 t
.a
.v
= vec_homodiv(t
.a
.v
);
88 t
.b
.v
= vec_homodiv(t
.b
.v
);
89 t
.c
.v
= vec_homodiv(t
.c
.v
);
95 * Calculate a normal vector.
98 vec_t
tri_normal(tri_t t
)
100 vec_t n
= vec_cross(vec_sub(t
.b
.v
, t
.a
.v
), vec_sub(t
.c
.v
, t
.a
.v
));
106 * Calculate the AABB for the triangle.
109 aabb_t
tri_aabb(tri_t t
)
112 b
.min
= vec_new(scal_min2(t
.a
.v
.x
, t
.b
.v
.x
, t
.c
.v
.x
),
113 scal_min2(t
.a
.v
.y
, t
.b
.v
.y
, t
.c
.v
.y
),
114 scal_min2(t
.a
.v
.z
, t
.b
.v
.z
, t
.c
.v
.z
));
115 b
.max
= vec_new(scal_max2(t
.a
.v
.x
, t
.b
.v
.x
, t
.c
.v
.x
),
116 scal_max2(t
.a
.v
.y
, t
.b
.v
.y
, t
.c
.v
.y
),
117 scal_max2(t
.a
.v
.z
, t
.b
.v
.z
, t
.c
.v
.z
));
123 * Get the barycentric coordinates of a vector against a triangle. The
124 * returned coordinates will be a linear combination, but they may not
125 * actually be barycentric coordinates. Use the function vec_is_barycentric
126 * to check if they really are barycentric coordinates, meaning the point
127 * vector v is inside the triangle, ignoring the Z components.
130 bool tri_barycentric(tri_t t
, scal_t
* b
, vec_t v
)
132 scal_t denom
= (t
.b
.v
.y
- t
.c
.v
.y
) * (t
.a
.v
.x
- t
.c
.v
.x
) + (t
.c
.v
.x
- t
.b
.v
.x
) * (t
.a
.v
.y
- t
.c
.v
.y
);
133 b
[0] = ((t
.b
.v
.y
- t
.c
.v
.y
) * (v
.x
- t
.c
.v
.x
) + (t
.c
.v
.x
- t
.b
.v
.x
) * (v
.y
- t
.c
.v
.y
)) / denom
;
134 b
[1] = ((t
.c
.v
.y
- t
.a
.v
.y
) * (v
.x
- t
.c
.v
.x
) + (t
.a
.v
.x
- t
.c
.v
.x
) * (v
.y
- t
.c
.v
.y
)) / denom
;
135 b
[2] = S(1.0) - b
[0] - b
[1];
136 if (S(0.0) <= b
[0] && b
[0] <= S(1.0) &&
137 S(0.0) <= b
[1] && b
[1] <= S(1.0) &&
138 S(0.0) <= b
[2] && b
[2] <= S(1.0)) {
146 * Find the midpoint of the triangle.
149 vec_t
tri_midpoint(tri_t t
)
151 return vec_new((t
.a
.v
.x
+ t
.b
.v
.x
+ t
.c
.v
.x
) * S(0.333),
152 (t
.a
.v
.y
+ t
.b
.v
.y
+ t
.c
.v
.y
) * S(0.333),
153 (t
.a
.v
.z
+ t
.b
.v
.z
+ t
.c
.v
.z
) * S(0.333));
157 * Get the average color of the triangle.
160 color_t
tri_color(tri_t t
)
162 scal_t b
[] = {S(0.333), S(0.333), S(0.333)};
163 return color_interp2(t
.a
.c
, t
.b
.c
, t
.c
.c
, b
);
168 * Get an interpolated z-value at the barycentric coordinates.
171 scal_t
tri_z(tri_t t
, scal_t b
[3])
173 return t
.a
.v
.z
* b
[0] + t
.b
.v
.z
* b
[1] + t
.c
.v
.z
* b
[2];
177 * Calculate an interpolated point.
180 vec_t
tri_point(tri_t t
, scal_t b
[3])
182 return vec_interp(t
.a
.v
, t
.b
.v
, t
.c
.v
, b
);
186 * Calculate an interpolated normal.
189 vec_t
tri_normal2(tri_t t
, scal_t b
[3])
191 return vec_normalize(vec_interp(t
.a
.n
, t
.b
.n
, t
.c
.n
, b
));
195 * Calculate an interpolated texture coordinate.
198 vec_t
tri_tcoord(tri_t t
, scal_t b
[3])
201 return vec_tinterp(t
.a
.t
, t
.b
.t
, t
.c
.t
, b
);
203 return vec_interp(t
.a
.t
, t
.b
.t
, t
.c
.t
, b
);
208 * Calculate an entirely new vertex within the triangle based on barycentric
212 vert_t
tri_interp(tri_t t
, scal_t b
[3])
214 vert_t v
= vert_new(tri_point(t
, b
));
215 v
.c
= color_interp2(t
.a
.c
, t
.b
.c
, t
.c
.c
, b
);
216 v
.n
= tri_normal2(t
, b
);
217 v
.t
= tri_tcoord(t
, b
);
This page took 0.046179 seconds and 4 git commands to generate.