Compare commits

..

No commits in common. "1f80d210845f5d30ff14a98331d4fe513bd57305" and "92428711e4e7d0b18da59242afb3b3252e360751" have entirely different histories.

3 changed files with 177 additions and 364 deletions

View File

@ -92,8 +92,6 @@ static ft0::data_transfer::data_format data[4];
uint8_t send_buf[1024] __attribute__((aligned(32)));
uint8_t recv_buf[1024] __attribute__((aligned(32)));
constexpr void * bsp_start = &_binary_bsp_20kdm2_maps_20kdm2_bsp_start;
void do_get_condition()
{
auto writer = maple::host_command_writer(send_buf, recv_buf);
@ -183,40 +181,6 @@ void global_polygon_type_0(ta_parameter_writer& writer)
);
}
void global_polygon_type_0_textured(ta_parameter_writer& writer,
uint32_t obj_control_texture,
uint32_t texture_u_v_size,
uint32_t texture_control_word
)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::opaque
| obj_control::col_type::floating_color
| obj_control::gouraud
| obj_control_texture
;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
| isp_tsp_instruction_word::culling_mode::cull_if_negative
;
const uint32_t tsp_instruction_word = tsp_instruction_word::fog_control::no_fog
| tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero
| tsp_instruction_word::filter_mode::bilinear_filter
| tsp_instruction_word::texture_shading_instruction::modulate
| texture_u_v_size
;
writer.append<ta_global_parameter::polygon_type_0>() =
ta_global_parameter::polygon_type_0(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
texture_control_word,
0,
0);
}
void global_polygon_type_1(ta_parameter_writer& writer,
uint32_t obj_control_texture,
uint32_t texture_u_v_size,
@ -272,10 +236,10 @@ void global_texture(ta_parameter_writer& writer, int ix)
| texture_control_word::texture_address(texture_address / 8)
;
global_polygon_type_0_textured(writer,
obj_control::texture,
texture_u_v_size,
texture_control_word);
global_polygon_type_1(writer,
obj_control::texture,
texture_u_v_size,
texture_control_word);
}
void transform_vertices(uint8_t * buf, int length, const mat4x4& trans)
@ -319,55 +283,53 @@ static inline void render_tri_type_2(ta_parameter_writer& writer,
ci);
}
static int type5_tri_count = 0;
static int type7_tri_count = 0;
static int vis_tri_count = 0;
static int total_tri_count = 0;
static inline void render_tri_type_5(ta_parameter_writer& writer,
static inline void render_tri_type_7(ta_parameter_writer& writer,
vec3 ap,
vec3 bp,
vec3 cp,
vec2 at,
vec2 bt,
vec2 ct,
vec3 ac,
vec3 bc,
vec3 cc)
float ai,
float bi,
float ci)
{
type5_tri_count += 1;
type7_tri_count += 1;
writer.append<ta_vertex_parameter::polygon_type_5>() =
ta_vertex_parameter::polygon_type_5(polygon_vertex_parameter_control_word(false),
writer.append<ta_vertex_parameter::polygon_type_7>() =
ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(false),
ap.x, ap.y, ap.z,
at.x, at.y,
1.0, ac.x, ac.y, ac.z,
0, 0, 0, 0);
ai,
0);
writer.append<ta_vertex_parameter::polygon_type_5>() =
ta_vertex_parameter::polygon_type_5(polygon_vertex_parameter_control_word(false),
writer.append<ta_vertex_parameter::polygon_type_7>() =
ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(false),
bp.x, bp.y, bp.z,
bt.x, bt.y,
1.0, bc.x, bc.y, bc.z,
0, 0, 0, 0);
bi,
0);
writer.append<ta_vertex_parameter::polygon_type_5>() =
ta_vertex_parameter::polygon_type_5(polygon_vertex_parameter_control_word(true),
writer.append<ta_vertex_parameter::polygon_type_7>() =
ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(true),
cp.x, cp.y, cp.z,
ct.x, ct.y,
1.0, cc.x, cc.y, cc.z,
0, 0, 0, 0);
ci,
0);
}
static inline void render_clip_tri_type_5(ta_parameter_writer& writer,
static inline void render_clip_tri_type_7(ta_parameter_writer& writer,
vec3 ap,
vec3 bp,
vec3 cp,
vec2 at,
vec2 bt,
vec2 ct,
vec3 ac,
vec3 bc,
vec3 cc)
float li)
{
//return;
const vec3 plane_point = {0.f, 0.f, 1.f};
@ -375,19 +337,15 @@ static inline void render_clip_tri_type_5(ta_parameter_writer& writer,
vec3 preclip_position[] = {ap, bp, cp};
vec2 preclip_texture[] = {at, bt, ct};
vec3 preclip_color[] = {ac, bc, cc};
vec3 clip_position[4];
vec2 clip_texture[4];
vec3 clip_color[4];
int output_length = geometry::clip_polygon_3<3>(clip_position,
clip_texture,
clip_color,
plane_point,
plane_normal,
preclip_position,
preclip_texture,
preclip_color);
int output_length = geometry::clip_polygon_uv<3>(clip_position,
clip_texture,
plane_point,
plane_normal,
preclip_position,
preclip_texture);
{
vec3 ap;
@ -399,40 +357,35 @@ static inline void render_clip_tri_type_5(ta_parameter_writer& writer,
const vec2& bt = clip_texture[1];
const vec2& ct = clip_texture[2];
const vec2& dt = clip_texture[3];
const vec3& ac = clip_color[0];
const vec3& bc = clip_color[1];
const vec3& cc = clip_color[2];
const vec3& dc = clip_color[3];
if (output_length >= 3) {
ap = screen_transform(clip_position[0]);
bp = screen_transform(clip_position[1]);
cp = screen_transform(clip_position[2]);
render_tri_type_5(writer,
render_tri_type_7(writer,
ap,
bp,
cp,
at,
bt,
ct,
ac,
bc,
cc);
li,
li,
li);
}
if (output_length >= 4) {
dp = screen_transform(clip_position[3]);
render_tri_type_5(writer,
render_tri_type_7(writer,
ap,
cp,
dp,
at,
ct,
dt,
ac,
cc,
dc);
li,
li,
li);
}
}
}
@ -460,7 +413,7 @@ static vec3 light_vec = {20, -20, -20};
static inline void transfer_face(ta_parameter_writer& writer, q3bsp_face_t * face, int * last_texture)
{
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
q3bsp_direntry * ve = &header->direntries[LUMP_VERTEXES];
@ -509,9 +462,6 @@ static inline void transfer_face(ta_parameter_writer& writer, q3bsp_face_t * fac
vec3 n = vertex_cache[aix].normal;
float li = light_intensity(light_vec, n);
vec3 ac = (vec3){1, 1, 1} * li;
vec3 bc = ac;
vec3 cc = ac;
if (has_texture) {
float v_mul = textures[face->texture].v_mul;
@ -520,28 +470,26 @@ static inline void transfer_face(ta_parameter_writer& writer, q3bsp_face_t * fac
vec2 ct = {vert[cix].texcoord[0], vert[cix].texcoord[1] * v_mul};
if (ap.z < 0 || bp.z < 0 || cp.z < 0) {
render_clip_tri_type_5(writer,
render_clip_tri_type_7(writer,
ap,
bp,
cp,
at,
bt,
ct,
ac,
bc,
cc);
li);
} else {
render_tri_type_5(writer,
render_tri_type_7(writer,
screen_transform(ap),
screen_transform(bp),
screen_transform(cp),
at,
bt,
ct,
ac,
bc,
cc);
li,
li,
li);
}
} else {
/*
@ -559,7 +507,7 @@ static inline void transfer_face(ta_parameter_writer& writer, q3bsp_face_t * fac
void transfer_faces(ta_parameter_writer& writer)
{
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
@ -576,7 +524,7 @@ void transfer_faces(ta_parameter_writer& writer)
int count_face_triangles()
{
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
@ -858,7 +806,7 @@ void render_ix(ta_parameter_writer& writer, int row, char * s, int ix)
void render_leaf_ix(ta_parameter_writer& writer)
{
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
q3bsp_direntry * ne = &header->direntries[LUMP_NODES];
q3bsp_node_t * nodes = reinterpret_cast<q3bsp_node_t *>(&buf[ne->offset]);
@ -912,7 +860,7 @@ void render_tris_count(ta_parameter_writer& writer)
{
char s[32] = "rendered tris: ";
int row = 2;
render_num(writer, row, s, type5_tri_count, offset);
render_num(writer, row, s, type7_tri_count, offset);
}
}
@ -925,7 +873,7 @@ void render_bounding_box_mm(ta_parameter_writer& writer, const mat4x4& trans, in
void render_bounding_boxes(ta_parameter_writer& writer, const mat4x4& trans)
{
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
q3bsp_direntry * le = &header->direntries[LUMP_LEAFS];
@ -973,7 +921,7 @@ bool vec3_in_bb(vec3 v, int mins[3], int maxs[3])
void render_leaf_faces(ta_parameter_writer& writer, const mat4x4& trans, q3bsp_leaf_t * leaf)
{
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
//int leafface First leafface for leaf.
@ -1000,7 +948,7 @@ void render_leaf_faces(ta_parameter_writer& writer, const mat4x4& trans, q3bsp_l
void render_visible_faces(ta_parameter_writer& writer, const mat4x4& trans, const vec3 pos)
{
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
q3bsp_direntry * le = &header->direntries[LUMP_LEAFS];
@ -1062,7 +1010,7 @@ void render_visible_faces(ta_parameter_writer& writer, const mat4x4& trans, cons
}
assert(bb_leaf != NULL);
//uint32_t color = 0x8000ff16;
uint32_t color = 0x8000ff16;
//render_bounding_box_mm(writer, trans, bb_leaf->maxs, bb_leaf->mins, color);
render_leaf_faces(writer, trans, bb_leaf);
@ -1080,7 +1028,7 @@ void render_visible_faces(ta_parameter_writer& writer, const mat4x4& trans, cons
int x = leaf->cluster;
bool visible = (visdata->vecs[x * visdata->sz_vecs + y / 8] & (1 << (y % 8))) != 0;
if (visible) {
//uint32_t color = 0x40ff00e6;
uint32_t color = 0x40ff00e6;
//render_bounding_box_mm(writer, trans, leaf->maxs, leaf->mins, color);
render_leaf_faces(writer, trans, leaf);
}
@ -1089,7 +1037,7 @@ void render_visible_faces(ta_parameter_writer& writer, const mat4x4& trans, cons
void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans, const mat4x4& screen_trans_inv)
{
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
const mat4x4 trans = screen_trans;
@ -1109,7 +1057,7 @@ void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans, con
//render_zero_position(writer, screen_trans_inv);
vec3 pos = screen_trans_inv * (vec3){0, 0, 0};
type5_tri_count = 0;
type7_tri_count = 0;
vis_tri_count = 0;
for (int i = 0; i < face_count; i++) face_cache[i] = 0;
render_visible_faces(writer, trans, pos);
@ -1265,7 +1213,7 @@ mat4x4 update_analog(const mat4x4& screen)
0, 0, 0, 1,
};
uint8_t * buf = reinterpret_cast<uint8_t *>(bsp_start);
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_bsp_20kdm2_maps_20kdm2_bsp_start);
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
//q3bsp_direntry * le = &header->direntries[LUMP_LEAFS];
//int num_leaves = le->length / (sizeof (struct q3bsp_leaf));

View File

@ -4,7 +4,7 @@
namespace geometry {
template <typename T, int L>
template <int L, typename T>
constexpr inline
T line_plane_intersection_d(const vec<L, T>& plane_point, // p0
const vec<L, T>& plane_normal, // n
@ -19,7 +19,7 @@ T line_plane_intersection_d(const vec<L, T>& plane_point, // p0
return intersection;
}
template <typename T, int L>
template <int L, typename T>
constexpr inline
vec<L, T> line_plane_intersection(const vec<L, T>& plane_point, // p0
const vec<L, T>& plane_normal, // n
@ -34,19 +34,32 @@ vec<L, T> line_plane_intersection(const vec<L, T>& plane_point, // p0
return line_start + line_vector * intersection;
}
template <typename T, int L>
template <int L, typename T, int M>
constexpr inline
vec<L, T> interpolate(const vec<L, T>& line_start,
const vec<L, T>& line_end,
T intersection
)
std::tuple<vec<L, T>, vec<M, T>> line_plane_intersection_two_lines(const vec<L, T>& plane_point, // p0
const vec<L, T>& plane_normal, // n
const vec<L, T>& line_start, // l0
const vec<L, T>& line_end,
const vec<M, T>& line2_start,
const vec<M, T>& line2_end
)
{
const auto line_vector = line_end - line_start; // l
/* it is assumed that line and line2 are the same line, but in different
coordinates spaces. It is therefore possible to re-use the same
interpolation value on either line vector.
*/
return line_start + line_vector * intersection;
const auto line_vector = line_end - line_start; // l
const auto line2_vector = line2_end - line2_start;
const T intersection = line_plane_intersection_d(plane_point, plane_normal, line_start, line_vector); // d
return { line_start + line_vector * intersection
, line2_start + line2_vector * intersection
};
}
template <typename T, int L>
template <int L, typename T>
T clip_boundary(const vec<L, T>& plane_point, // X
const vec<L, T>& plane_normal, // Nc
const vec<L, T>& line_point
@ -61,7 +74,7 @@ inline T positive_modulo(T a, T b)
return (a % b + b) % b;
}
template <int polygon_len, typename T, int L>
template <int polygon_len, int L, typename T>
inline int clip_polygon1(vec<L, T> * output,
const vec<L, T> plane_point,
const vec<L, T> plane_normal,
@ -73,7 +86,7 @@ inline int clip_polygon1(vec<L, T> * output,
const vec<L, T>& s = polygon[ix_s];
const vec<L, T>& f = polygon[ix_f];
bool this_inside = 0.f < clip_boundary<T, L>(plane_point,
bool this_inside = 0.f < clip_boundary<L, T>(plane_point,
plane_normal,
f);
@ -85,7 +98,7 @@ inline int clip_polygon1(vec<L, T> * output,
case 0b01: // I, F
length = 2;
{
const auto i = line_plane_intersection<T, L>(plane_point, plane_normal, s, f);
const auto i = line_plane_intersection<L, T>(plane_point, plane_normal, s, f);
*output++ = i;
*output++ = f;
}
@ -93,7 +106,7 @@ inline int clip_polygon1(vec<L, T> * output,
case 0b10: // I
length = 1;
{
const auto i = line_plane_intersection<T, L>(plane_point, plane_normal, s, f);
const auto i = line_plane_intersection<L, T>(plane_point, plane_normal, s, f);
*output++ = i;
}
break;
@ -106,7 +119,7 @@ inline int clip_polygon1(vec<L, T> * output,
bool end_of_polygon = ix_f == (polygon_len - 1);
if (!end_of_polygon) {
return length +
clip_polygon1<polygon_len, T, L>(output,
clip_polygon1<polygon_len, L, T>(output,
plane_point,
plane_normal,
polygon,
@ -129,11 +142,11 @@ int clip_polygon(vec<L, T> * output,
// It would be nice to remove the extra dot product, but the
// alternative seems likely uglier.
bool this_inside = 0.f < clip_boundary<T, L>(plane_point,
bool this_inside = 0.f < clip_boundary<L, T>(plane_point,
plane_normal,
f);
return clip_polygon1<polygon_len, T, L>(output,
return clip_polygon1<polygon_len, L, T>(output,
plane_point,
plane_normal,
polygon,
@ -142,219 +155,104 @@ int clip_polygon(vec<L, T> * output,
this_inside);
}
template <int polygon_len, typename T, int L, int M>
inline int clip_polygon1_2(vec<L, T> * output_1,
vec<M, T> * output_2,
const vec<L, T> plane_point,
const vec<L, T> plane_normal,
const vec<L, T> * polygon_1,
const vec<M, T> * polygon_2,
const int ix_s,
const int ix_f,
const bool last_inside)
template <int polygon_len, int L, typename T, int M>
inline int clip_polygon1_uv(vec<L, T> * output,
vec<M, T> * output_uv,
const vec<L, T> plane_point,
const vec<L, T> plane_normal,
const vec<L, T> * polygon,
const vec<M, T> * polygon_uv,
const int ix_s,
const int ix_f,
const bool last_inside)
{
const vec<L, T>& s_1 = polygon_1[ix_s];
const vec<L, T>& f_1 = polygon_1[ix_f];
const vec<L, T>& s = polygon[ix_s];
const vec<L, T>& f = polygon[ix_f];
const vec<M, T>& s_2 = polygon_2[ix_s];
const vec<M, T>& f_2 = polygon_2[ix_f];
const vec<M, T>& s_uv = polygon_uv[ix_s];
const vec<M, T>& f_uv = polygon_uv[ix_f];
bool this_inside = 0.f < clip_boundary<T, L>(plane_point,
plane_normal,
f_1);
int length = 0;
int control = (last_inside << 1) | (this_inside << 0);
switch (control) {
case 0b00: // no output
break;
case 0b10: // I
[[fallthrough]];
case 0b01: // I, F
{
const auto& i_1_start = s_1;
const auto i_1_vector = f_1 - s_1; // l
const T intersection = line_plane_intersection_d<T, L>(plane_point, plane_normal,
i_1_start, i_1_vector);
const vec<L, T> i_1 = i_1_start + i_1_vector * intersection;
*output_1++ = i_1;
*output_2++ = interpolate(s_2, f_2, intersection);
if (control == 0b01) { // I, F
*output_1++ = f_1;
*output_2++ = f_2;
length = 2;
} else {
length = 1;
}
}
break;
case 0b11: // F
*output_1++ = f_1;
*output_2++ = f_2;
length = 1;
break;
}
bool end_of_polygon = ix_f == (polygon_len - 1);
if (!end_of_polygon) {
return length +
clip_polygon1_2<polygon_len, T, L, M>(output_1,
output_2,
plane_point,
plane_normal,
polygon_1,
polygon_2,
ix_f,
ix_f + 1,
this_inside);
} else {
return length;
}
}
template <int polygon_len, typename T, int L, int M>
int clip_polygon_2(vec<L, T> * output_1,
vec<M, T> * output_2,
const vec<L, T>& plane_point,
const vec<L, T>& plane_normal,
const vec<L, T> * polygon_1,
const vec<M, T> * polygon_2
)
{
const vec<L, T> f = polygon_1[polygon_len - 1];
// It would be nice to remove the extra dot product, but the
// alternative seems likely uglier.
bool this_inside = 0.f < clip_boundary<T, L>(plane_point,
bool this_inside = 0.f < clip_boundary<L, T>(plane_point,
plane_normal,
f);
return clip_polygon1_2<polygon_len, T, L, M>(output_1,
output_2,
plane_point,
plane_normal,
polygon_1,
polygon_2,
polygon_len - 1, // ix_s
0, // ix_f
this_inside);
}
template <int polygon_len, typename T, int L, int M, int N>
inline int clip_polygon1_3(vec<L, T> * output_1,
vec<M, T> * output_2,
vec<N, T> * output_3,
const vec<L, T> plane_point,
const vec<L, T> plane_normal,
const vec<L, T> * polygon_1,
const vec<M, T> * polygon_2,
const vec<N, T> * polygon_3,
const int ix_s,
const int ix_f,
const bool last_inside)
{
const vec<L, T>& s_1 = polygon_1[ix_s];
const vec<L, T>& f_1 = polygon_1[ix_f];
const vec<M, T>& s_2 = polygon_2[ix_s];
const vec<M, T>& f_2 = polygon_2[ix_f];
const vec<N, T>& s_3 = polygon_3[ix_s];
const vec<N, T>& f_3 = polygon_3[ix_f];
bool this_inside = 0.f < clip_boundary<T, L>(plane_point,
plane_normal,
f_1);
int length = 0;
int control = (last_inside << 1) | (this_inside << 0);
switch (control) {
switch ((last_inside << 1) | (this_inside << 0)) {
case 0b00: // no output
length = 0;
break;
case 0b10: // I
[[fallthrough]];
case 0b01: // I, F
length = 2;
{
const auto& i_1_start = s_1;
const auto i_1_vector = f_1 - s_1; // l
const T intersection = line_plane_intersection_d<T, L>(plane_point, plane_normal,
i_1_start, i_1_vector);
const vec<L, T> i_1 = i_1_start + i_1_vector * intersection;
*output_1++ = i_1;
*output_2++ = interpolate(s_2, f_2, intersection);
*output_3++ = interpolate(s_3, f_3, intersection);
if (control == 0b01) { // I, F
*output_1++ = f_1;
*output_2++ = f_2;
*output_3++ = f_3;
length = 2;
} else {
length = 1;
}
auto [i, i_uv] = line_plane_intersection_two_lines<L, T, M>(plane_point, plane_normal,
s, f,
s_uv, f_uv);
*output++ = i;
*output_uv++ = i_uv;
*output++ = f;
*output_uv++ = f_uv;
}
break;
case 0b10: // I
length = 1;
{
auto [i, i_uv] = line_plane_intersection_two_lines<L, T, M>(plane_point, plane_normal,
s, f,
s_uv, f_uv);
*output++ = i;
*output_uv++ = i_uv;
}
break;
case 0b11: // F
*output_1++ = f_1;
*output_2++ = f_2;
*output_3++ = f_3;
length = 1;
*output++ = f;
*output_uv++ = f_uv;
break;
}
bool end_of_polygon = ix_f == (polygon_len - 1);
if (!end_of_polygon) {
return length +
clip_polygon1_3<polygon_len, T, L, M, N>(output_1,
output_2,
output_3,
plane_point,
plane_normal,
polygon_1,
polygon_2,
polygon_3,
ix_f,
ix_f + 1,
this_inside);
clip_polygon1_uv<polygon_len, L, T, M>(output,
output_uv,
plane_point,
plane_normal,
polygon,
polygon_uv,
ix_f,
ix_f + 1,
this_inside);
} else {
return length;
}
}
template <int polygon_len, typename T, int L, int M, int N>
int clip_polygon_3(vec<L, T> * output_1,
vec<M, T> * output_2,
vec<N, T> * output_3,
const vec<L, T>& plane_point,
const vec<L, T>& plane_normal,
const vec<L, T> * polygon_1,
const vec<M, T> * polygon_2,
const vec<N, T> * polygon_3
)
template <int polygon_len, int L, typename T, int M>
int clip_polygon_uv(vec<L, T> * output,
vec<M, T> * output_uv,
const vec<L, T>& plane_point,
const vec<L, T>& plane_normal,
const vec<L, T> * polygon,
const vec<M, T> * polygon_uv
)
{
const vec<L, T> f = polygon_1[polygon_len - 1];
const vec<L, T> f = polygon[polygon_len - 1];
// It would be nice to remove the extra dot product, but the
// alternative seems likely uglier.
bool this_inside = 0.f < clip_boundary<T, L>(plane_point,
bool this_inside = 0.f < clip_boundary<L, T>(plane_point,
plane_normal,
f);
return clip_polygon1_3<polygon_len, T, L, M>(output_1,
output_2,
output_3,
plane_point,
plane_normal,
polygon_1,
polygon_2,
polygon_3,
polygon_len - 1, // ix_s
0, // ix_f
this_inside);
return clip_polygon1_uv<polygon_len, L, T, M>(output,
output_uv,
plane_point,
plane_normal,
polygon,
polygon_uv,
polygon_len - 1, // ix_s
0, // ix_f
this_inside);
}
}

View File

@ -36,8 +36,10 @@ void print_direntries(struct q3bsp_header * header)
}
}
void print_header(struct q3bsp_header * header)
void print_header(void * buf)
{
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
printf("magic: ");
putchar(header->magic[0]);
putchar(header->magic[1]);
@ -49,31 +51,27 @@ void print_header(struct q3bsp_header * header)
print_direntries(header);
}
void print_textures(uint8_t * buf, struct q3bsp_header * header)
void print_textures(void * buf, int length)
{
q3bsp_direntry * te = &header->direntries[LUMP_TEXTURES];
q3bsp_texture_t * textures = reinterpret_cast<q3bsp_texture_t *>(&buf[te->offset]);
q3bsp_texture_t * texture = reinterpret_cast<q3bsp_texture_t *>(buf);
int count = te->length / (sizeof (struct q3bsp_texture));
int count = length / (sizeof (struct q3bsp_texture));
for (int i = 0; i < count; i++) {
q3bsp_texture_t * texture = &textures[i];
printf("texture [%d]\n", i);
printf(" name=%s\n", texture->name);
printf(" flags=%x\n", texture->flags);
printf(" contents=%x\n", texture->contents);
printf(" name=%s\n", texture[i].name);
printf(" flags=%x\n", texture[i].flags);
printf(" contents=%x\n", texture[i].contents);
}
}
void print_models(uint8_t * buf, struct q3bsp_header * header)
void print_models(void * buf, int length)
{
q3bsp_direntry * me = &header->direntries[LUMP_MODELS];
q3bsp_model_t * models = reinterpret_cast<q3bsp_model_t *>(&buf[me->offset]);
q3bsp_model_t * model = reinterpret_cast<q3bsp_model_t *>(buf);
int count = me->length / (sizeof (struct q3bsp_model));
int count = length / (sizeof (struct q3bsp_model));
for (int i = 0; i < count; i++) {
q3bsp_model_t * model = &models[i];
printf("model [%d]\n", i);
printf(" mins={%f, %f, %f}\n", model->mins[0], model->mins[2], model->mins[2]);
printf(" maxs={%f, %f, %f}\n", model->maxs[0], model->maxs[2], model->maxs[2]);
@ -84,71 +82,40 @@ void print_models(uint8_t * buf, struct q3bsp_header * header)
}
}
void print_vertexes(uint8_t * buf, struct q3bsp_header * header)
void print_faces(void * buf, int length)
{
q3bsp_direntry * ve = &header->direntries[LUMP_VERTEXES];
q3bsp_vertex_t * vertexes = reinterpret_cast<q3bsp_vertex_t *>(&buf[ve->offset]);
q3bsp_face_t * face = reinterpret_cast<q3bsp_face_t *>(buf);
int count = ve->length / (sizeof (struct q3bsp_vertex));
printf("vertexes count: %d\n", count);
for (int i = 0; i < count; i++) {
q3bsp_vertex_t * vertex = &vertexes[i];
printf("vertex [%d]: lightmapcoord=(%f %f)\n", i, vertex->lightmapcoord[0], vertex->lightmapcoord[1]);
//assert(vertex->lightmapcoord[0] >= 0.0 && vertex->lightmapcoord[0] <= 1.0);
//assert(vertex->lightmapcoord[1] >= 0.0 && vertex->lightmapcoord[1] <= 1.0);
}
}
void print_faces(uint8_t * buf, struct q3bsp_header * header)
{
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
q3bsp_face_t * faces = reinterpret_cast<q3bsp_face_t *>(&buf[fe->offset]);
int count = fe->length / (sizeof (struct q3bsp_face));
int count = length / (sizeof (struct q3bsp_face));
printf("faces count: %d\n", count);
for (int i = 0; i < count; i++) {
q3bsp_face_t * face = &faces[i];
printf("face [%d]\n", i);
printf(" type=%d n_vertexes=%d n_meshverts=%d texture=%d lightmap=%d\n", face->type, face->n_vertexes, face->n_meshverts, face->texture, face->lm_index);
printf(" type=%d n_vertexes=%d n_meshverts=%d texture=%d\n", face[i].type, face[i].n_vertexes, face[i].n_meshverts, face[i].texture);
}
}
void print_lightmaps(uint8_t * buf, struct q3bsp_header * header)
{
q3bsp_direntry * lme = &header->direntries[LUMP_LIGHTMAPS];
q3bsp_lightmap_t * lightmaps = reinterpret_cast<q3bsp_lightmap_t *>(&buf[lme->offset]);
int count = lme->length / (sizeof (struct q3bsp_lightmap));
printf("lightmaps count: %d offset: %d\n", count, lme->offset);
}
void debug_print_q3bsp(uint8_t * buf, q3bsp_header_t * header)
{
// header
//print_header(header);
//print_header(buf);
if (0) {
print_textures(buf, header);
q3bsp_direntry * e = &header->direntries[LUMP_TEXTURES];
print_textures(&buf[e->offset], e->length);
}
if (0) {
print_models(buf, header);
}
if (1) {
print_vertexes(buf, header);
}
if (1) {
print_faces(buf, header);
}
if (1) {
print_lightmaps(buf, header);
q3bsp_direntry * e = &header->direntries[LUMP_MODELS];
print_models(&buf[e->offset], e->length);
}
if (0) {
q3bsp_direntry * e = &header->direntries[LUMP_FACES];
print_faces(&buf[e->offset], e->length);
}
{
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
q3bsp_face_t * faces = reinterpret_cast<q3bsp_face_t *>(&buf[fe->offset]);
int face_count = fe->length / (sizeof (struct q3bsp_face));