example: add heart

I originally planned to make this a render-to-texture demo, but this
is fairly interesting by itself.
This commit is contained in:
Zack Buhman 2023-12-31 20:19:41 +08:00
parent b6457bf687
commit e8aea009c6
10 changed files with 932 additions and 24 deletions

View File

@ -2,7 +2,7 @@ MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
DIR := $(dir $(MAKEFILE_PATH))
LIB ?= .
OPT ?= -O3
OPT ?= -O2
DEBUG ?= -g -gdwarf-4
GENERATED ?=

View File

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

333
example/heart.cpp Normal file
View File

@ -0,0 +1,333 @@
#include <cstdint>
#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>() =
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>() =
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<volatile texture_memory_alloc *>(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<float>(x);
mt[ix].y = -7.5f + 5.f * static_cast<float>(y);
mt[ix].z = 6.f;
mt[ix].rx = (-8.f + static_cast<float>(ix)) * -pi / 16;
mt[ix].ry = (-8.f + static_cast<float>(ix)) * ix * -pi / 16;
mt[ix].rz = (-8.f + static_cast<float>(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>() = 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;
}
}

View File

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

BIN
geometry/heart.blend Normal file

Binary file not shown.

247
geometry/heart.hpp Normal file
View File

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

234
geometry/heart.obj Normal file
View File

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

View File

@ -1,3 +1,5 @@
#pragma once
#include <cstdint>
#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 {

View File

@ -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 <typename T>
inline constexpr vec<4, T>::vec(const vec<3, T>& v)
: x(v.x), y(v.y), z(v.z), w(1.f)
{}
template <typename T>
constexpr inline vec<4, T> vec<4, T>::operator-() const
{

View File

@ -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,13 +82,35 @@ def parse_face(line):
maybe_int(iix, offset=-1)
for iix in 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:
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)
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
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__':