diff --git a/common.mk b/common.mk index d2b1975..25146ff 100644 --- a/common.mk +++ b/common.mk @@ -2,7 +2,7 @@ MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) DIR := $(dir $(MAKEFILE_PATH)) LIB ?= . -OPT ?= -O3 +OPT ?= -O2 DEBUG ?= -g -gdwarf-4 GENERATED ?= diff --git a/example/example.mk b/example/example.mk index 2b8c7c1..332b821 100644 --- a/example/example.mk +++ b/example/example.mk @@ -152,6 +152,17 @@ MODIFIER_VOLUME_WITH_TWO_VOLUMES_OBJ = \ maple/maple.o \ $(LIBGCC) +HEART_OBJ = \ + example/heart.o \ + vga.o \ + holly/core.o \ + holly/region_array.o \ + holly/background.o \ + holly/ta_fifo_polygon_converter.o + +example/heart.elf: LDSCRIPT = $(LIB)/alt.lds +example/heart.elf: $(START_OBJ) $(HEART_OBJ) + example/modifier_volume_with_two_volumes.elf: LDSCRIPT = $(LIB)/alt.lds example/modifier_volume_with_two_volumes.elf: $(START_OBJ) $(MODIFIER_VOLUME_WITH_TWO_VOLUMES_OBJ) diff --git a/example/heart.cpp b/example/heart.cpp new file mode 100644 index 0000000..22c33e5 --- /dev/null +++ b/example/heart.cpp @@ -0,0 +1,333 @@ +#include + +#include "align.hpp" +#include "vga.hpp" + +#include "holly/texture_memory_alloc.hpp" +#include "holly.hpp" +#include "holly/core.hpp" +#include "holly/core_bits.hpp" +#include "holly/ta_fifo_polygon_converter.hpp" +#include "holly/ta_parameter.hpp" +#include "holly/ta_global_parameter.hpp" +#include "holly/ta_vertex_parameter.hpp" +#include "holly/ta_bits.hpp" +#include "holly/region_array.hpp" +#include "holly/background.hpp" +#include "holly/isp_tsp.hpp" +#include "memorymap.hpp" + +#include "geometry/heart.hpp" +#include "math/vec3.hpp" +#include "math/vec4.hpp" +#include "math/mat4x4.hpp" + +using mat4x4 = mat<4, 4, float>; + +constexpr float pi = 3.141592653589793; + +struct rotation_weights { + float drx; + float dry; + float drz; +}; + +// randomly generated numbers +constexpr rotation_weights weights[16] = { + {-0.8154296875, 0.8583984375, -0.498046875}, + {0.322265625, 0.6796875, 0.3251953125}, + {-0.2626953125, -0.7744140625, 0.37109375}, + {0.5830078125, 0.42578125, 0.5546875}, + {0.9140625, 0.7568359375, -0.037109375}, + {0.8974609375, 0.103515625, -0.2666015625}, + {0.8427734375, -0.4091796875, -0.365234375}, + {0.162109375, -0.603515625, 0.4248046875}, + {-0.47265625, -0.73828125, -0.4912109375}, + {-0.921875, 0.4609375, 0.2216796875}, + {0.400390625, -0.5634765625, -0.3232421875}, + {0.896484375, 0.26953125, -0.951171875}, + {0.541015625, 0.90625, 0.640625}, + {0.5927734375, -0.361328125, 0.21875}, + {-0.9267578125, -0.9423828125, 0.4580078125}, + {0.16796875, 0.3662109375, 0.603515625}, +}; + +// randomly generated numbers +float lighting_weights[16] = { + 0.7314453125, + 0.44921875, + 0.259765625, + 0.3232421875, + 0.1015625, + 0.2529296875, + 0.8662109375, + 0.5439453125, + 0.1337890625, + 0.041015625, + 0.6298828125, + 0.30859375, + 0.517578125, + 0.6259765625, + 0.283203125, + 0.982421875, +}; + +struct model_transform { + float x; + float y; + float z; + float rx; + float ry; + float rz; + + model_transform() + : x(0.f) + , y(0.f) + , z(0.f) + , rx(0.f) + , ry(0.f) + , rz(0.f) + { } +}; + +struct model_transform models[] = { +}; + +inline mat4x4 rotate_x(float t) +{ + return mat4x4(1.f, 0.f, 0.f, 0.f, + 0.f, cos(t), -sin(t), 0.f, + 0.f, sin(t), cos(t), 0.f, + 0.f, 0.f, 0.f, 1.f + ); +} + +inline mat4x4 rotate_y(float t) +{ + return mat4x4( cos(t), 0.f, sin(t), 0.f, + 0.f, 1.f, 0.f, 0.f, + -sin(t), 0.f, cos(t), 0.f, + 0.f, 0.f, 0.f, 1.f + ); +} + +inline mat4x4 rotate_z(float t) +{ + return mat4x4(cos(t), -sin(t), 0.f, 0.f, + sin(t), cos(t), 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f + ); +} + +inline mat4x4 translate(float x, float y, float z) +{ + return mat4x4(1.f, 0.f, 0.f, x, + 0.f, 1.f, 0.f, y, + 0.f, 0.f, 1.f, z, + 0.f, 0.f, 0.f, 1.f + ); +} + +vec3 _transform(const vec4& point) +{ + float x = point.x; + float y = point.y; + float z = point.z; + + // camera transform + z += 4; + + // perspective + x = x / z; + y = y / z; + + // screen space transform + x *= 240.f; + y *= 240.f; + x += 320.f; + y += 240.f; + z = 1 / z; + + return {x, y, z}; +} + +void transform_model(ta_parameter_writer& parameter, + const position__color * vertices, + const vec3 * normals, + const face_vn * faces, + const uint32_t num_faces, + const model_transform& mt, + const float lighting_weight) +{ + 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; + + 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::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::fog_control::no_fog; + + const mat4x4 mat = translate(mt.x, mt.y, mt.z) * rotate_z(mt.rz) * rotate_y(mt.ry) * rotate_x(mt.rx); + + constexpr uint32_t strip_length = 3; + for (uint32_t face_ix = 0; face_ix < num_faces; face_ix++) { + + parameter.append() = + ta_global_parameter::polygon_type_0(parameter_control_word, + isp_tsp_instruction_word, + tsp_instruction_word, + 0, // texture_control_word + 0, // data_size_for_sort_dma + 0 // next_address_for_sort_dma + ); + + auto& face = faces[face_ix]; + for (uint32_t i = 0; i < strip_length; i++) { + // world transform + uint32_t vertex_ix = face[i].vertex; + auto& vertex = vertices[vertex_ix].position; + auto& color = vertices[vertex_ix].color; + auto point = mat * vec4(vertex); + + uint32_t normal_ix = face[i].normal; + auto& normal = normals[normal_ix]; + auto n = mat * vec4(normal); + + vec4 light = {0.f, 0.f, 40.f, 1.f}; + auto l = light - point; + auto n_dot_l = dot(n, l); + vec3 c(0.f, 0.f, 0.f); + c.r += color.r * 0.1; + c.g += color.g * 0.1; + c.b += color.b * 0.1; + if (n_dot_l > 0) { + float intensity = n_dot_l / (length(n) * length(l)); + c.r += color.r * intensity * lighting_weight; + c.g += color.g * intensity * lighting_weight; + c.b += color.b * intensity * lighting_weight; + } + + auto screen = _transform(point); + + bool end_of_strip = i == strip_length - 1; + parameter.append() = + ta_vertex_parameter::polygon_type_1(polygon_vertex_parameter_control_word(end_of_strip), + screen.x, + screen.y, + screen.z, + 1.0f, // alpha + c.r, // red + c.g, // green + c.b // blue + ); + } + } +} + +void init_texture_memory(const struct opb_size& opb_size) +{ + auto mem = reinterpret_cast(texture_memory32); + + background_parameter(mem->background, 0xff220000); + holly.VO_BORDER_COL = 0x00220000; + + region_array2(mem->region_array, + (offsetof (struct texture_memory_alloc, object_list)), + 640 / 32, // width + 480 / 32, // height + opb_size + ); +} + +uint32_t _ta_parameter_buf[((32 * 8192) + 32) / 4]; + +void main() +{ + vga(); + + // The address of `ta_parameter_buf` must be a multiple of 32 bytes. + // This is mandatory for ch2-dma to the ta fifo polygon converter. + uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf); + + constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list + | ta_alloc_ctrl::tm_opb::no_list + | ta_alloc_ctrl::t_opb::no_list + | ta_alloc_ctrl::om_opb::no_list + | ta_alloc_ctrl::o_opb::_16x4byte; + + constexpr struct opb_size opb_size = { .opaque = 16 * 4 + , .opaque_modifier = 0 + , .translucent = 0 + , .translucent_modifier = 0 + , .punch_through = 0 + }; + + holly.SOFTRESET = softreset::pipeline_soft_reset + | softreset::ta_soft_reset; + holly.SOFTRESET = 0; + + core_init(); + init_texture_memory(opb_size); + + uint32_t frame_ix = 0; + constexpr uint32_t num_frames = 1; + + float theta = 0; + + model_transform mt[16] = {}; + for (int x = 0; x < 4; x++) { + for (int y = 0; y < 4; y++) { + int ix = y * 4 + x; + mt[ix].x = -8.f + 5.f * static_cast(x); + mt[ix].y = -7.5f + 5.f * static_cast(y); + mt[ix].z = 6.f; + mt[ix].rx = (-8.f + static_cast(ix)) * -pi / 16; + mt[ix].ry = (-8.f + static_cast(ix)) * ix * -pi / 16; + mt[ix].rz = (-8.f + static_cast(ix)) * ix * -pi / 16; + } + } + + while (true) { + ta_polygon_converter_init(opb_size.total(), + ta_alloc, + 640 / 32, + 480 / 32); + auto parameter = ta_parameter_writer(ta_parameter_buf); + { // plane + for (uint32_t i = 0; i < 16; i++) { + transform_model(parameter, + heart::vertices, + heart::normals, + heart::faces, + heart::num_faces, + mt[i], + (1.f + sin(theta * 2 * lighting_weights[i])) * 0.5f); + + // update model + auto& weight = weights[i]; + mt[i].rx += weight.drx / 50.f; + mt[i].ry += weight.dry / 50.f; + mt[i].rz += weight.drz / 50.f; + } + } + // end of opaque list + parameter.append() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); + + ta_polygon_converter_transfer(ta_parameter_buf, parameter.offset); + ta_wait_opaque_list(); + + core_start_render(frame_ix, num_frames); + + v_sync_in(); + core_wait_end_of_render_video(frame_ix, num_frames); + + constexpr float half_degree = 0.01745329f / 2; + theta += half_degree; + frame_ix += 1; + } +} diff --git a/geometry/geometry.hpp b/geometry/geometry.hpp index cd865a5..25f89da 100644 --- a/geometry/geometry.hpp +++ b/geometry/geometry.hpp @@ -16,4 +16,16 @@ struct vertex__texture__normal { uint16_t normal; }; -using face = vertex__texture__normal[3]; +struct vertex__normal { + uint16_t vertex; + uint16_t normal; +}; + +struct position__color { + vec3 position; + vec3 color; +}; + +using face_vtn = vertex__texture__normal[3]; + +using face_vn = vertex__normal[3]; diff --git a/geometry/heart.blend b/geometry/heart.blend new file mode 100644 index 0000000..f5d2fc3 Binary files /dev/null and b/geometry/heart.blend differ diff --git a/geometry/heart.hpp b/geometry/heart.hpp new file mode 100644 index 0000000..d5f9bc8 --- /dev/null +++ b/geometry/heart.hpp @@ -0,0 +1,247 @@ +#pragma once + +#include "geometry.hpp" + +namespace heart { + constexpr position__color vertices[] = { + { { 0.000000f, 0.400000f, -0.707107f}, { 1.000000f, 0.611800f, 0.211800f} }, + { { 0.144430f, -0.400000f, -0.831470f}, { 1.000000f, 0.000000f, 0.674500f} }, + { { 0.144430f, 0.400000f, -0.831470f}, { 1.000000f, 0.611800f, 0.215700f} }, + { { 0.317317f, -0.400000f, -0.923880f}, { 1.000000f, 0.000000f, 0.670600f} }, + { { 0.317317f, 0.400000f, -0.923880f}, { 1.000000f, 0.611800f, 0.211800f} }, + { { 0.504910f, -0.400000f, -0.980785f}, { 1.000000f, 0.011800f, 0.670600f} }, + { { 0.504910f, 0.400000f, -0.980785f}, { 1.000000f, 0.611800f, 0.211800f} }, + { { 0.700000f, -0.400000f, -1.000000f}, { 1.000000f, 0.000000f, 0.670600f} }, + { { 0.700000f, 0.400000f, -1.000000f}, { 1.000000f, 0.611800f, 0.211800f} }, + { { 0.895090f, -0.400000f, -0.980785f}, { 1.000000f, 0.000000f, 0.898000f} }, + { { 0.895090f, 0.400000f, -0.980785f}, { 1.000000f, 0.235300f, 0.843100f} }, + { { 1.082684f, -0.400000f, -0.923879f}, { 1.000000f, 0.023500f, 0.909800f} }, + { { 1.082684f, 0.400000f, -0.923879f}, { 1.000000f, 0.611800f, 0.211800f} }, + { { 1.255570f, -0.400000f, -0.831469f}, { 1.000000f, 0.329400f, 0.866600f} }, + { { 1.255570f, 0.400000f, -0.831469f}, { 1.000000f, 0.615700f, 0.219600f} }, + { { 1.407107f, -0.400000f, -0.707107f}, { 1.000000f, 0.282300f, 0.886200f} }, + { { 1.407107f, 0.400000f, -0.707107f}, { 1.000000f, 0.580400f, 0.384300f} }, + { { 1.531470f, -0.400000f, -0.555570f}, { 1.000000f, 0.282300f, 0.886200f} }, + { { 1.531470f, 0.400000f, -0.555570f}, { 1.000000f, 0.051000f, 0.600000f} }, + { { 1.623880f, -0.400000f, -0.382683f}, { 1.000000f, 0.282300f, 0.886200f} }, + { { 1.623880f, 0.400000f, -0.382683f}, { 1.000000f, 0.051000f, 0.603900f} }, + { { 1.680785f, -0.400000f, -0.195090f}, { 1.000000f, 0.615700f, 0.674500f} }, + { { 1.680785f, 0.400000f, -0.195090f}, { 1.000000f, 0.035300f, 0.776400f} }, + { { 1.700000f, -0.400000f, 0.000000f}, { 1.000000f, 0.623600f, 0.666700f} }, + { { 1.700000f, 0.400000f, 0.000000f}, { 0.988200f, 0.003900f, 0.996000f} }, + { { 1.680785f, -0.400000f, 0.195090f}, { 1.000000f, 0.000000f, 0.909800f} }, + { { 1.680785f, 0.400000f, 0.195090f}, { 0.843100f, 0.011800f, 0.956800f} }, + { { 1.623879f, -0.400000f, 0.382684f}, { 1.000000f, 0.011800f, 0.909800f} }, + { { 1.623879f, 0.400000f, 0.382684f}, { 0.611800f, 0.239200f, 0.976400f} }, + { { 1.531470f, -0.400000f, 0.555570f}, { 1.000000f, 0.643200f, 0.619700f} }, + { { 1.531470f, 0.400000f, 0.555570f}, { 0.611800f, 0.231400f, 0.976400f} }, + { { 1.407107f, 0.400000f, 0.707107f}, { 0.572500f, 0.235300f, 0.976400f} }, + { { 0.000000f, -0.400000f, -0.707107f}, { 1.000000f, 0.000000f, 0.670600f} }, + { {-0.000000f, 0.400000f, 2.121320f}, { 0.000000f, 0.807800f, 1.000000f} }, + { {-0.000000f, -0.400000f, 2.121320f}, { 1.000000f, 0.921500f, 0.000000f} }, + { { 1.407107f, -0.400000f, 0.707107f}, { 1.000000f, 0.780400f, 0.415700f} }, + { {-0.144430f, -0.400000f, -0.831470f}, { 0.901900f, 0.439200f, 0.603900f} }, + { {-0.144430f, 0.400000f, -0.831470f}, { 1.000000f, 0.611800f, 0.211800f} }, + { {-0.317317f, -0.400000f, -0.923880f}, { 0.670600f, 0.745100f, 0.603900f} }, + { {-0.317317f, 0.400000f, -0.923880f}, { 1.000000f, 0.607900f, 0.235300f} }, + { {-0.504910f, -0.400000f, -0.980785f}, { 0.235300f, 0.976400f, 0.196100f} }, + { {-0.504910f, 0.400000f, -0.980785f}, { 1.000000f, 0.047100f, 0.913700f} }, + { {-0.700000f, -0.400000f, -1.000000f}, { 0.403900f, 0.917600f, 0.360800f} }, + { {-0.700000f, 0.400000f, -1.000000f}, { 1.000000f, 0.000000f, 0.909800f} }, + { {-0.895090f, -0.400000f, -0.980785f}, { 0.403900f, 0.917600f, 0.360800f} }, + { {-0.895090f, 0.400000f, -0.980785f}, { 1.000000f, 0.000000f, 0.909800f} }, + { {-1.082683f, -0.400000f, -0.923880f}, { 0.262700f, 0.968600f, 0.223500f} }, + { {-1.082683f, 0.400000f, -0.923880f}, { 1.000000f, 0.117600f, 0.956800f} }, + { {-1.255570f, -0.400000f, -0.831470f}, { 0.560800f, 0.831300f, 0.505900f} }, + { {-1.255570f, 0.400000f, -0.831470f}, { 1.000000f, 0.000000f, 0.956800f} }, + { {-1.407107f, -0.400000f, -0.707107f}, { 0.776400f, 0.996000f, 0.090200f} }, + { {-1.407107f, 0.400000f, -0.707107f}, { 1.000000f, 0.117600f, 0.956800f} }, + { {-1.531470f, -0.400000f, -0.555570f}, { 0.878400f, 0.941100f, 0.305900f} }, + { {-1.531470f, 0.400000f, -0.555570f}, { 1.000000f, 0.000000f, 0.956800f} }, + { {-1.623880f, -0.400000f, -0.382683f}, { 0.882300f, 0.933300f, 0.325500f} }, + { {-1.623880f, 0.400000f, -0.382683f}, { 0.984300f, 1.000000f, 0.019600f} }, + { {-1.680785f, -0.400000f, -0.195090f}, { 0.745100f, 0.878400f, 0.458900f} }, + { {-1.680785f, 0.400000f, -0.195090f}, { 0.698000f, 0.741200f, 0.639300f} }, + { {-1.700000f, -0.400000f, -0.000000f}, { 0.219600f, 0.768600f, 0.639300f} }, + { {-1.700000f, 0.400000f, -0.000000f}, { 0.254900f, 1.000000f, 0.003900f} }, + { {-1.680785f, -0.400000f, 0.195090f}, { 0.051000f, 0.203900f, 0.980400f} }, + { {-1.680785f, 0.400000f, 0.195090f}, { 0.251000f, 1.000000f, 0.003900f} }, + { {-1.623879f, -0.400000f, 0.382683f}, { 0.054900f, 0.223500f, 0.976400f} }, + { {-1.623879f, 0.400000f, 0.382683f}, { 0.251000f, 1.000000f, 0.003900f} }, + { {-1.531470f, -0.400000f, 0.555570f}, { 0.098000f, 0.423500f, 0.901900f} }, + { {-1.531470f, 0.400000f, 0.555570f}, { 0.251000f, 1.000000f, 0.003900f} }, + { {-1.407107f, 0.400000f, 0.707107f}, { 0.254900f, 1.000000f, 0.007800f} }, + { {-1.407107f, -0.400000f, 0.707107f}, { 0.105900f, 0.203900f, 0.980400f} }, + }; + + constexpr vec3 normals[] = { + { -0.652500f, -0.000000f, -0.757800f }, + { -0.471400f, -0.000000f, -0.881900f }, + { -0.290300f, -0.000000f, -0.956900f }, + { -0.098000f, -0.000000f, -0.995200f }, + { 0.098000f, -0.000000f, -0.995200f }, + { 0.290300f, -0.000000f, -0.956900f }, + { 0.471400f, -0.000000f, -0.881900f }, + { 0.634400f, -0.000000f, -0.773000f }, + { 0.773000f, -0.000000f, -0.634400f }, + { 0.881900f, -0.000000f, -0.471400f }, + { 0.956900f, -0.000000f, -0.290300f }, + { 0.995200f, -0.000000f, -0.098000f }, + { 0.995200f, -0.000000f, 0.098000f }, + { 0.956900f, -0.000000f, 0.290300f }, + { 0.881900f, -0.000000f, 0.471400f }, + { 0.773000f, -0.000000f, 0.634400f }, + { -0.000000f, 1.000000f, -0.000000f }, + { -0.000000f, -1.000000f, -0.000000f }, + { 0.708900f, -0.000000f, 0.705300f }, + { 0.652500f, -0.000000f, -0.757800f }, + { -0.634400f, -0.000000f, -0.773000f }, + { -0.773000f, -0.000000f, -0.634400f }, + { -0.881900f, -0.000000f, -0.471400f }, + { -0.956900f, -0.000000f, -0.290300f }, + { -0.995200f, -0.000000f, -0.098000f }, + { -0.995200f, -0.000000f, 0.098000f }, + { -0.956900f, -0.000000f, 0.290300f }, + { -0.881900f, -0.000000f, 0.471400f }, + { -0.773000f, -0.000000f, 0.634400f }, + { -0.708900f, -0.000000f, 0.705300f }, + }; + + constexpr face_vn faces[] = { + {{ 0, 0}, { 1, 0}, {32, 0}}, + {{ 2, 1}, { 3, 1}, { 1, 1}}, + {{ 4, 2}, { 5, 2}, { 3, 2}}, + {{ 6, 3}, { 7, 3}, { 5, 3}}, + {{ 8, 4}, { 9, 4}, { 7, 4}}, + {{10, 5}, {11, 5}, { 9, 5}}, + {{12, 6}, {13, 6}, {11, 6}}, + {{14, 7}, {15, 7}, {13, 7}}, + {{16, 8}, {17, 8}, {15, 8}}, + {{18, 9}, {19, 9}, {17, 9}}, + {{20, 10}, {21, 10}, {19, 10}}, + {{22, 11}, {23, 11}, {21, 11}}, + {{24, 12}, {25, 12}, {23, 12}}, + {{26, 13}, {27, 13}, {25, 13}}, + {{28, 14}, {29, 14}, {27, 14}}, + {{30, 15}, {35, 15}, {29, 15}}, + {{ 0, 16}, {18, 16}, {10, 16}}, + {{ 1, 17}, {17, 17}, {25, 17}}, + {{31, 18}, {34, 18}, {35, 18}}, + {{35, 17}, {34, 17}, {32, 17}}, + {{33, 16}, {31, 16}, { 0, 16}}, + {{36, 19}, { 0, 19}, {32, 19}}, + {{38, 6}, {37, 6}, {36, 6}}, + {{40, 5}, {39, 5}, {38, 5}}, + {{42, 4}, {41, 4}, {40, 4}}, + {{44, 3}, {43, 3}, {42, 3}}, + {{46, 2}, {45, 2}, {44, 2}}, + {{48, 1}, {47, 1}, {46, 1}}, + {{50, 20}, {49, 20}, {48, 20}}, + {{52, 21}, {51, 21}, {50, 21}}, + {{54, 22}, {53, 22}, {52, 22}}, + {{56, 23}, {55, 23}, {54, 23}}, + {{58, 24}, {57, 24}, {56, 24}}, + {{60, 25}, {59, 25}, {58, 25}}, + {{62, 26}, {61, 26}, {60, 26}}, + {{64, 27}, {63, 27}, {62, 27}}, + {{67, 28}, {65, 28}, {64, 28}}, + {{39, 16}, {55, 16}, {63, 16}}, + {{67, 17}, {50, 17}, {42, 17}}, + {{34, 29}, {66, 29}, {67, 29}}, + {{67, 17}, {32, 17}, {34, 17}}, + {{33, 16}, { 0, 16}, {66, 16}}, + {{ 0, 0}, { 2, 0}, { 1, 0}}, + {{ 2, 1}, { 4, 1}, { 3, 1}}, + {{ 4, 2}, { 6, 2}, { 5, 2}}, + {{ 6, 3}, { 8, 3}, { 7, 3}}, + {{ 8, 4}, {10, 4}, { 9, 4}}, + {{10, 5}, {12, 5}, {11, 5}}, + {{12, 6}, {14, 6}, {13, 6}}, + {{14, 7}, {16, 7}, {15, 7}}, + {{16, 8}, {18, 8}, {17, 8}}, + {{18, 9}, {20, 9}, {19, 9}}, + {{20, 10}, {22, 10}, {21, 10}}, + {{22, 11}, {24, 11}, {23, 11}}, + {{24, 12}, {26, 12}, {25, 12}}, + {{26, 13}, {28, 13}, {27, 13}}, + {{28, 14}, {30, 14}, {29, 14}}, + {{30, 15}, {31, 15}, {35, 15}}, + {{ 4, 16}, { 2, 16}, { 0, 16}}, + {{ 0, 16}, {31, 16}, {30, 16}}, + {{30, 16}, {28, 16}, {26, 16}}, + {{26, 16}, {24, 16}, {22, 16}}, + {{22, 16}, {20, 16}, {18, 16}}, + {{18, 16}, {16, 16}, {14, 16}}, + {{14, 16}, {12, 16}, {10, 16}}, + {{10, 16}, { 8, 16}, { 6, 16}}, + {{ 6, 16}, { 4, 16}, { 0, 16}}, + {{ 0, 16}, {30, 16}, {26, 16}}, + {{26, 16}, {22, 16}, {18, 16}}, + {{18, 16}, {14, 16}, {10, 16}}, + {{10, 16}, { 6, 16}, { 0, 16}}, + {{ 0, 16}, {26, 16}, {18, 16}}, + {{35, 17}, {32, 17}, { 1, 17}}, + {{ 1, 17}, { 3, 17}, { 5, 17}}, + {{ 5, 17}, { 7, 17}, { 9, 17}}, + {{ 9, 17}, {11, 17}, {13, 17}}, + {{13, 17}, {15, 17}, {17, 17}}, + {{17, 17}, {19, 17}, {21, 17}}, + {{21, 17}, {23, 17}, {25, 17}}, + {{25, 17}, {27, 17}, {29, 17}}, + {{29, 17}, {35, 17}, { 1, 17}}, + {{ 1, 17}, { 5, 17}, { 9, 17}}, + {{ 9, 17}, {13, 17}, {17, 17}}, + {{17, 17}, {21, 17}, {25, 17}}, + {{25, 17}, {29, 17}, { 1, 17}}, + {{ 1, 17}, { 9, 17}, {17, 17}}, + {{31, 18}, {33, 18}, {34, 18}}, + {{36, 19}, {37, 19}, { 0, 19}}, + {{38, 6}, {39, 6}, {37, 6}}, + {{40, 5}, {41, 5}, {39, 5}}, + {{42, 4}, {43, 4}, {41, 4}}, + {{44, 3}, {45, 3}, {43, 3}}, + {{46, 2}, {47, 2}, {45, 2}}, + {{48, 1}, {49, 1}, {47, 1}}, + {{50, 20}, {51, 20}, {49, 20}}, + {{52, 21}, {53, 21}, {51, 21}}, + {{54, 22}, {55, 22}, {53, 22}}, + {{56, 23}, {57, 23}, {55, 23}}, + {{58, 24}, {59, 24}, {57, 24}}, + {{60, 25}, {61, 25}, {59, 25}}, + {{62, 26}, {63, 26}, {61, 26}}, + {{64, 27}, {65, 27}, {63, 27}}, + {{67, 28}, {66, 28}, {65, 28}}, + {{ 0, 16}, {37, 16}, {39, 16}}, + {{39, 16}, {41, 16}, {43, 16}}, + {{43, 16}, {45, 16}, {47, 16}}, + {{47, 16}, {49, 16}, {51, 16}}, + {{51, 16}, {53, 16}, {55, 16}}, + {{55, 16}, {57, 16}, {59, 16}}, + {{59, 16}, {61, 16}, {63, 16}}, + {{63, 16}, {65, 16}, {66, 16}}, + {{66, 16}, { 0, 16}, {39, 16}}, + {{39, 16}, {43, 16}, {47, 16}}, + {{47, 16}, {51, 16}, {55, 16}}, + {{55, 16}, {59, 16}, {63, 16}}, + {{63, 16}, {66, 16}, {39, 16}}, + {{39, 16}, {47, 16}, {55, 16}}, + {{36, 17}, {32, 17}, {67, 17}}, + {{67, 17}, {64, 17}, {62, 17}}, + {{62, 17}, {60, 17}, {58, 17}}, + {{58, 17}, {56, 17}, {54, 17}}, + {{54, 17}, {52, 17}, {50, 17}}, + {{50, 17}, {48, 17}, {46, 17}}, + {{46, 17}, {44, 17}, {42, 17}}, + {{42, 17}, {40, 17}, {38, 17}}, + {{38, 17}, {36, 17}, {67, 17}}, + {{67, 17}, {62, 17}, {58, 17}}, + {{58, 17}, {54, 17}, {50, 17}}, + {{50, 17}, {46, 17}, {42, 17}}, + {{42, 17}, {38, 17}, {67, 17}}, + {{67, 17}, {58, 17}, {50, 17}}, + {{34, 29}, {33, 29}, {66, 29}}, + }; + + constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face_vn)); + +} diff --git a/geometry/heart.obj b/geometry/heart.obj new file mode 100644 index 0000000..6dbc837 --- /dev/null +++ b/geometry/heart.obj @@ -0,0 +1,234 @@ +# Blender 3.3.6 +# www.blender.org +o Heart +v 0.000000 0.400000 -0.707107 1.0000 0.6118 0.2118 +v 0.144430 -0.400000 -0.831470 1.0000 0.0000 0.6745 +v 0.144430 0.400000 -0.831470 1.0000 0.6118 0.2157 +v 0.317317 -0.400000 -0.923880 1.0000 0.0000 0.6706 +v 0.317317 0.400000 -0.923880 1.0000 0.6118 0.2118 +v 0.504910 -0.400000 -0.980785 1.0000 0.0118 0.6706 +v 0.504910 0.400000 -0.980785 1.0000 0.6118 0.2118 +v 0.700000 -0.400000 -1.000000 1.0000 0.0000 0.6706 +v 0.700000 0.400000 -1.000000 1.0000 0.6118 0.2118 +v 0.895090 -0.400000 -0.980785 1.0000 0.0000 0.8980 +v 0.895090 0.400000 -0.980785 1.0000 0.2353 0.8431 +v 1.082684 -0.400000 -0.923879 1.0000 0.0235 0.9098 +v 1.082684 0.400000 -0.923879 1.0000 0.6118 0.2118 +v 1.255570 -0.400000 -0.831469 1.0000 0.3294 0.8666 +v 1.255570 0.400000 -0.831469 1.0000 0.6157 0.2196 +v 1.407107 -0.400000 -0.707107 1.0000 0.2823 0.8862 +v 1.407107 0.400000 -0.707107 1.0000 0.5804 0.3843 +v 1.531470 -0.400000 -0.555570 1.0000 0.2823 0.8862 +v 1.531470 0.400000 -0.555570 1.0000 0.0510 0.6000 +v 1.623880 -0.400000 -0.382683 1.0000 0.2823 0.8862 +v 1.623880 0.400000 -0.382683 1.0000 0.0510 0.6039 +v 1.680785 -0.400000 -0.195090 1.0000 0.6157 0.6745 +v 1.680785 0.400000 -0.195090 1.0000 0.0353 0.7764 +v 1.700000 -0.400000 0.000000 1.0000 0.6236 0.6667 +v 1.700000 0.400000 0.000000 0.9882 0.0039 0.9960 +v 1.680785 -0.400000 0.195090 1.0000 0.0000 0.9098 +v 1.680785 0.400000 0.195090 0.8431 0.0118 0.9568 +v 1.623879 -0.400000 0.382684 1.0000 0.0118 0.9098 +v 1.623879 0.400000 0.382684 0.6118 0.2392 0.9764 +v 1.531470 -0.400000 0.555570 1.0000 0.6432 0.6197 +v 1.531470 0.400000 0.555570 0.6118 0.2314 0.9764 +v 1.407107 0.400000 0.707107 0.5725 0.2353 0.9764 +v 0.000000 -0.400000 -0.707107 1.0000 0.0000 0.6706 +v -0.000000 0.400000 2.121320 0.0000 0.8078 1.0000 +v -0.000000 -0.400000 2.121320 1.0000 0.9215 0.0000 +v 1.407107 -0.400000 0.707107 1.0000 0.7804 0.4157 +v -0.144430 -0.400000 -0.831470 0.9019 0.4392 0.6039 +v -0.144430 0.400000 -0.831470 1.0000 0.6118 0.2118 +v -0.317317 -0.400000 -0.923880 0.6706 0.7451 0.6039 +v -0.317317 0.400000 -0.923880 1.0000 0.6079 0.2353 +v -0.504910 -0.400000 -0.980785 0.2353 0.9764 0.1961 +v -0.504910 0.400000 -0.980785 1.0000 0.0471 0.9137 +v -0.700000 -0.400000 -1.000000 0.4039 0.9176 0.3608 +v -0.700000 0.400000 -1.000000 1.0000 0.0000 0.9098 +v -0.895090 -0.400000 -0.980785 0.4039 0.9176 0.3608 +v -0.895090 0.400000 -0.980785 1.0000 0.0000 0.9098 +v -1.082683 -0.400000 -0.923880 0.2627 0.9686 0.2235 +v -1.082683 0.400000 -0.923880 1.0000 0.1176 0.9568 +v -1.255570 -0.400000 -0.831470 0.5608 0.8313 0.5059 +v -1.255570 0.400000 -0.831470 1.0000 0.0000 0.9568 +v -1.407107 -0.400000 -0.707107 0.7764 0.9960 0.0902 +v -1.407107 0.400000 -0.707107 1.0000 0.1176 0.9568 +v -1.531470 -0.400000 -0.555570 0.8784 0.9411 0.3059 +v -1.531470 0.400000 -0.555570 1.0000 0.0000 0.9568 +v -1.623880 -0.400000 -0.382683 0.8823 0.9333 0.3255 +v -1.623880 0.400000 -0.382683 0.9843 1.0000 0.0196 +v -1.680785 -0.400000 -0.195090 0.7451 0.8784 0.4589 +v -1.680785 0.400000 -0.195090 0.6980 0.7412 0.6393 +v -1.700000 -0.400000 -0.000000 0.2196 0.7686 0.6393 +v -1.700000 0.400000 -0.000000 0.2549 1.0000 0.0039 +v -1.680785 -0.400000 0.195090 0.0510 0.2039 0.9804 +v -1.680785 0.400000 0.195090 0.2510 1.0000 0.0039 +v -1.623879 -0.400000 0.382683 0.0549 0.2235 0.9764 +v -1.623879 0.400000 0.382683 0.2510 1.0000 0.0039 +v -1.531470 -0.400000 0.555570 0.0980 0.4235 0.9019 +v -1.531470 0.400000 0.555570 0.2510 1.0000 0.0039 +v -1.407107 0.400000 0.707107 0.2549 1.0000 0.0078 +v -1.407107 -0.400000 0.707107 0.1059 0.2039 0.9804 +vn -0.6525 -0.0000 -0.7578 +vn -0.4714 -0.0000 -0.8819 +vn -0.2903 -0.0000 -0.9569 +vn -0.0980 -0.0000 -0.9952 +vn 0.0980 -0.0000 -0.9952 +vn 0.2903 -0.0000 -0.9569 +vn 0.4714 -0.0000 -0.8819 +vn 0.6344 -0.0000 -0.7730 +vn 0.7730 -0.0000 -0.6344 +vn 0.8819 -0.0000 -0.4714 +vn 0.9569 -0.0000 -0.2903 +vn 0.9952 -0.0000 -0.0980 +vn 0.9952 -0.0000 0.0980 +vn 0.9569 -0.0000 0.2903 +vn 0.8819 -0.0000 0.4714 +vn 0.7730 -0.0000 0.6344 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn 0.7089 -0.0000 0.7053 +vn 0.6525 -0.0000 -0.7578 +vn -0.6344 -0.0000 -0.7730 +vn -0.7730 -0.0000 -0.6344 +vn -0.8819 -0.0000 -0.4714 +vn -0.9569 -0.0000 -0.2903 +vn -0.9952 -0.0000 -0.0980 +vn -0.9952 -0.0000 0.0980 +vn -0.9569 -0.0000 0.2903 +vn -0.8819 -0.0000 0.4714 +vn -0.7730 -0.0000 0.6344 +vn -0.7089 -0.0000 0.7053 +s 0 +f 1//1 2//1 33//1 +f 3//2 4//2 2//2 +f 5//3 6//3 4//3 +f 7//4 8//4 6//4 +f 9//5 10//5 8//5 +f 11//6 12//6 10//6 +f 13//7 14//7 12//7 +f 15//8 16//8 14//8 +f 17//9 18//9 16//9 +f 19//10 20//10 18//10 +f 21//11 22//11 20//11 +f 23//12 24//12 22//12 +f 25//13 26//13 24//13 +f 27//14 28//14 26//14 +f 29//15 30//15 28//15 +f 31//16 36//16 30//16 +f 1//17 19//17 11//17 +f 2//18 18//18 26//18 +f 32//19 35//19 36//19 +f 36//18 35//18 33//18 +f 34//17 32//17 1//17 +f 37//20 1//20 33//20 +f 39//7 38//7 37//7 +f 41//6 40//6 39//6 +f 43//5 42//5 41//5 +f 45//4 44//4 43//4 +f 47//3 46//3 45//3 +f 49//2 48//2 47//2 +f 51//21 50//21 49//21 +f 53//22 52//22 51//22 +f 55//23 54//23 53//23 +f 57//24 56//24 55//24 +f 59//25 58//25 57//25 +f 61//26 60//26 59//26 +f 63//27 62//27 61//27 +f 65//28 64//28 63//28 +f 68//29 66//29 65//29 +f 40//17 56//17 64//17 +f 68//18 51//18 43//18 +f 35//30 67//30 68//30 +f 68//18 33//18 35//18 +f 34//17 1//17 67//17 +f 1//1 3//1 2//1 +f 3//2 5//2 4//2 +f 5//3 7//3 6//3 +f 7//4 9//4 8//4 +f 9//5 11//5 10//5 +f 11//6 13//6 12//6 +f 13//7 15//7 14//7 +f 15//8 17//8 16//8 +f 17//9 19//9 18//9 +f 19//10 21//10 20//10 +f 21//11 23//11 22//11 +f 23//12 25//12 24//12 +f 25//13 27//13 26//13 +f 27//14 29//14 28//14 +f 29//15 31//15 30//15 +f 31//16 32//16 36//16 +f 5//17 3//17 1//17 +f 1//17 32//17 31//17 +f 31//17 29//17 27//17 +f 27//17 25//17 23//17 +f 23//17 21//17 19//17 +f 19//17 17//17 15//17 +f 15//17 13//17 11//17 +f 11//17 9//17 7//17 +f 7//17 5//17 1//17 +f 1//17 31//17 27//17 +f 27//17 23//17 19//17 +f 19//17 15//17 11//17 +f 11//17 7//17 1//17 +f 1//17 27//17 19//17 +f 36//18 33//18 2//18 +f 2//18 4//18 6//18 +f 6//18 8//18 10//18 +f 10//18 12//18 14//18 +f 14//18 16//18 18//18 +f 18//18 20//18 22//18 +f 22//18 24//18 26//18 +f 26//18 28//18 30//18 +f 30//18 36//18 2//18 +f 2//18 6//18 10//18 +f 10//18 14//18 18//18 +f 18//18 22//18 26//18 +f 26//18 30//18 2//18 +f 2//18 10//18 18//18 +f 32//19 34//19 35//19 +f 37//20 38//20 1//20 +f 39//7 40//7 38//7 +f 41//6 42//6 40//6 +f 43//5 44//5 42//5 +f 45//4 46//4 44//4 +f 47//3 48//3 46//3 +f 49//2 50//2 48//2 +f 51//21 52//21 50//21 +f 53//22 54//22 52//22 +f 55//23 56//23 54//23 +f 57//24 58//24 56//24 +f 59//25 60//25 58//25 +f 61//26 62//26 60//26 +f 63//27 64//27 62//27 +f 65//28 66//28 64//28 +f 68//29 67//29 66//29 +f 1//17 38//17 40//17 +f 40//17 42//17 44//17 +f 44//17 46//17 48//17 +f 48//17 50//17 52//17 +f 52//17 54//17 56//17 +f 56//17 58//17 60//17 +f 60//17 62//17 64//17 +f 64//17 66//17 67//17 +f 67//17 1//17 40//17 +f 40//17 44//17 48//17 +f 48//17 52//17 56//17 +f 56//17 60//17 64//17 +f 64//17 67//17 40//17 +f 40//17 48//17 56//17 +f 37//18 33//18 68//18 +f 68//18 65//18 63//18 +f 63//18 61//18 59//18 +f 59//18 57//18 55//18 +f 55//18 53//18 51//18 +f 51//18 49//18 47//18 +f 47//18 45//18 43//18 +f 43//18 41//18 39//18 +f 39//18 37//18 68//18 +f 68//18 63//18 59//18 +f 59//18 55//18 51//18 +f 51//18 47//18 43//18 +f 43//18 39//18 68//18 +f 68//18 59//18 51//18 +f 35//30 34//30 67//30 diff --git a/holly/core_bits.hpp b/holly/core_bits.hpp index d288e96..81bf1a6 100644 --- a/holly/core_bits.hpp +++ b/holly/core_bits.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include "../float_uint32.hpp" @@ -139,7 +141,7 @@ namespace fpu_shad_scale { } namespace fpu_cull_val { - constexpr uint32_t culling_comparison_value(float num) { return _i(__builtin_fabsf(num));; } + inline uint32_t culling_comparison_value(float num) { return _i(__builtin_fabsf(num));; } } namespace fpu_param_cfg { @@ -180,11 +182,11 @@ namespace half_offset { } namespace fpu_perp_val { - constexpr uint32_t perpendicular_triangle_compare(float num) { return _i(__builtin_fabsf(num));; } + inline uint32_t perpendicular_triangle_compare(float num) { return _i(__builtin_fabsf(num));; } } namespace isp_backgnd_d { - constexpr uint32_t background_plane_depth(float num) { return _i(num) & 0xfffffff0; } + inline uint32_t background_plane_depth(float num) { return _i(num) & 0xfffffff0; } } namespace isp_backgnd_t { diff --git a/math/vec4.hpp b/math/vec4.hpp index bbf7813..5b28c27 100644 --- a/math/vec4.hpp +++ b/math/vec4.hpp @@ -18,6 +18,7 @@ struct vec<4, T> inline constexpr vec(); inline constexpr vec(T scalar); inline constexpr vec(T _x, T _y, T _z, T _w); + inline constexpr vec(const vec<3, T>& v); constexpr inline vec<4, T> operator-() const; inline constexpr T const& operator[](int i) const; @@ -41,6 +42,11 @@ inline constexpr vec<4, T>::vec(T _x, T _y, T _z, T _w) : x(_x), y(_y), z(_z), w(_w) {} +template +inline constexpr vec<4, T>::vec(const vec<3, T>& v) + : x(v.x), y(v.y), z(v.z), w(1.f) +{} + template constexpr inline vec<4, T> vec<4, T>::operator-() const { diff --git a/tools/obj_to_cpp.py b/tools/obj_to_cpp.py index 17a7919..4ee6db6 100644 --- a/tools/obj_to_cpp.py +++ b/tools/obj_to_cpp.py @@ -1,6 +1,7 @@ import math from dataclasses import dataclass import sys +from typing import Union from generate import renderer @@ -13,18 +14,30 @@ class Vertex: y: float z: float +@dataclass(frozen=True) +class Color: + r: float + g: float + b: float + @dataclass(frozen=True) class TextureCoordinate: u: float v: float +@dataclass +class VertexNormal: + vertex: int + normal: int + @dataclass class VertexTextureNormal: vertex: int texture: int normal: int -Face = tuple[VertexTextureNormal, VertexTextureNormal, VertexTextureNormal] +Face = Union[tuple[VertexTextureNormal, VertexTextureNormal, VertexTextureNormal], + tuple[VertexNormal, VertexNormal, VertexNormal]] name = None @@ -34,10 +47,17 @@ def parse_object(line): return name.lower() def parse_vertex(line): - h, *xyz = line.split() + h, *xyz_rgb = line.split() assert h == 'v' or h == 'vn' - assert len(xyz) == 3 - return Vertex(*map(float, xyz)) + if h == 'vn': + assert len(xyz_rgb) == 3 + if h == 'v': + assert len(xyz_rgb) == 6 or len(xyz_rgb) == 3 + coords = list(map(float, xyz_rgb)) + if len(xyz_rgb) == 6: + return Vertex(*coords[0:3]), Color(*coords[3:6]) + else: + return Vertex(*coords[0:3]) def parse_texture_coordinate(line): h, *uv = line.split() @@ -47,7 +67,7 @@ def parse_texture_coordinate(line): def maybe_int(i, offset): if i.strip() == "": - assert False + return None else: return int(i) + offset @@ -62,14 +82,36 @@ def parse_face(line): maybe_int(iix, offset=-1) for iix in ix ] - return VertexTextureNormal(vertex_ix, uv_ix, normal_ix) + assert vertex_ix is not None + assert normal_ix is not None + if uv_ix is None: + return VertexNormal(vertex_ix, normal_ix) + else: + return VertexTextureNormal(vertex_ix, uv_ix, normal_ix) return tuple(map(parse_ixs, tri)) +def vertex_type(vertices): + types = set(type(v) for v in vertices) + assert len(types) == 1, types + if type(vertices[0]) is tuple: + return "position__color" + elif type(vertices[0]) is Vertex: + return "vec3" + else: + assert False, type(verticies[0]) + def generate_vertices(vertices): - yield "constexpr vec3 vertices[] = {" - for v in vertices: - yield f"{{ {v.x:9f}f, {v.y:9f}f, {v.z:9f}f }}," + type_str = vertex_type(vertices) + yield f"constexpr {type_str} vertices[] = {{" + for p_c in vertices: + if type(p_c) is tuple: + p, c = p_c + yield f"{{ {{{p.x:9f}f, {p.y:9f}f, {p.z:9f}f}}, {{{c.r:9f}f, {c.g:9f}f, {c.b:9f}f}} }}," + else: + assert type(p_c) is Vertex + p = p_c + yield f"{{ {v.x:9f}f, {v.y:9f}f, {v.z:9f}f }}," yield "};" yield "" @@ -87,26 +129,42 @@ def generate_texture_coordinates(texture_coordinates): yield "};" yield "" -def generate_faces(faces): +def face_type_str(face_type): + if face_type is VertexNormal: + return "face_vn" + elif face_type is VertexTextureNormal: + return "face_vtn" + else: + assert False, face_type + +def generate_faces(faces, face_type): + def face_coords(vtn): + if face_type is VertexNormal: + return [vtn.vertex, vtn.normal] + elif face_type is VertexTextureNormal: + return [vtn.vertex, vtn.texture, vtn.normal] + else: + assert False, face_type max_ix = max( i for f in faces for vtn in f - for i in [vtn.vertex, vtn.texture, vtn.normal] + for i in face_coords(vtn) ) align = 1 + math.floor(math.log(max_ix) / math.log(10)) - yield "constexpr face faces[] = {" + type_str = face_type_str(face_type) + yield f"constexpr {type_str} faces[] = {{" def align_vtn(vtn): - return ", ".join(str(ix).rjust(align) for ix in [vtn.vertex, vtn.texture, vtn.normal]) + return ", ".join(str(ix).rjust(align) for ix in face_coords(vtn)) for f in faces: inner = ", ".join(f"{{{align_vtn(vtn)}}}" for vtn in f) yield f"{{{inner}}}," yield "};" yield "" - yield "constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof (face));" + yield f"constexpr uint32_t num_faces = (sizeof (faces)) / (sizeof ({type_str}));" yield "" -def generate_namespace(vertices, texture_coordinates, normals, faces): +def generate_namespace(vertices, texture_coordinates, normals, faces, face_type): global name assert name is not None yield "#pragma once" @@ -116,9 +174,10 @@ def generate_namespace(vertices, texture_coordinates, normals, faces): yield f"namespace {name} {{" yield from generate_vertices(vertices) - yield from generate_texture_coordinates(texture_coordinates) + if texture_coordinates != []: + yield from generate_texture_coordinates(texture_coordinates) yield from generate_normals(normals) - yield from generate_faces(faces) + yield from generate_faces(faces, face_type) yield "}" @@ -163,10 +222,14 @@ def main(): else: pass - texture_coordinates, faces = merge_texture_coordinates(texture_coordinates, faces) + face_types = set(type(vtn) for f in faces for vtn in f) + assert len(face_types) == 1, face_types + face_type = next(iter(face_types)) + if face_type is VertexTextureNormal: + texture_coordinates, faces = merge_texture_coordinates(texture_coordinates, faces) render, out = renderer() - render(generate_namespace(vertices, texture_coordinates, normals, faces)) + render(generate_namespace(vertices, texture_coordinates, normals, faces, face_type)) sys.stdout.write(out.getvalue()) if __name__ == '__main__':