diff --git a/base.mk b/base.mk index 8f30382..47092d7 100644 --- a/base.mk +++ b/base.mk @@ -114,6 +114,12 @@ endef %.bsp.o: %.bsp $(BUILD_BINARY_O) +%.glm.h: %.glm + $(BUILD_BINARY_H) + +%.glm.o: %.glm + $(BUILD_BINARY_O) + %.o: %.s $(AS) $(AARCH) $(AFLAGS) $(DEBUG) $< -o $@ diff --git a/bsp/texture_gen.py b/bsp/texture_gen.py index 786149e..427e7a1 100644 --- a/bsp/texture_gen.py +++ b/bsp/texture_gen.py @@ -39,43 +39,36 @@ class Size: @dataclass class Texture: - name: str filename: str real_size: Size npot_size: Size offset: int -mipmapped = False - -def mip_size(n): +def mip_size(n, bytes_per_pixel): + assert bytes_per_pixel == 2 # fixme VQ codebook size if n == 0: return 0 - size = 6 + size = 0 if bytes_per_pixel < 1 else 6 while n > 0: - size += n * n * 2 + size += int(n * n * bytes_per_pixel) n >>= 1 return size -assert mip_size(256) == 0x2aab0, hex(mip_size(256)) +assert mip_size(256, 2) == 0x2aab0, hex(mip_size(256)) -def texture_metadata(): - global mipmapped - - names = read_texture_names() +def texture_metadata(filenames, mipmapped, bytes_per_pixel): acc = 0 - for name in names: - filename = glob_and_filter(name) + for filename in filenames: w, h = image_size(filename) nw, nh = npot(w), npot(h) - if w > 256: + if w > 512: name = None filename = None w, h, nw, nh = 0, 0, 0, 0 elif filename: print(filename) yield Texture( - name, filename, Size(w, h), Size(nw, nh), @@ -84,25 +77,33 @@ def texture_metadata(): if mipmapped: assert w == h and nw == w, (w, h) - acc += mip_size(w) + acc += mip_size(w, bytes_per_pixel) + assert acc % 32 == 0, (filename, acc) else: - acc += nw * h * 2 - assert acc <= (0x80_0000 - 0x37_1800), acc + if w != h: + h = w + assert w == h, (w, h) + extra = 0 if bytes_per_pixel == 2 else 256 * 4 * 2 + 16 + size = int(w * h * bytes_per_pixel) + extra + size = (size + 31) & (~31) + acc += size + assert acc % 32 == 0, (filename, acc) + assert acc <= (0x80_0000 - 0x38_4040), acc -def name_to_bin(filename): +def name_to_bin(prefix, suffix, filename): if filename is None: return None else: name, ext = path.splitext(filename) - return f"_binary_bsp_" + name.replace('/', '_').replace('.', '_').replace('-', '_') + "_data" + return f"_binary_" + prefix + name.replace('/', '_').replace('.', '_').replace('-', '_') + suffix def uv_mul(texture): u = 0 if texture.npot_size.w == 0 else texture.real_size.w / texture.npot_size.w v = 0 if texture.npot_size.h == 0 else texture.real_size.h / texture.npot_size.h return u, v -def render_texture_metadata(texture): - name = name_to_bin(texture.filename) +def render_texture_metadata(prefix, suffix, texture): + name = name_to_bin(prefix, suffix, texture.filename) u, v = uv_mul(texture) assert u == 1.0 or u == 0.0 start = "0" if name is None else f"&{name}_start" @@ -117,20 +118,24 @@ def render_texture_metadata(texture): yield f".v_mul = {v}, // {texture.real_size.h}" yield "}," -def render_texture_metadatas(): - for texture in texture_metadata(): - yield from render_texture_metadata(texture) +def render_texture_metadatas(names, mipmapped, bytes_per_pixel, prefix, suffix): + for texture in texture_metadata(names, mipmapped, bytes_per_pixel): + yield from render_texture_metadata(prefix, suffix, texture) def main(): global mipmapped out_filename = sys.argv[1] is_mipmapped = sys.argv[2] + bytes_per_pixel = float(sys.argv[3]) assert is_mipmapped in {"mipmapped", "non_mipmapped"} mipmapped = is_mipmapped == "mipmapped" - + names = map(glob_and_filter, read_texture_names()) render, out = renderer() - render(render_texture_metadatas()) + prefix = "bsp_" + suffix = "_data" + render(render_texture_metadatas(names, mipmapped, bytes_per_pixel, prefix, suffix)) with open(out_filename, "w") as f: f.write(out.getvalue()) -main() +if __name__ == "__main__": + main() diff --git a/example/bsp/20kdm2.cpp b/example/bsp/20kdm2.cpp index ecda67b..df6b380 100644 --- a/example/bsp/20kdm2.cpp +++ b/example/bsp/20kdm2.cpp @@ -75,6 +75,17 @@ #include "bsp/20kdm2/maps/20kdm2.bsp.h" #include "bsp/20kdm2/texture.h" +#include "mdxm/mdxm.h" +#include "model/tavion_new/model.glm.h" +#include "model/tavion_new/legs.vq.h" +#include "model/tavion_new/torso.vq.h" +#include "model/tavion_new/head.vq.h" +#include "model/tavion_new/face.vq.h" +#include "model/tavion_new/arm.vq.h" +#include "model/tavion_new/hands.vq.h" +#include "model/tavion_new/surface.h" +#include "model/tavion_new/texture.h" + #include "model/model.h" #include "model/icosphere/model.h" @@ -94,7 +105,7 @@ using mat4x4 = mat<4, 4, float>; #define _fsrra(n) (1.0f / (__builtin_sqrtf(n))) -static vec3 sphere_position = {890, 480, 450}; +static vec3 sphere_position = {890, 550, 450}; static ft0::data_transfer::data_format data[4]; @@ -104,6 +115,8 @@ uint8_t recv_buf[1024] __attribute__((aligned(32))); constexpr void * bsp_start = &_binary_bsp_20kdm2_maps_20kdm2_bsp_start; uint32_t lightmap_base = 0; +uint32_t bsp_base = 0; +uint32_t tavion_base = 0; void do_get_condition() { @@ -194,7 +207,7 @@ void global_polygon_type_0(ta_parameter_writer& writer) } void global_polygon_type_1(ta_parameter_writer& writer, - uint32_t obj_control_texture, + uint32_t para_control_obj_control, uint32_t texture_u_v_size, uint32_t texture_control_word, const float a = 1.0f, @@ -204,10 +217,9 @@ void global_polygon_type_1(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::intensity_mode_1 | obj_control::gouraud - | obj_control_texture + | para_control_obj_control ; const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater @@ -297,12 +309,40 @@ void global_texture(ta_parameter_writer& writer, int texture_ix) | texture_control_word::texture_address(texture_address / 8) ; + uint32_t control = para_control::list_type::translucent + | obj_control::texture; global_polygon_type_1(writer, - obj_control::texture, + control, texture_u_v_size, texture_control_word); } +void global_tavion_texture(ta_parameter_writer& writer, int texture_ix) +{ + const struct pk_texture * texture = &tavion_textures[texture_ix]; + + uint32_t texture_u_v_size = tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::texture_u_size::from_int(texture->width) + | tsp_instruction_word::texture_v_size::from_int(texture->height) + ; + + uint32_t texture_address = texture_memory_alloc.texture.start + font_base + lightmap_base + bsp_base + texture->offset; + uint32_t texture_control_word = texture_control_word::vq_compressed + | texture_control_word::pixel_format::_565 + | texture_control_word::scan_order::twiddled + | texture_control_word::texture_address(texture_address / 8) + ; + + uint32_t control = para_control::list_type::opaque + | obj_control::texture; + global_polygon_type_1(writer, + control, + texture_u_v_size, + texture_control_word); +} + +/* void global_lightmap(ta_parameter_writer& writer, int lightmap_ix) { uint32_t texture_u_v_size = tsp_instruction_word::src_alpha_instr::one @@ -322,6 +362,7 @@ void global_lightmap(ta_parameter_writer& writer, int lightmap_ix) texture_u_v_size, texture_control_word); } +*/ void global_texture_lightmap(ta_parameter_writer& writer, int texture_ix, int lightmap_ix) { @@ -961,7 +1002,18 @@ void transfer_icosphere(ta_parameter_writer& writer, const mat4x4& screen_trans) float r = 0.9f; float g = 0.5f; float b = 0.0f; - global_polygon_type_1(writer, 0, 0, 0, a, r, g, b); + uint32_t control = para_control::list_type::opaque; + uint32_t texture_u_v_size = tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero; + uint32_t texture_control_word = 0; + global_polygon_type_1(writer, + control, + texture_u_v_size, + texture_control_word, + a, + r, + g, + b); for (int i = 0; i < object->triangle_count; i++) { const union triangle * tri = &object->triangle[i]; @@ -982,6 +1034,97 @@ void transfer_icosphere(ta_parameter_writer& writer, const mat4x4& screen_trans) } } +struct mdxm_trans { + vec3 position; + vec3 normal; +}; + +static inline void transfer_mdxm_surface(ta_parameter_writer& writer, const mat4x4& trans, const mdxm_surface_t * surface) +{ + mdxm_vertex_t * v = (mdxm_vertex_t *) (((uint8_t *)surface) + surface->offset_verts); + + mdxm_trans transformed[surface->num_verts]; + for (int i = 0; i < surface->num_verts; i++) { + vec3 position = {v[i].position[0], v[i].position[1], v[i].position[2]}; + vec3 normal = {v[i].normal[0], v[i].normal[1], v[i].normal[2] }; + + transformed[i].position = trans * position; + transformed[i].normal = normal_transform(trans, normal); + } + + mdxm_triangle_t * triangles = (mdxm_triangle_t *)(((uint8_t *)surface) + surface->offset_triangles); + mdxm_vertex_texture_coord_t * texture = (mdxm_vertex_texture_coord_t *)&v[surface->num_verts]; + + for (int i = 0; i < surface->num_triangles; i++) { + const vec3& ap = transformed[triangles[i].index[0]].position; + const vec3& bp = transformed[triangles[i].index[1]].position; + const vec3& cp = transformed[triangles[i].index[2]].position; + //if (ap.z < 0 || bp.z < 0 || cp.z < 0) continue; + + const vec3& n = transformed[triangles[i].index[0]].normal; + float li = light_intensity(light_vec, n); + vec2 at = {texture[triangles[i].index[0]].texture[0], texture[triangles[i].index[0]].texture[1]}; + vec2 bt = {texture[triangles[i].index[1]].texture[0], texture[triangles[i].index[1]].texture[1]}; + vec2 ct = {texture[triangles[i].index[2]].texture[0], texture[triangles[i].index[2]].texture[1]}; + + render_tri_type_7(writer, + screen_transform(ap), + screen_transform(bp), + screen_transform(cp), + at, + bt, + ct, + li); + } +} + +void transfer_tavion(ta_parameter_writer& writer, const mat4x4& screen_trans) +{ + float s = 1; + mat4x4 scale = { + s, 0, 0, 0, + 0, -s, 0, 0, + 0, 0, s, 0, + 0, 0, 0, 1 + }; + + mat4x4 translate = { + 1, 0, 0, sphere_position.x, + 0, 1, 0, sphere_position.y, + 0, 0, 1, sphere_position.z, + 0, 0, 0, 1 + }; + + mat4x4 trans = screen_trans * translate * scale; + + uint8_t * buf = reinterpret_cast(&_binary_model_tavion_new_model_glm_start); + mdxm_header_t * header = (mdxm_header_t *)(buf); + mdxm_lod_t * lod = (mdxm_lod_t *)&buf[header->offset_lods]; + const int surface_offset = (sizeof (mdxm_lod_t)) + (header->num_surfaces * (sizeof (mdxm_lod_surf_offset_t))); + mdxm_surface_t * surface = (mdxm_surface_t *)(((uint8_t *)lod) + surface_offset); + //int count = 0; + + int last_texture_ix = -1; + + for (int i = 0; i < header->num_surfaces; i++) { + //printf("surf %d\n", i); + if (i > 36) + break; + if (tavion_surface[i] >= 0) { + int texture_ix = tavion_surface[i]; + if (tavion_surface[i] != last_texture_ix) + global_tavion_texture(writer, texture_ix); + last_texture_ix = texture_ix; + //printf("mdxm %d\n", i); + transfer_mdxm_surface(writer, trans, surface); + } + + // next surface + surface = (mdxm_surface_t *)(((uint8_t *)surface) + surface->offset_end); + } + //printf("count: %d\n", count); +} + static inline void render_quad(ta_parameter_writer& writer, vec3 ap, vec3 bp, @@ -1501,34 +1644,49 @@ void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans, con int face_count = fe->length / (sizeof (struct q3bsp_face)); //transfer_faces(writer, trans); - //transfer_icosphere(writer, trans); //render_matrix(writer, screen_trans); //render_leaf_ix(writer); //render_sphere_position(writer); //render_zero_position(writer, screen_trans_inv); - vec3 pos = screen_trans_inv * (vec3){0, 0, 0}; - typen_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); - //render_tris_count(writer); + // opaque list + { + //transfer_icosphere(writer, trans); + transfer_tavion(writer, trans); - writer.append() = - ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + writer.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + } + + // punch through list + { + vec3 pos = screen_trans_inv * (vec3){0, 0, 0}; + typen_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); + //render_tris_count(writer); + + writer.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + } // translucent list - transfer_billboard(writer, trans); + { + transfer_billboard(writer, trans); - writer.append() = - ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + writer.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + } // modifier volume list - transfer_modifier_volume(writer); + { + transfer_modifier_volume(writer); - writer.append() = - ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + writer.append() = + ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + } /* global_polygon_type_0(writer); @@ -1584,11 +1742,14 @@ constexpr inline mat4x4 rotate_z(float t) void transfer_ta_fifo_texture_memory_32byte(void * dst, void * src, int length) { + assert((((int)dst) & 31) == 0); + assert((((int)length) & 31) == 0); + uint32_t out_addr = (uint32_t)dst; sh7091.CCN.QACR0 = ((reinterpret_cast(out_addr) >> 24) & 0b11100); sh7091.CCN.QACR1 = ((reinterpret_cast(out_addr) >> 24) & 0b11100); - volatile uint32_t * base = &store_queue[(out_addr & 0x03ffffc0) / 4]; + volatile uint32_t * base = &store_queue[(out_addr & 0x03ffffe0) / 4]; uint32_t * src32 = reinterpret_cast(src); length = (length + 31) & ~31; // round up to nearest multiple of 32 @@ -1633,6 +1794,7 @@ void transfer_lightmaps() } uint32_t offset = texture_memory_alloc.texture.start + font_base + lightmap_base; + assert((offset & 31) == 0); // lightmap void * dst = reinterpret_cast(&ta_fifo_texture_memory[offset / 4]); uint32_t size = 128 * 128 * 2; transfer_ta_fifo_texture_memory_32byte(dst, temp, size); @@ -1641,24 +1803,67 @@ void transfer_lightmaps() } } +void transfer_bsp_textures() +{ + const int textures_length = (sizeof (textures)) / (sizeof (textures[0])); + + bsp_base = 0; + + for (int i = 0; i < textures_length; i++) { + uint32_t offset = texture_memory_alloc.texture.start + font_base + lightmap_base + textures[i].offset; + assert((offset & 31) == 0); // bsp + void * dst = reinterpret_cast(&ta_fifo_texture_memory[offset / 4]); + void * src = textures[i].start; + uint32_t size = textures[i].size; + size = (size + 31) & (~31); + assert((size & 31) == 0); + assert(offset + size < 0x800000); + transfer_ta_fifo_texture_memory_32byte(dst, src, size); + + bsp_base += (int)size; + } +} + +void transfer_tavion_textures() +{ + const int textures_length = (sizeof (tavion_textures)) / (sizeof (tavion_textures[0])); + + tavion_base = 0; + + for (int i = 0; i < textures_length; i++) { + uint32_t offset = texture_memory_alloc.texture.start + font_base + lightmap_base + bsp_base + tavion_textures[i].offset; + assert((offset & 31) == 0); // tavion + void * dst = reinterpret_cast(&ta_fifo_texture_memory[offset / 4]); + void * src = tavion_textures[i].start; + uint32_t size = tavion_textures[i].size; + size = (size + 31) & ~31; + assert(offset + size < 0x800000); + transfer_ta_fifo_texture_memory_32byte(dst, src, size); + + tavion_base += (int)size; + } +} + void transfer_textures() { system.LMMODE0 = 0; // 64-bit address space system.LMMODE1 = 0; // 64-bit address space transfer_lightmaps(); - printf("lightmap base: %d\n", lightmap_base); + transfer_bsp_textures(); + printf("bsp base: %d\n", bsp_base); + transfer_tavion_textures(); + printf("tavion base: %d\n", tavion_base); - const int textures_length = (sizeof (textures)) / (sizeof (textures[0])); + int total = 8 * 1024 * 1024; + int used = texture_memory_alloc.texture.start + + font_base + + lightmap_base + + bsp_base + + tavion_base; - for (int i = 0; i < textures_length; i++) { - uint32_t offset = texture_memory_alloc.texture.start + font_base + lightmap_base + textures[i].offset; - void * dst = reinterpret_cast(&ta_fifo_texture_memory[offset / 4]); - void * src = textures[i].start; - uint32_t size = textures[i].size; - transfer_ta_fifo_texture_memory_32byte(dst, src, size); - } + printf("texture memory free %d\n", total - used); } static bool push = false; @@ -1727,15 +1932,21 @@ mat4x4 update_analog(const mat4x4& screen) q3bsp_direntry * ne = &header->direntries[LUMP_NODES]; q3bsp_node_t * nodes = reinterpret_cast(&buf[ne->offset]); - if (0) { + //printf("%d %d\n", draw_tavion_surface, tavion_surface[draw_tavion_surface]); + if (1) { + uint8_t * buf = reinterpret_cast(&_binary_model_tavion_new_model_glm_start); + mdxm_header_t * header = (mdxm_header_t *)(buf); + 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; @@ -1748,7 +1959,7 @@ mat4x4 update_analog(const mat4x4& screen) if (!db_x && !db_y) { push = false; } - } else { + } else if (0) { if (db_x && !db_b) { sphere_position.x -= 10; } @@ -1800,12 +2011,12 @@ constexpr uint32_t ta_alloc = 0 | ta_alloc_ctrl::tm_opb::no_list | ta_alloc_ctrl::t_opb::_8x4byte | ta_alloc_ctrl::om_opb::_8x4byte - | ta_alloc_ctrl::o_opb::no_list; + | ta_alloc_ctrl::o_opb::_8x4byte; constexpr int ta_cont_count = 1; constexpr struct opb_size opb_size[ta_cont_count] = { { - .opaque = 0, + .opaque = 8 * 4, .opaque_modifier = 8 * 4, .translucent = 8 * 4, .translucent_modifier = 0, diff --git a/example/bsp/bsp.mk b/example/bsp/bsp.mk index 2536161..9cb06f7 100644 --- a/example/bsp/bsp.mk +++ b/example/bsp/bsp.mk @@ -44,6 +44,13 @@ BSP_20KDM2_OBJ = \ bsp/20kdm2/textures/sfx/flame6.data.o \ bsp/20kdm2/textures/sfx/flame7.data.o \ bsp/20kdm2/textures/sfx/flame8.data.o \ + model/tavion_new/model.glm.o \ + model/tavion_new/legs.vq.o \ + model/tavion_new/torso.vq.o \ + model/tavion_new/head.vq.o \ + model/tavion_new/face.vq.o \ + model/tavion_new/arm.vq.o \ + model/tavion_new/hands.vq.o \ $(LIBGCC) example/bsp/20kdm2.elf: LDSCRIPT = $(LIB)/main.lds diff --git a/gen/k_means/python/decode_pvrt.py b/gen/k_means/python/decode_pvrt.py index aefea2c..d28b78b 100644 --- a/gen/k_means/python/decode_pvrt.py +++ b/gen/k_means/python/decode_pvrt.py @@ -70,7 +70,7 @@ def decode_vq_indices(codebook, indices, width, height): bi = ((ty * 2) + 1) * width + ((tx * 2) + 0) ci = ((ty * 2) + 0) * width + ((tx * 2) + 1) di = ((ty * 2) + 1) * width + ((tx * 2) + 1) - print(width, height, ai, ty, tx) + #print(width, height, ai, ty, tx) canvas[ai] = codeword[0] canvas[bi] = codeword[1] canvas[ci] = codeword[2] diff --git a/mdxm/debug.c b/mdxm/debug.c index 9f440c2..ae8a7a2 100644 --- a/mdxm/debug.c +++ b/mdxm/debug.c @@ -24,6 +24,7 @@ void print_surface_hierarchy(struct mdxm_header * header) for (int i = 0; i < header->num_surfaces; i++) { printf("[%d] %s\n", i, &sh->shader[1]); printf(" %s\n", sh->name); + printf(" %d\n", sh->num_children); int offset = (int)(&(((mdxm_surf_hierarchy_t *)0)->child_indexes[sh->num_children])); sh = (mdxm_surf_hierarchy_t *)(((uint8_t *)sh) + offset); } @@ -41,29 +42,35 @@ void print_surfaces(struct mdxm_header * header) const int surface_offset = (sizeof (mdxm_lod_t)) + (header->num_surfaces * (sizeof (mdxm_lod_surf_offset_t))); for (int l = 0; l < header->num_lods; l++) { mdxm_surface_t * surf = (mdxm_surface_t *)(((uint8_t *)lod) + surface_offset); + int sum = 0; for (int i = 0; i < header->num_surfaces; i++) { //printf("surf ident: %d\n", surf->ident); //printf("offset header: %d\n", surf->offset_header); - mdxm_vertex_t * v = (mdxm_vertex_t *) (((uint8_t *)surf) + surf->offset_verts); - mdxm_vertex_texture_coord_t * t = (mdxm_vertex_texture_coord_t *)&v[surf->num_verts]; - printf("num_verts %d\n", surf->num_verts); - for (int j = 0; j < surf->num_verts; j++) { - printf("[%d] %f %f %f\n", j, v[j].position[0], v[j].position[1], v[j].position[2]); - printf(" %f %f %f\n", v[j].normal[0], v[j].normal[1], v[j].normal[2]); - } + if (0) { + mdxm_vertex_t * v = (mdxm_vertex_t *) (((uint8_t *)surf) + surf->offset_verts); + mdxm_vertex_texture_coord_t * t = (mdxm_vertex_texture_coord_t *)&v[surf->num_verts]; + printf("num_verts %d\n", surf->num_verts); + for (int j = 0; j < surf->num_verts; j++) { + printf("[%d] %f %f %f\n", j, v[j].position[0], v[j].position[1], v[j].position[2]); + printf(" %f %f %f\n", v[j].normal[0], v[j].normal[1], v[j].normal[2]); + } - mdxm_triangle_t * triangles = (mdxm_triangle_t *)(((uint8_t *)surf) + surf->offset_triangles); - printf("num_triangles %d\n", surf->num_triangles); - for (int j = 0; j < surf->num_triangles; j++) { - printf("%d %d %d\n", triangles[j].index[0], triangles[j].index[1], triangles[j].index[2]); + mdxm_triangle_t * triangles = (mdxm_triangle_t *)(((uint8_t *)surf) + surf->offset_triangles); + printf("num_triangles %d\n", surf->num_triangles); + for (int j = 0; j < surf->num_triangles; j++) { + printf("%d %d %d\n", triangles[j].index[0], triangles[j].index[1], triangles[j].index[2]); + } } + sum += surf->num_triangles; + // next surface surf = (mdxm_surface_t *)(((uint8_t *)surf) + surf->offset_end); } + printf("[%d] num_triangles: %d\n", l, surf->num_triangles); + // next lod lod = (mdxm_lod_t *)(((uint8_t *)lod) + lod->offset_end); - break; } } diff --git a/model/tavion_new/arm.vq b/model/tavion_new/arm.vq new file mode 100644 index 0000000..84cbed9 Binary files /dev/null and b/model/tavion_new/arm.vq differ diff --git a/model/tavion_new/arm.vq.h b/model/tavion_new/arm.vq.h new file mode 100644 index 0000000..26ed587 --- /dev/null +++ b/model/tavion_new/arm.vq.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_model_tavion_new_arm_vq_start __asm("_binary_model_tavion_new_arm_vq_start"); +extern uint32_t _binary_model_tavion_new_arm_vq_end __asm("_binary_model_tavion_new_arm_vq_end"); +extern uint32_t _binary_model_tavion_new_arm_vq_size __asm("_binary_model_tavion_new_arm_vq_size"); + +#ifdef __cplusplus +} +#endif diff --git a/model/tavion_new/face.vq b/model/tavion_new/face.vq new file mode 100644 index 0000000..b6d6e9b Binary files /dev/null and b/model/tavion_new/face.vq differ diff --git a/model/tavion_new/face.vq.h b/model/tavion_new/face.vq.h new file mode 100644 index 0000000..2c28c8d --- /dev/null +++ b/model/tavion_new/face.vq.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_model_tavion_new_face_vq_start __asm("_binary_model_tavion_new_face_vq_start"); +extern uint32_t _binary_model_tavion_new_face_vq_end __asm("_binary_model_tavion_new_face_vq_end"); +extern uint32_t _binary_model_tavion_new_face_vq_size __asm("_binary_model_tavion_new_face_vq_size"); + +#ifdef __cplusplus +} +#endif diff --git a/model/tavion_new/gen.sh b/model/tavion_new/gen.sh new file mode 100644 index 0000000..5adf6cf --- /dev/null +++ b/model/tavion_new/gen.sh @@ -0,0 +1,17 @@ +while read line; do + filename=$line + name="${line%.*}" + ppm_name="${name}.ppm" + vq_name="${name}.vq" + magick "${filename}" "${ppm_name}" + + #python ~/model_generator/color_convert.py $filename argb1555 twiddled non_mipmapped $data_name + ./gen/k_means/k_means_vq "${ppm_name}" "${vq_name}" & + make ${vq_name}.h +done + +for job in `jobs -p` +do + echo wait $job + wait $job +done diff --git a/model/tavion_new/gen_texture.py b/model/tavion_new/gen_texture.py new file mode 100644 index 0000000..7abea8b --- /dev/null +++ b/model/tavion_new/gen_texture.py @@ -0,0 +1,44 @@ +import sys +from os import path as os_path +from generate import renderer + +with open(sys.argv[1], "r") as f: + lines = f.read().strip().split('\n') + +prefix = "models/players" + +texture_ix = 0 +textures = {} + +def get_texture_ix(path): + global texture_ix + global textures + if path not in textures: + textures[path] = texture_ix + texture_ix += 1 + return textures[path] + +with open(sys.argv[2], "w") as f: + for line in lines: + name, path = line.split(",") + path = path.removeprefix(prefix) + path = path.removesuffix(".tga") + path = "model" + path + ".jpg" + if os_path.exists(path): + ix = get_texture_ix(path) + f.write(f" {ix}, // {line}\n") + else: + f.write(f" -1, // {line}\n") + +from texture_gen import render_texture_metadatas + +textures = [k for k, v in sorted(textures.items(), key=lambda kv: kv[1])] + +mipmapped = False +prefix = "" +suffix = "_vq" +render, out = renderer() +bytes_per_pixel = 0.25 +render(render_texture_metadatas(textures, mipmapped, bytes_per_pixel, prefix, suffix)) +with open(sys.argv[3], "w") as f: + f.write(out.getvalue()) diff --git a/model/tavion_new/hands.vq b/model/tavion_new/hands.vq new file mode 100644 index 0000000..6c11baa Binary files /dev/null and b/model/tavion_new/hands.vq differ diff --git a/model/tavion_new/hands.vq.h b/model/tavion_new/hands.vq.h new file mode 100644 index 0000000..6ff9ba9 --- /dev/null +++ b/model/tavion_new/hands.vq.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_model_tavion_new_hands_vq_start __asm("_binary_model_tavion_new_hands_vq_start"); +extern uint32_t _binary_model_tavion_new_hands_vq_end __asm("_binary_model_tavion_new_hands_vq_end"); +extern uint32_t _binary_model_tavion_new_hands_vq_size __asm("_binary_model_tavion_new_hands_vq_size"); + +#ifdef __cplusplus +} +#endif diff --git a/model/tavion_new/head.vq b/model/tavion_new/head.vq new file mode 100644 index 0000000..abab9a5 Binary files /dev/null and b/model/tavion_new/head.vq differ diff --git a/model/tavion_new/head.vq.h b/model/tavion_new/head.vq.h new file mode 100644 index 0000000..bea1626 --- /dev/null +++ b/model/tavion_new/head.vq.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_model_tavion_new_head_vq_start __asm("_binary_model_tavion_new_head_vq_start"); +extern uint32_t _binary_model_tavion_new_head_vq_end __asm("_binary_model_tavion_new_head_vq_end"); +extern uint32_t _binary_model_tavion_new_head_vq_size __asm("_binary_model_tavion_new_head_vq_size"); + +#ifdef __cplusplus +} +#endif diff --git a/model/tavion_new/legs.vq b/model/tavion_new/legs.vq new file mode 100644 index 0000000..fd99382 Binary files /dev/null and b/model/tavion_new/legs.vq differ diff --git a/model/tavion_new/legs.vq.h b/model/tavion_new/legs.vq.h new file mode 100644 index 0000000..f46ca66 --- /dev/null +++ b/model/tavion_new/legs.vq.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_model_tavion_new_legs_vq_start __asm("_binary_model_tavion_new_legs_vq_start"); +extern uint32_t _binary_model_tavion_new_legs_vq_end __asm("_binary_model_tavion_new_legs_vq_end"); +extern uint32_t _binary_model_tavion_new_legs_vq_size __asm("_binary_model_tavion_new_legs_vq_size"); + +#ifdef __cplusplus +} +#endif diff --git a/model/tavion_new/model.glm.h b/model/tavion_new/model.glm.h new file mode 100644 index 0000000..9515681 --- /dev/null +++ b/model/tavion_new/model.glm.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_model_tavion_new_model_glm_start __asm("_binary_model_tavion_new_model_glm_start"); +extern uint32_t _binary_model_tavion_new_model_glm_end __asm("_binary_model_tavion_new_model_glm_end"); +extern uint32_t _binary_model_tavion_new_model_glm_size __asm("_binary_model_tavion_new_model_glm_size"); + +#ifdef __cplusplus +} +#endif diff --git a/model/tavion_new/surface.h b/model/tavion_new/surface.h new file mode 100644 index 0000000..1409d2a --- /dev/null +++ b/model/tavion_new/surface.h @@ -0,0 +1,5 @@ +#pragma once + +const int tavion_surface[] = { + #include "surface.inc" +}; diff --git a/model/tavion_new/surface.inc b/model/tavion_new/surface.inc new file mode 100644 index 0000000..14e9751 --- /dev/null +++ b/model/tavion_new/surface.inc @@ -0,0 +1,37 @@ + 0, // hips,models/players/tavion_new/legs.tga + 0, // hips_belt,models/players/tavion_new/legs.tga + 0, // hips_pockets,models/players/tavion_new/legs.tga + 1, // torso,models/players/tavion_new/torso.tga + 1, // torso_armor,models/players/tavion_new/torso.tga + 2, // head,models/players/tavion_new/head.tga + 2, // head_hair,models/players/tavion_new/head.tga + 3, // head_teeth,models/players/tavion_new/face.tga + 2, // head_twills,models/players/tavion_new/head.tga + -1, // head_feathers,models/players/tavion_new/feathers.tga + -1, // head_eyelashes,models/players/tavion_new/feathers.tga + -1, // head_ahair,models/players/tavion_new/feathers.tga + -1, // head_cap_torso_off,models/players/stormtrooper/caps.tga + 3, // head_face,models/players/tavion_new/face.tga + 3, // head_moutheyes,models/players/tavion_new/face.tga + 4, // r_arm,models/players/tavion_new/arm.tga + 5, // r_hand,models/players/tavion_new/hands.tga + -1, // r_hand_cap_r_arm_off,models/players/stormtrooper/caps.tga + 4, // r_arm_gauntlet,models/players/tavion_new/arm.tga + -1, // r_arm_cap_r_hand_off,models/players/stormtrooper/caps.tga + -1, // r_arm_cap_torso_off,models/players/stormtrooper/caps.tga + 4, // l_arm,models/players/tavion_new/arm.tga + 5, // l_hand,models/players/tavion_new/hands.tga + -1, // l_hand_cap_l_arm_off,models/players/stormtrooper/caps.tga + -1, // l_arm_cap_l_hand_off,models/players/stormtrooper/caps.tga + -1, // l_arm_cap_torso_off,models/players/stormtrooper/caps.tga + -1, // torso_cap_head_off,models/players/stormtrooper/caps.tga + -1, // torso_cap_hips_off,models/players/stormtrooper/caps.tga + -1, // torso_cap_l_arm_off,models/players/stormtrooper/caps.tga + -1, // torso_cap_r_arm_off,models/players/stormtrooper/caps.tga + 0, // r_leg,models/players/tavion_new/legs.tga + -1, // r_leg_cap_hips_off,models/players/stormtrooper/caps.tga + 0, // l_leg,models/players/tavion_new/legs.tga + -1, // l_leg_cap_hips_off,models/players/stormtrooper/caps.tga + -1, // hips_cap_l_leg_off,models/players/stormtrooper/caps.tga + -1, // hips_cap_r_leg_off,models/players/stormtrooper/caps.tga + -1, // hips_cap_torso_off,models/players/stormtrooper/caps.tga diff --git a/model/tavion_new/texture.h b/model/tavion_new/texture.h new file mode 100644 index 0000000..c0caeeb --- /dev/null +++ b/model/tavion_new/texture.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +const struct pk_texture tavion_textures[] = { + #include "texture.inc" +}; diff --git a/model/tavion_new/texture.inc b/model/tavion_new/texture.inc new file mode 100644 index 0000000..5e3eb26 --- /dev/null +++ b/model/tavion_new/texture.inc @@ -0,0 +1,48 @@ +{ + .start = (void *)&_binary_model_tavion_new_legs_vq_start, + .size = (uint32_t)&_binary_model_tavion_new_legs_vq_size, + .offset = 0, + .width = 512, + .height = 512, + .v_mul = 1.0, // 512 +}, +{ + .start = (void *)&_binary_model_tavion_new_torso_vq_start, + .size = (uint32_t)&_binary_model_tavion_new_torso_vq_size, + .offset = 67648, + .width = 512, + .height = 512, + .v_mul = 1.0, // 512 +}, +{ + .start = (void *)&_binary_model_tavion_new_head_vq_start, + .size = (uint32_t)&_binary_model_tavion_new_head_vq_size, + .offset = 135296, + .width = 512, + .height = 512, + .v_mul = 1.0, // 512 +}, +{ + .start = (void *)&_binary_model_tavion_new_face_vq_start, + .size = (uint32_t)&_binary_model_tavion_new_face_vq_size, + .offset = 202944, + .width = 512, + .height = 512, + .v_mul = 1.0, // 512 +}, +{ + .start = (void *)&_binary_model_tavion_new_arm_vq_start, + .size = (uint32_t)&_binary_model_tavion_new_arm_vq_size, + .offset = 270592, + .width = 512, + .height = 512, + .v_mul = 1.0, // 512 +}, +{ + .start = (void *)&_binary_model_tavion_new_hands_vq_start, + .size = (uint32_t)&_binary_model_tavion_new_hands_vq_size, + .offset = 338240, + .width = 256, + .height = 128, + .v_mul = 1.0, // 128 +}, diff --git a/model/tavion_new/texture_gen.sh b/model/tavion_new/texture_gen.sh new file mode 100644 index 0000000..5785aa9 --- /dev/null +++ b/model/tavion_new/texture_gen.sh @@ -0,0 +1 @@ +PYTHONPATH=bsp:regs/gen python model/tavion_new/gen_texture.py model/tavion_new/model_default.skin model/tavion_new/surface.inc model/tavion_new/texture.inc > names.txt diff --git a/model/tavion_new/torso.vq b/model/tavion_new/torso.vq new file mode 100644 index 0000000..d5ac31a Binary files /dev/null and b/model/tavion_new/torso.vq differ diff --git a/model/tavion_new/torso.vq.h b/model/tavion_new/torso.vq.h new file mode 100644 index 0000000..13332c0 --- /dev/null +++ b/model/tavion_new/torso.vq.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_model_tavion_new_torso_vq_start __asm("_binary_model_tavion_new_torso_vq_start"); +extern uint32_t _binary_model_tavion_new_torso_vq_end __asm("_binary_model_tavion_new_torso_vq_end"); +extern uint32_t _binary_model_tavion_new_torso_vq_size __asm("_binary_model_tavion_new_torso_vq_size"); + +#ifdef __cplusplus +} +#endif