bezier: switch to quad-vector interpolation

This allows 20kdm2 to use bezier normals.
This commit is contained in:
Zack Buhman 2025-04-28 20:43:13 -05:00
parent f7abfa14cf
commit 7213d5f30d
4 changed files with 51 additions and 32 deletions

View File

@ -746,7 +746,8 @@ static inline void transfer_face_patch_surfaces(ta_parameter_writer& writer, con
const vec2& blm = bv->n;
const vec2& clm = cv->n;
float li0 = 1.0;
const vec3 n = normal_transform(trans, av->o);
float li0 = light_intensity(light_vec, n);
float li1 = 2.0;
render_tri_type_13(writer,
@ -1416,6 +1417,8 @@ void render_visible_faces(ta_parameter_writer& writer, const mat4x4& trans, cons
}
*/
if (!(a_inside || b_inside))
return;
assert(a_inside || b_inside);
//assert(new_root != NULL);
root = new_root;

View File

@ -4,11 +4,12 @@
namespace bezier {
template <typename T, int L, int M, int N>
struct vec_lmn {
template <typename T, int L, int M, int N, int O>
struct vec_lmno {
vec<L, T> l;
vec<M, T> m;
vec<N, T> n;
vec<O, T> o;
};
struct triangle {
@ -17,13 +18,13 @@ struct triangle {
int c;
};
template <typename T, int L, int M, int N>
template <typename T, int L, int M, int N, int O>
constexpr inline
vec_lmn<T, L, M, N>
vec_lmno<T, L, M, N, O>
interpolate_quadratic(const T d,
const vec<L, T>& l1, const vec<M, T>& m1, const vec<N, T>& n1,
const vec<L, T>& l2, const vec<M, T>& m2, const vec<N, T>& n2,
const vec<L, T>& l3, const vec<M, T>& m3, const vec<N, T>& n3)
const vec<L, T>& l1, const vec<M, T>& m1, const vec<N, T>& n1, const vec<O, T>& o1,
const vec<L, T>& l2, const vec<M, T>& m2, const vec<N, T>& n2, const vec<O, T>& o2,
const vec<L, T>& l3, const vec<M, T>& m3, const vec<N, T>& n3, const vec<O, T>& o3)
{
T invd = 1.0 - d;
T d1 = invd * invd;
@ -45,33 +46,38 @@ interpolate_quadratic(const T d,
n[i] = n1[i] * d1 + n2[i] * d2 + n3[i] * d3;
};
return {l, m, n};
vec<O, T> o;
for (int i = 0; i < O; i++) {
o[i] = o1[i] * d1 + o2[i] * d2 + o3[i] * d3;
};
return {l, m, n, o};
}
template <typename T, int L, int M, int N>
template <typename T, int L, int M, int N, int O>
constexpr inline
vec_lmn<T, L, M, N>
vec_lmno<T, L, M, N, O>
interpolate_quadratic(const T d,
const vec_lmn<T, L, M, N>& va,
const vec_lmn<T, L, M, N>& vb,
const vec_lmn<T, L, M, N>& vc)
const vec_lmno<T, L, M, N, O>& va,
const vec_lmno<T, L, M, N, O>& vb,
const vec_lmno<T, L, M, N, O>& vc)
{
return interpolate_quadratic<T>(d,
va.l, va.m, va.n,
vb.l, vb.m, vb.n,
vc.l, vc.m, vc.n);
va.l, va.m, va.n, va.o,
vb.l, vb.m, vb.n, vb.o,
vc.l, vc.m, vc.n, vc.o);
}
template <typename T, int L, int M, int N>
template <typename T, int L, int M, int N, int O>
constexpr inline
void
tessellate(const int level,
const vec_lmn<T, L, M, N> * control, // [9]
vec_lmn<T, L, M, N> * vertices, // [2 * level * level]
const vec_lmno<T, L, M, N, O> * control, // [9]
vec_lmno<T, L, M, N, O> * vertices, // [2 * level * level]
triangle * triangles,
int vertex_base = 0)
{
vec_lmn<T, L, M, N> column[3][level + 1];
vec_lmno<T, L, M, N, O> column[3][level + 1];
T inv_level = 1.0 / level;
for (int i = 0; i <= level; i++) {

View File

@ -74,17 +74,27 @@ static int triangulate_patch(const q3bsp_vertex_t * vertexes,
const vec2 h_l = {h->lightmap[0], h->lightmap[1]};
const vec2 i_l = {i->lightmap[0], i->lightmap[1]};
const vec3 a_n = {a->normal[0], a->normal[1], a->normal[2]};
const vec3 b_n = {b->normal[0], b->normal[1], b->normal[2]};
const vec3 c_n = {c->normal[0], c->normal[1], c->normal[2]};
const vec3 d_n = {d->normal[0], d->normal[1], d->normal[2]};
const vec3 e_n = {e->normal[0], e->normal[1], e->normal[2]};
const vec3 f_n = {f->normal[0], f->normal[1], f->normal[2]};
const vec3 g_n = {g->normal[0], g->normal[1], g->normal[2]};
const vec3 h_n = {h->normal[0], h->normal[1], h->normal[2]};
const vec3 i_n = {i->normal[0], i->normal[1], i->normal[2]};
const vertex_plm control[9] = {
{a_p, a_t, a_l}, {b_p, b_t, b_l}, {c_p, c_t, c_l},
{d_p, d_t, d_l}, {e_p, e_t, e_l}, {f_p, f_t, f_l},
{g_p, g_t, g_l}, {h_p, h_t, h_l}, {i_p, i_t, i_l},
{a_p, a_t, a_l, a_n}, {b_p, b_t, b_l, b_n}, {c_p, c_t, c_l, c_n},
{d_p, d_t, d_l, d_n}, {e_p, e_t, e_l, e_n}, {f_p, f_t, f_l, f_n},
{g_p, g_t, g_l, g_n}, {h_p, h_t, h_l, h_n}, {i_p, i_t, i_l, i_n},
};
bezier::tessellate<float, 3, 2, 2>(level,
control,
p_vtx,
p_tri,
vertex_base);
bezier::tessellate<float, 3, 2, 2, 3>(level,
control,
p_vtx,
p_tri,
vertex_base);
p_vtx += vertices_per_surface;
p_tri += triangles_per_surface;
vertex_base += vertices_per_surface;

View File

@ -5,8 +5,8 @@
namespace q3bsp_patch {
constexpr int max_patch_count = 16; // 12
constexpr int max_surface_count = 32; // 20
constexpr int max_level = 3;
constexpr int level = 3;
constexpr int max_level = 5;
constexpr int level = 5;
constexpr int max_vertices_per_surface = (max_level + 1) * (max_level + 1);
constexpr int max_triangles_per_surface = max_level * max_level * 2;
@ -17,7 +17,7 @@ namespace q3bsp_patch {
void triangulate_patches(const void * bsp);
extern int patch_count;
using vertex_plm = bezier::vec_lmn<float, 3, 2, 2>;
using vertex_plm = bezier::vec_lmno<float, 3, 2, 2, 3>;
struct patch {
int face_ix;