diff --git a/example/q3bsp.cpp b/example/q3bsp.cpp index aee9208..026257d 100644 --- a/example/q3bsp.cpp +++ b/example/q3bsp.cpp @@ -68,10 +68,12 @@ #include "palette.hpp" #include "printf/unparse.h" -constexpr int font_offset = ((0x7f - 0x20) + 1) * 8 * 16 / 2; +#include "assert.h" #include "pk/texture.h" +constexpr int font_offset = ((0x7f - 0x20) + 1) * 8 * 16 / 2; + using vec2 = vec<2, float>; using vec3 = vec<3, float>; using vec4 = vec<4, float>; @@ -143,6 +145,34 @@ static inline vec3 screen_transform(vec3 v) }; } +void global_polygon_type_0(ta_parameter_writer& writer) +{ + const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume + | para_control::list_type::translucent + | obj_control::col_type::packed_color + ; + + const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater + | isp_tsp_instruction_word::culling_mode::no_culling; + + const uint32_t tsp_instruction_word = tsp_instruction_word::fog_control::no_fog + | tsp_instruction_word::src_alpha_instr::src_alpha + | tsp_instruction_word::dst_alpha_instr::inverse_src_alpha + | tsp_instruction_word::use_alpha + ; + + const uint32_t texture_control_word = 0; + + writer.append() = + ta_global_parameter::polygon_type_0(parameter_control_word, + isp_tsp_instruction_word, + tsp_instruction_word, + texture_control_word, + 0, // data_size_for_sort_dma + 0 // next_address_for_sort_dma + ); +} + void global_polygon_type_1(ta_parameter_writer& writer, uint32_t obj_control_texture, uint32_t texture_u_v_size, @@ -390,6 +420,93 @@ void transfer_faces(uint8_t * buf, q3bsp_header_t * header, ta_parameter_writer& } } +static inline void render_quad(ta_parameter_writer& writer, + vec3 ap, + vec3 bp, + vec3 cp, + vec3 dp, + uint32_t base_color) +{ + if (ap.z < 0 || bp.z < 0 || cp.z < 0 || dp.z < 0) + return; + + writer.append() = + ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(false), + ap.x, ap.y, ap.z, + base_color); + + writer.append() = + ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(false), + bp.x, bp.y, bp.z, + base_color); + + writer.append() = + ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(false), + dp.x, dp.y, dp.z, + base_color); + + writer.append() = + ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(true), + cp.x, cp.y, cp.z, + base_color); +} + +void render_bounding_box(ta_parameter_writer& writer, mat4x4& trans, vec3 max, vec3 min, uint32_t color) +{ + vec3 a = max; + vec3 b = min; + + global_polygon_type_0(writer); + + // ax + render_quad(writer, + screen_transform(trans * (vec3){a.x, a.y, a.z}), + screen_transform(trans * (vec3){a.x, b.y, a.z}), + screen_transform(trans * (vec3){a.x, b.y, b.z}), + screen_transform(trans * (vec3){a.x, a.y, b.z}), + color); + + // bx + render_quad(writer, + screen_transform(trans * (vec3){b.x, a.y, a.z}), + screen_transform(trans * (vec3){b.x, b.y, a.z}), + screen_transform(trans * (vec3){b.x, b.y, b.z}), + screen_transform(trans * (vec3){b.x, a.y, b.z}), + color); + + // ay + render_quad(writer, + screen_transform(trans * (vec3){b.x, a.y, a.z}), + screen_transform(trans * (vec3){a.x, a.y, a.z}), + screen_transform(trans * (vec3){a.x, a.y, b.z}), + screen_transform(trans * (vec3){b.x, a.y, b.z}), + color); + + // by + render_quad(writer, + screen_transform(trans * (vec3){b.x, b.y, a.z}), + screen_transform(trans * (vec3){a.x, b.y, a.z}), + screen_transform(trans * (vec3){a.x, b.y, b.z}), + screen_transform(trans * (vec3){b.x, b.y, b.z}), + color); + + // az + render_quad(writer, + screen_transform(trans * (vec3){b.x, a.y, a.z}), + screen_transform(trans * (vec3){b.x, b.y, a.z}), + screen_transform(trans * (vec3){a.x, b.y, a.z}), + screen_transform(trans * (vec3){a.x, a.y, a.z}), + color); + + // bz + render_quad(writer, + screen_transform(trans * (vec3){b.x, a.y, b.z}), + screen_transform(trans * (vec3){b.x, b.y, b.z}), + screen_transform(trans * (vec3){a.x, b.y, b.z}), + screen_transform(trans * (vec3){a.x, a.y, b.z}), + color); +} + int format_float(char * s, float num, int pad_length) { int offset = 0; @@ -431,6 +548,115 @@ void render_matrix(ta_parameter_writer& writer, const mat4x4& trans) } } +static int root_ix = 0; + +void render_ix(ta_parameter_writer& writer, int row, char * s, int ix) +{ + int offset = 15; + bool is_leaf = ix < 0; + if (ix < 0) + ix = -(ix - 1); + + offset += unparse_base10_unsigned(&s[offset], ix, 5, ' '); + + if (is_leaf) { + s[offset++] = ' '; + s[offset++] = '('; + s[offset++] = 'l'; + s[offset++] = 'e'; + s[offset++] = 'a'; + s[offset++] = 'f'; + s[offset++] = ')'; + } else { + s[offset++] = ' '; + s[offset++] = '('; + s[offset++] = 'n'; + s[offset++] = 'o'; + s[offset++] = 'd'; + s[offset++] = 'e'; + s[offset++] = ')'; + } + + font_bitmap::transform_string(writer, + 8, 16, // texture + 8, 16, // glyph + 16 + 50 * 8, // position x + 16 + row * 16, // position y + s, offset, + para_control::list_type::opaque); +} + +void render_leaf_ix(ta_parameter_writer& writer) +{ + uint8_t * buf = reinterpret_cast(&_binary_pk_maps_20kdm2_bsp_start); + q3bsp_header_t * header = reinterpret_cast(buf); + q3bsp_direntry * ne = &header->direntries[LUMP_NODES]; + q3bsp_node_t * nodes = reinterpret_cast(&buf[ne->offset]); + q3bsp_node_t * root = &nodes[root_ix]; + + { + char s[32] = "root: "; + int row = 0; + render_ix(writer, row, s, root_ix); + } + + { + char s[32] = "root.child[0]: "; + int row = 1; + render_ix(writer, row, s, root->children[0]); + } + + { + char s[32] = "root.child[1]: "; + int row = 2; + render_ix(writer, row, s, root->children[1]); + } +} + +void render_bounding_box_mm(ta_parameter_writer& writer, mat4x4& trans, int mins[3], int maxs[3], uint32_t color) +{ + vec3 max = {(float)maxs[0], (float)maxs[1], (float)maxs[2]}; + vec3 min = {(float)mins[0], (float)mins[1], (float)mins[2]}; + render_bounding_box(writer, trans, max, min, color); +} + +void render_bounding_boxes(ta_parameter_writer& writer, mat4x4& trans) +{ + uint8_t * buf = reinterpret_cast(&_binary_pk_maps_20kdm2_bsp_start); + q3bsp_header_t * header = reinterpret_cast(buf); + + q3bsp_direntry * le = &header->direntries[LUMP_LEAFS]; + q3bsp_leaf_t * leafs = reinterpret_cast(&buf[le->offset]); + + q3bsp_direntry * ne = &header->direntries[LUMP_NODES]; + q3bsp_node_t * nodes = reinterpret_cast(&buf[ne->offset]); + q3bsp_node_t * root = &nodes[root_ix]; + + { + if (root->children[0] >= 0) { + q3bsp_node_t * a = &nodes[root->children[0]]; + uint32_t color = 0x80ff00e6; + render_bounding_box_mm(writer, trans, a->mins, a->maxs, color); + } else { + int leaf_ix = -(root->children[0] + 1); + q3bsp_leaf_t * leaf = &leafs[leaf_ix]; + uint32_t color = 0x80ff0016; + render_bounding_box_mm(writer, trans, leaf->maxs, leaf->mins, color); + } + + if (root->children[1] >= 0) { + q3bsp_node_t * b = &nodes[root->children[1]]; + uint32_t color = 0x8000ffe6; + render_bounding_box_mm(writer, trans, b->mins, b->maxs, color); + } else { + int leaf_ix = -(root->children[1] + 1); + q3bsp_leaf_t * leaf = &leafs[leaf_ix]; + uint32_t color = 0x8000ff16; + render_bounding_box_mm(writer, trans, leaf->maxs, leaf->mins, color); + } + } +} + void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans) { uint8_t * buf = reinterpret_cast(&_binary_pk_maps_20kdm2_bsp_start); @@ -443,7 +669,13 @@ void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans) transfer_faces(buf, header, writer); - render_matrix(writer, screen_trans); + render_matrix(writer, trans); + render_leaf_ix(writer); + + writer.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + + render_bounding_boxes(writer, trans); writer.append() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); @@ -528,6 +760,8 @@ void transfer_textures() } } +static bool push = false; + mat4x4 update_analog(mat4x4& screen) { const float x_ = static_cast(data[0].analog_coordinate_axis[2] - 0x80) / 127.f; @@ -538,6 +772,9 @@ mat4x4 update_analog(mat4x4& screen) int da = ft0::data_transfer::digital_button::da(data[0].digital_button) == 0; int ua = ft0::data_transfer::digital_button::ua(data[0].digital_button) == 0; + int db_x = ft0::data_transfer::digital_button::x(data[0].digital_button) == 0; + int db_y = ft0::data_transfer::digital_button::y(data[0].digital_button) == 0; + float x = 0; if (ra && !la) x = -10; if (la && !ra) x = 10; @@ -570,6 +807,34 @@ mat4x4 update_analog(mat4x4& screen) 0, 0, 0, 1, }; + uint8_t * buf = reinterpret_cast(&_binary_pk_maps_20kdm2_bsp_start); + q3bsp_header_t * header = reinterpret_cast(buf); + //q3bsp_direntry * le = &header->direntries[LUMP_LEAFS]; + //int num_leaves = le->length / (sizeof (struct q3bsp_leaf)); + q3bsp_direntry * ne = &header->direntries[LUMP_NODES]; + q3bsp_node_t * nodes = reinterpret_cast(&buf[ne->offset]); + + if (db_x && !db_y && !push) { + push = true; + //leaf_ix -= 1; + //if (leaf_ix < 0) leaf_ix = num_leaves - 1; + + int ix = nodes[root_ix].children[0]; + if (ix >= 0) + root_ix = ix; + } + if (db_y && !db_x && !push) { + push = true; + //leaf_ix += 1; + //if (leaf_ix > num_leaves) leaf_ix = 0; + int ix = nodes[root_ix].children[1]; + if (ix >= 0) + root_ix = ix; + } + if (!db_x && !db_y) { + push = false; + } + return rx * ry * t * screen; } @@ -597,7 +862,7 @@ int main() constexpr uint32_t ta_alloc = 0 | ta_alloc_ctrl::pt_opb::no_list | ta_alloc_ctrl::tm_opb::no_list - | ta_alloc_ctrl::t_opb::no_list + | ta_alloc_ctrl::t_opb::_16x4byte | ta_alloc_ctrl::om_opb::no_list | ta_alloc_ctrl::o_opb::_16x4byte; @@ -606,7 +871,7 @@ int main() { .opaque = 16 * 4, .opaque_modifier = 0, - .translucent = 0, + .translucent = 16 * 4, .translucent_modifier = 0, .punch_through = 0 } @@ -672,7 +937,8 @@ int main() transfer_scene(writer, trans); ta_polygon_converter_writeback(writer.buf, writer.offset); ta_polygon_converter_transfer(writer.buf, writer.offset); - ta_wait_opaque_list(); + ta_wait_translucent_list(); + //ta_wait_opaque_list(); render_done = 0; core_start_render2(texture_memory_alloc.region_array[core].start, diff --git a/model/icosphere/icosphere.obj b/model/icosphere/icosphere.obj new file mode 100644 index 0000000..f30fd7c --- /dev/null +++ b/model/icosphere/icosphere.obj @@ -0,0 +1,78 @@ +# Blender 4.2.1 LTS +# www.blender.org +o Icosphere +v 0.000000 -1.000000 0.000000 +v 0.723600 -0.447215 0.525720 +v -0.276385 -0.447215 0.850640 +v -0.894425 -0.447215 0.000000 +v -0.276385 -0.447215 -0.850640 +v 0.723600 -0.447215 -0.525720 +v 0.276385 0.447215 0.850640 +v -0.723600 0.447215 0.525720 +v -0.723600 0.447215 -0.525720 +v 0.276385 0.447215 -0.850640 +v 0.894425 0.447215 0.000000 +v 0.000000 1.000000 0.000000 +vn 0.1876 -0.7947 0.5774 +vn 0.6071 -0.7947 -0.0000 +vn -0.4911 -0.7947 0.3568 +vn -0.4911 -0.7947 -0.3568 +vn 0.1876 -0.7947 -0.5774 +vn 0.9822 -0.1876 -0.0000 +vn 0.3035 -0.1876 0.9342 +vn -0.7946 -0.1876 0.5774 +vn -0.7946 -0.1876 -0.5774 +vn 0.3035 -0.1876 -0.9342 +vn 0.7946 0.1876 0.5774 +vn -0.3035 0.1876 0.9342 +vn -0.9822 0.1876 -0.0000 +vn -0.3035 0.1876 -0.9342 +vn 0.7946 0.1876 -0.5774 +vn 0.4911 0.7947 0.3568 +vn -0.1876 0.7947 0.5774 +vn -0.6071 0.7947 -0.0000 +vn -0.1876 0.7947 -0.5774 +vn 0.4911 0.7947 -0.3568 +vt 0.181819 0.000000 +vt 0.272728 0.157461 +vt 0.090910 0.157461 +vt 0.363637 0.000000 +vt 0.454546 0.157461 +vt 0.909091 0.000000 +vt 1.000000 0.157461 +vt 0.818182 0.157461 +vt 0.727273 0.000000 +vt 0.636364 0.157461 +vt 0.545455 0.000000 +vt 0.363637 0.314921 +vt 0.181819 0.314921 +vt 0.909091 0.314921 +vt 0.727273 0.314921 +vt 0.545455 0.314921 +vt 0.000000 0.314921 +vt 0.272728 0.472382 +vt 0.090910 0.472382 +vt 0.818182 0.472382 +vt 0.636364 0.472382 +vt 0.454546 0.472382 +s 0 +f 1/1/1 2/2/1 3/3/1 +f 2/2/2 1/4/2 6/5/2 +f 1/6/3 3/7/3 4/8/3 +f 1/9/4 4/8/4 5/10/4 +f 1/11/5 5/10/5 6/5/5 +f 2/2/6 6/5/6 11/12/6 +f 3/3/7 2/2/7 7/13/7 +f 4/8/8 3/7/8 8/14/8 +f 5/10/9 4/8/9 9/15/9 +f 6/5/10 5/10/10 10/16/10 +f 2/2/11 11/12/11 7/13/11 +f 3/3/12 7/13/12 8/17/12 +f 4/8/13 8/14/13 9/15/13 +f 5/10/14 9/15/14 10/16/14 +f 6/5/15 10/16/15 11/12/15 +f 7/13/16 11/12/16 12/18/16 +f 8/17/17 7/13/17 12/19/17 +f 9/15/18 8/14/18 12/20/18 +f 10/16/19 9/15/19 12/21/19 +f 11/12/20 10/16/20 12/22/20