model: add tavion

This commit is contained in:
Zack Buhman 2025-04-30 03:17:52 -05:00
parent 0c1da1c858
commit c6f8bfd829
26 changed files with 576 additions and 76 deletions

View File

@ -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 $@

View File

@ -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()

View File

@ -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<uint8_t *>(&_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>() =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
writer.append<ta_global_parameter::end_of_list>() =
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>() =
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>() =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
writer.append<ta_global_parameter::end_of_list>() =
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>() =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
writer.append<ta_global_parameter::end_of_list>() =
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<uint32_t>(out_addr) >> 24) & 0b11100);
sh7091.CCN.QACR1 = ((reinterpret_cast<uint32_t>(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<uint32_t *>(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<void *>(&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<void *>(&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<void *>(&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<void *>(&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<q3bsp_node_t *>(&buf[ne->offset]);
if (0) {
//printf("%d %d\n", draw_tavion_surface, tavion_surface[draw_tavion_surface]);
if (1) {
uint8_t * buf = reinterpret_cast<uint8_t *>(&_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,

View File

@ -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

View File

@ -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]

View File

@ -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;
}
}

BIN
model/tavion_new/arm.vq Normal file

Binary file not shown.

15
model/tavion_new/arm.vq.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#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

BIN
model/tavion_new/face.vq Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#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

17
model/tavion_new/gen.sh Normal file
View File

@ -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

View File

@ -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())

BIN
model/tavion_new/hands.vq Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#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

BIN
model/tavion_new/head.vq Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#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

BIN
model/tavion_new/legs.vq Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#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

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#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

View File

@ -0,0 +1,5 @@
#pragma once
const int tavion_surface[] = {
#include "surface.inc"
};

View File

@ -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

View File

@ -0,0 +1,7 @@
#pragma once
#include <stdint.h>
const struct pk_texture tavion_textures[] = {
#include "texture.inc"
};

View File

@ -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
},

View File

@ -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

BIN
model/tavion_new/torso.vq Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#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