From 1f5d52fb9ad7d466dac5c351be3a3701520fe788 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 1 Sep 2017 02:28:47 -0700 Subject: [PATCH] implemented vertex shader inputs --- src/demo/demo.cpp | 362 ++- src/pipeline/pipeline.cpp | 14 +- src/pipeline/pipeline.h | 12 +- src/spirv_to_llvm/core_instructions.cpp | 19 +- src/spirv_to_llvm/spirv_to_llvm.cpp | 81 +- src/spirv_to_llvm/spirv_to_llvm.h | 4 +- .../spirv_to_llvm_implementation.h | 141 +- src/spirv_to_llvm/vertex_entry_point.cpp | 479 ++-- test-files/demo-text.obj | 2214 +++++++++++++++++ test-files/tri.vert | 645 +---- test-files/tri.vert.spv | Bin 15956 -> 576 bytes 11 files changed, 3081 insertions(+), 890 deletions(-) create mode 100644 test-files/demo-text.obj diff --git a/src/demo/demo.cpp b/src/demo/demo.cpp index 797309f..8db8ea6 100644 --- a/src/demo/demo.cpp +++ b/src/demo/demo.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "spirv/spirv.h" #include "spirv/parser.h" @@ -242,7 +243,9 @@ pipeline::Pipeline_layout_handle make_pipeline_layout() } template -util::optional parse_unsigned_integer(util::string_view str, Integer_type max_value = std::numeric_limits::max()) noexcept +util::optional parse_unsigned_integer( + util::string_view str, + Integer_type max_value = std::numeric_limits::max()) noexcept { static_assert(std::is_unsigned::value, ""); if(str.empty()) @@ -261,6 +264,313 @@ util::optional parse_unsigned_integer(util::string_view str, Integ return retval; } +template +util::optional parse_signed_integer( + util::string_view str, + Integer_type max_value = std::numeric_limits::max(), + Integer_type min_value = std::numeric_limits::min()) noexcept +{ + assert(max_value >= min_value); + static_assert(std::is_signed::value, ""); + typedef typename std::make_unsigned::type Unsigned_type; + bool is_negative = false; + if(str.empty()) + return {}; + if(str.front() == '+') + { + str.remove_prefix(1); + } + else if(str.front() == '-') + { + is_negative = true; + str.remove_prefix(1); + } + if(str.empty()) + return {}; + Unsigned_type unsigned_max; + if(is_negative) + { + if(min_value > 0) + return {}; + unsigned_max = -static_cast(min_value); + } + else + { + if(max_value < 0) + return {}; + unsigned_max = static_cast(max_value); + } + auto unsigned_retval = parse_unsigned_integer(str, unsigned_max); + if(!unsigned_retval) + return {}; + Integer_type retval; + if(is_negative) + { + retval = static_cast(-*unsigned_retval); + if(retval > max_value) + return {}; + } + else + { + retval = static_cast(*unsigned_retval); + if(retval < min_value) + return {}; + } + return retval; +} + +struct Vertex_input_struct +{ + struct alignas(4 * alignof(float)) Vec4 + { + float x, y, z, w; + static constexpr VkFormat format = VK_FORMAT_R32G32B32A32_SFLOAT; + }; + Vec4 position; + static constexpr VkFormat position_format = decltype(position)::format; + static constexpr std::size_t position_location = 0; // must match tri.vert + constexpr Vertex_input_struct() noexcept : position{} + { + } + constexpr explicit Vertex_input_struct(const Vec4 &position) noexcept : position(position) + { + } +}; + +struct Wavefront_obj_parse_error : public std::runtime_error +{ + const char *filename; + std::size_t line_number; + static std::string make_what(const char *filename, + std::size_t line_number, + util::string_view message) + { + std::ostringstream ss; + ss << filename << ":" << line_number << ": error: " << message; + return ss.str(); + } + Wavefront_obj_parse_error(const char *filename, + std::size_t line_number, + util::string_view message) + : runtime_error(make_what(filename, line_number, message)), + filename(filename), + line_number(line_number) + { + } +}; + +std::vector load_wavefront_obj_file(const char *filename) +{ + std::vector retval; + std::ifstream is(filename); + if(!is) + throw Wavefront_obj_parse_error(filename, 0, "failed to open file"); + std::size_t line_number = 0; + struct Vertex + { + float x = 0, y = 0, z = 0; + }; + std::vector vertexes; + struct Texture_vertex + { + float u = 0, v = 0; + }; + std::vector texture_vertexes; + struct Normal_vertex + { + float x = 0, y = 0, z = 0; + }; + std::vector normal_vertexes; + while(is) + { + line_number++; + std::string line_str; + std::getline(is, line_str); + for(char &ch : line_str) + { + // replace all white space with a space character + if(std::isspace(static_cast(ch))) + ch = ' '; + } + util::string_view line(line_str); + // skip leading whitespace + while(!line.empty() && line.front() == ' ') + line.remove_prefix(1); + // skip trailing whitespace + while(!line.empty() && line.back() == ' ') + line.remove_suffix(1); + // skip blank lines and comments + if(line.empty() || line.front() == '#') + continue; + auto command = line.substr(0, line.find_first_of(' ')); + line.remove_prefix(command.size()); + // skip leading whitespace + while(!line.empty() && line.front() == ' ') + line.remove_prefix(1); + if(command == "v") // vertex + { + std::istringstream is; + is.str(std::string(line)); + float x = 0, y = 0, z = 0; + is >> x >> y >> z; + if(!is || is.peek() != std::char_traits::eof()) + throw Wavefront_obj_parse_error( + filename, line_number, "parsing vertex command failed"); + vertexes.push_back({ + .x = x, .y = y, .z = z, + }); + } + else if(command == "vn") // vertex normal + { + std::istringstream is; + is.str(std::string(line)); + float x = 0, y = 0, z = 0; + is >> x >> y >> z; + if(!is || is.peek() != std::char_traits::eof()) + throw Wavefront_obj_parse_error( + filename, line_number, "parsing vertex normal command failed"); + normal_vertexes.push_back({ + .x = x, .y = y, .z = z, + }); + } + else if(command == "vt") // vertex texture + { + std::istringstream is; + is.str(std::string(line)); + float u = 0, v = 0; + is >> u >> v; + if(!is || is.peek() != std::char_traits::eof()) + throw Wavefront_obj_parse_error( + filename, line_number, "parsing vertex texture command failed"); + texture_vertexes.push_back({ + .u = u, .v = v, + }); + } + else if(command == "s" && line == "off") + { + // smoothing groups are not implemented, so turning smoothing off has no effect + } + else if(command == "f") + { + struct Face_vertex + { + Vertex vertex; + util::optional texture_vertex; + util::optional normal_vertex; + }; + std::vector face_vertexes; + while(!line.empty()) + { + auto vertex_str = line.substr(0, line.find_first_of(' ')); + line.remove_prefix(vertex_str.size()); + // skip leading whitespace + while(!line.empty() && line.front() == ' ') + line.remove_prefix(1); + assert(!vertex_str.empty()); + auto vertex_index_str = vertex_str.substr(0, vertex_str.find_first_of('/')); + vertex_str.remove_prefix(vertex_index_str.size()); + util::string_view vertex_texture_index_str; + util::string_view vertex_normal_index_str; + if(!vertex_str.empty()) + { + vertex_str.remove_prefix(1); // remove slash + vertex_texture_index_str = vertex_str.substr(0, vertex_str.find_first_of('/')); + vertex_str.remove_prefix(vertex_texture_index_str.size()); + if(!vertex_str.empty()) + { + vertex_str.remove_prefix(1); // remove slash + vertex_normal_index_str = vertex_str; + } + } + auto parse_vertex_index = [filename, line_number]( + auto &vertexes, + util::string_view vertex_index_str, + const char *vertex_index_name) + { + std::size_t vertex_count = vertexes.size(); + std::int64_t max_index = vertex_count; + std::int64_t min_index = -vertex_count; + auto vertex_index = + parse_signed_integer(vertex_index_str, max_index, min_index); + if(!vertex_index || *vertex_index == 0) + throw Wavefront_obj_parse_error(filename, + line_number, + std::string("invalid ") + vertex_index_name + + ": " + + std::string(vertex_index_str)); + if(*vertex_index < 0) + *vertex_index += vertex_count; + else + (*vertex_index)--; + assert(*vertex_index >= 0 && *vertex_index < vertex_count); + return vertexes[*vertex_index]; + }; + auto vertex = parse_vertex_index(vertexes, vertex_index_str, "vertex index"); + util::optional texture_vertex; + if(!vertex_texture_index_str.empty()) + texture_vertex = parse_vertex_index( + texture_vertexes, vertex_texture_index_str, "vertex texture index"); + util::optional normal_vertex; + if(!vertex_normal_index_str.empty()) + normal_vertex = parse_vertex_index( + normal_vertexes, vertex_normal_index_str, "vertex normal index"); + face_vertexes.push_back({ + .vertex = vertex, + .texture_vertex = texture_vertex, + .normal_vertex = normal_vertex, + }); + } + if(face_vertexes.size() < 3) + throw Wavefront_obj_parse_error( + filename, line_number, "faces must have at least 3 vertexes"); + std::vector transformed_vertexes; + transformed_vertexes.reserve(face_vertexes.size()); + for(auto &face_vertex : face_vertexes) + { + // convert from obj coordinate system to OpenGL coordinate system + float global_x = face_vertex.vertex.x; + float global_y = -face_vertex.vertex.z; + float global_z = face_vertex.vertex.y; + // camera transformation + float camera_x = global_x; + float camera_y = global_y; + float camera_z = global_z - 1; + // perspective project + constexpr float far_plane = 10; + constexpr float factor = 1 / far_plane; + float projected_x = factor * camera_x; + float projected_y = -factor * camera_y; + float projected_z = -factor * camera_z; + float projected_w = -factor * camera_z; + // fix aspect ratio + constexpr float x_aspect_ratio_correction = 3.0 / 4; + constexpr float y_aspect_ratio_correction = 1; + float final_x = projected_x * x_aspect_ratio_correction; + float final_y = projected_y * y_aspect_ratio_correction; + float final_z = projected_z; + float final_w = projected_w; + transformed_vertexes.push_back(Vertex_input_struct({ + .x = final_x, .y = final_y, .z = final_z, .w = final_w, + })); + } + // triangulate face + for(std::size_t leading_vertex_index = 2, trailing_vertex_index = 1; + leading_vertex_index < transformed_vertexes.size(); + leading_vertex_index++, trailing_vertex_index++) + { + retval.push_back(transformed_vertexes[0]); + retval.push_back(transformed_vertexes[trailing_vertex_index]); + retval.push_back(transformed_vertexes[leading_vertex_index]); + } + } +#warning finish implementing load_wavefront_obj_file + else + throw Wavefront_obj_parse_error( + filename, line_number, "unimplemented command: " + std::string(command)); + } + return retval; +} + int test_main(int argc, char **argv) { if(SDL_Init(0) < 0) @@ -277,28 +587,23 @@ int test_main(int argc, char **argv) } shutdown_sdl; const char *vertex_shader_filename = "test-files/tri.vert.spv"; const char *fragment_shader_filename = "test-files/tri.frag.spv"; - const char *vertex_count_str = "633"; + const char *vertexes_filename = "test-files/demo-text.obj"; if(argc > 1) { if(argc != 4 || argv[1][0] == '-' || argv[2][0] == '-' || argv[3][0] == '-') { - std::cerr << "usage: demo [ ]\n"; + std::cerr << "usage: demo [ ]\n"; return 1; } vertex_shader_filename = argv[1]; fragment_shader_filename = argv[2]; - vertex_count_str = argv[3]; + vertexes_filename = argv[3]; } try { - auto vertex_count = parse_unsigned_integer(vertex_count_str); - if(!vertex_count) - throw std::runtime_error("invalid value for vertex count, must be a decimal integer"); - constexpr auto max_vertex_count = 50000000; - if(*vertex_count > max_vertex_count) - throw std::runtime_error("vertex count is too large"); auto vertex_shader = load_shader(vertex_shader_filename); auto fragment_shader = load_shader(fragment_shader_filename); + auto vertexes = load_wavefront_obj_file(vertexes_filename); auto pipeline_layout = make_pipeline_layout(); constexpr std::size_t main_color_attachment_index = 0; constexpr std::size_t attachment_count = main_color_attachment_index + 1; @@ -370,14 +675,35 @@ int test_main(int argc, char **argv) .pName = "main", .pSpecializationInfo = nullptr, }; + constexpr std::size_t vertex_input_buffer_binding_index = 0; + constexpr std::size_t binding_count = vertex_input_buffer_binding_index + 1; + constexpr std::size_t vertex_input_binding_description_count = 1; + VkVertexInputBindingDescription + vertex_input_binding_descriptions[vertex_input_binding_description_count] = { + { + .binding = vertex_input_buffer_binding_index, + .stride = sizeof(Vertex_input_struct), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }, + }; + constexpr std::size_t vertex_input_attribute_description_count = 1; + VkVertexInputAttributeDescription + vertex_input_attribute_descriptions[vertex_input_attribute_description_count] = { + { + .location = Vertex_input_struct::position_location, + .binding = vertex_input_buffer_binding_index, + .format = Vertex_input_struct::position_format, + .offset = offsetof(Vertex_input_struct, position), + }, + }; VkPipelineVertexInputStateCreateInfo pipeline_vertex_input_state_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pNext = nullptr, .flags = 0, - .vertexBindingDescriptionCount = 0, - .pVertexBindingDescriptions = nullptr, - .vertexAttributeDescriptionCount = 0, - .pVertexAttributeDescriptions = nullptr, + .vertexBindingDescriptionCount = vertex_input_binding_description_count, + .pVertexBindingDescriptions = vertex_input_binding_descriptions, + .vertexAttributeDescriptionCount = vertex_input_attribute_description_count, + .pVertexAttributeDescriptions = vertex_input_attribute_descriptions, }; VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, @@ -528,9 +854,13 @@ int test_main(int argc, char **argv) clear_color.float32[3] = 1; color_attachment.clear(clear_color); constexpr std::uint32_t vertex_start_index = 0; - std::uint32_t vertex_end_index = *vertex_count; + std::uint32_t vertex_end_index = vertexes.size(); constexpr std::uint32_t instance_id = 0; - graphics_pipeline->run(vertex_start_index, vertex_end_index, instance_id, color_attachment); + void *bindings[binding_count] = { + vertexes.data(), + }; + graphics_pipeline->run( + vertex_start_index, vertex_end_index, instance_id, color_attachment, bindings); typedef std::uint32_t Pixel_type; // check Pixel_type static_assert(std::is_voidrun_fragment_shader( diff --git a/src/pipeline/pipeline.cpp b/src/pipeline/pipeline.cpp index 9561930..c0fc697 100644 --- a/src/pipeline/pipeline.cpp +++ b/src/pipeline/pipeline.cpp @@ -101,6 +101,7 @@ llvm_wrapper::Module Pipeline::optimize_module(llvm_wrapper::Module module, ::LLVMAddSCCPPass(manager.get()); ::LLVMAddAggressiveDCEPass(manager.get()); ::LLVMAddLICMPass(manager.get()); + ::LLVMAddIndVarSimplifyPass(manager.get()); ::LLVMAddCFGSimplificationPass(manager.get()); ::LLVMAddReassociatePass(manager.get()); ::LLVMAddInstructionCombiningPass(manager.get()); @@ -126,6 +127,8 @@ llvm_wrapper::Module Pipeline::optimize_module(llvm_wrapper::Module module, ::LLVMAddCFGSimplificationPass(manager.get()); ::LLVMAddPromoteMemoryToRegisterPass(manager.get()); ::LLVMAddScalarReplAggregatesPass(manager.get()); + ::LLVMAddLICMPass(manager.get()); + ::LLVMAddIndVarSimplifyPass(manager.get()); ::LLVMAddReassociatePass(manager.get()); ::LLVMAddInstructionCombiningPass(manager.get()); ::LLVMAddLoopUnrollPass(manager.get()); @@ -409,7 +412,8 @@ void Graphics_pipeline::dump_vertex_shader_output_struct(const void *output_stru void Graphics_pipeline::run(std::uint32_t vertex_start_index, std::uint32_t vertex_end_index, std::uint32_t instance_id, - const image::Image &color_attachment) + const image::Image &color_attachment, + void *const *bindings) { typedef std::uint32_t Pixel_type; assert(color_attachment.descriptor.tiling == VK_IMAGE_TILING_LINEAR); @@ -616,7 +620,8 @@ void Graphics_pipeline::run(std::uint32_t vertex_start_index, run_vertex_shader(current_vertex_start_index, current_vertex_start_index + chunk_size, instance_id, - chunk_vertex_buffer.get()); + chunk_vertex_buffer.get(), + bindings); const unsigned char *current_vertex = chunk_vertex_buffer.get() + vertex_shader_position_output_offset; triangles.clear(); @@ -919,13 +924,16 @@ std::unique_ptr Graphics_pipeline::make( } std::cerr << dump_callbacks.ss.str() << std::endl; } + assert(create_info.pVertexInputState); + assert(create_info.pVertexInputState->sType == VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO); auto compiled_shader = spirv_to_llvm::spirv_to_llvm(implementation->llvm_context.get(), llvm_target_machine.get(), shader_module->words(), shader_module->word_count(), implementation->compiled_shaders.size(), execution_model, - stage_info.pName); + stage_info.pName, + create_info.pVertexInputState); std::cerr << "Translation to LLVM succeeded." << std::endl; ::LLVMDumpModule(compiled_shader.module.get()); bool failed = diff --git a/src/pipeline/pipeline.h b/src/pipeline/pipeline.h index 8850d82..b125377 100644 --- a/src/pipeline/pipeline.h +++ b/src/pipeline/pipeline.h @@ -206,16 +206,19 @@ public: typedef void (*Vertex_shader_function)(std::uint32_t vertex_start_index, std::uint32_t vertex_end_index, std::uint32_t instance_id, - void *output_buffer); + void *output_buffer, + void *const *bindings); typedef void (*Fragment_shader_function)(std::uint32_t *color_attachment_pixel); public: void run_vertex_shader(std::uint32_t vertex_start_index, std::uint32_t vertex_end_index, std::uint32_t instance_id, - void *output_buffer) const noexcept + void *output_buffer, + void *const *input_bindings) const noexcept { - vertex_shader_function(vertex_start_index, vertex_end_index, instance_id, output_buffer); + vertex_shader_function( + vertex_start_index, vertex_end_index, instance_id, output_buffer, input_bindings); } std::size_t get_vertex_shader_output_struct_size() const noexcept { @@ -229,7 +232,8 @@ public: void run(std::uint32_t vertex_start_index, std::uint32_t vertex_end_index, std::uint32_t instance_id, - const image::Image &color_attachment); + const image::Image &color_attachment, + void *const *bindings); static std::unique_ptr make(Pipeline_cache *pipeline_cache, const VkGraphicsPipelineCreateInfo &create_info); static std::unique_ptr move_from_handle(VkPipeline pipeline) noexcept diff --git a/src/spirv_to_llvm/core_instructions.cpp b/src/spirv_to_llvm/core_instructions.cpp index 739f04a..586b6f7 100644 --- a/src/spirv_to_llvm/core_instructions.cpp +++ b/src/spirv_to_llvm/core_instructions.cpp @@ -880,9 +880,23 @@ void Spirv_to_llvm::handle_instruction_op_constant_composite(Op_constant_composi } case Stage::generate_code: { + auto type = get_type(instruction.result_type, instruction_start_index); + auto llvm_type = type->get_or_make_type(); auto &state = get_id_state(instruction.result); - state.value = Value(state.constant->get_or_make_value(), - get_type(instruction.result_type, instruction_start_index)); + auto global = ::LLVMAddGlobal(module.get(), llvm_type.type, ""); + ::LLVMSetAlignment(global, llvm_type.alignment); + ::LLVMSetGlobalConstant(global, true); + ::LLVMSetInitializer(global, state.constant->get_or_make_value()); + ::LLVMSetLinkage(global, ::LLVMInternalLinkage); + ::LLVMSetUnnamedAddr(global, true); + assert(!current_function_id); + auto set_value_fn = [this, &state, global, type, llvm_type]() + { + auto load = ::LLVMBuildLoad(builder.get(), global, ""); + ::LLVMSetAlignment(load, llvm_type.alignment); + state.value = Value(load, type); + }; + function_entry_block_handlers.push_back(set_value_fn); break; } } @@ -991,6 +1005,7 @@ void Spirv_to_llvm::handle_instruction_op_function(Op_function instruction, auto function = ::LLVMAddFunction( module.get(), function_name.c_str(), function_type->get_or_make_type().type); llvm_wrapper::Module::set_function_target_machine(function, target_machine); + ::LLVMSetLinkage(function, ::LLVMInternalLinkage); state.function = Function_state(function_type, function, std::move(function_name)); break; } diff --git a/src/spirv_to_llvm/spirv_to_llvm.cpp b/src/spirv_to_llvm/spirv_to_llvm.cpp index f046286..3ba5cbb 100644 --- a/src/spirv_to_llvm/spirv_to_llvm.cpp +++ b/src/spirv_to_llvm/spirv_to_llvm.cpp @@ -383,19 +383,65 @@ void Struct_type_descriptor::complete_type() + std::string(get_enumerant_name(decoration.value))); } auto member_type = member.type->get_or_make_type(); + std::size_t size = ::LLVMABISizeOfType(target_data, member_type.type); + struct Member_type_visitor : public Type_descriptor::Type_visitor + { + LLVM_type_and_alignment &member_type; + std::size_t &size; + Struct_type_descriptor *this_; + virtual void visit(Simple_type_descriptor &type) override + { +#warning finish implementing member type + } + virtual void visit(Vector_type_descriptor &type) override + { +#warning finish implementing member type + } + virtual void visit(Matrix_type_descriptor &type) override + { +#warning finish implementing member type + throw Parser_error(this_->instruction_start_index, + this_->instruction_start_index, + "unimplemented member type"); + } + virtual void visit(Array_type_descriptor &type) override + { +#warning finish implementing member type + } + virtual void visit(Pointer_type_descriptor &type) override + { +#warning finish implementing member type + } + virtual void visit(Function_type_descriptor &type) override + { +#warning finish implementing member type + } + virtual void visit(Struct_type_descriptor &type) override + { +#warning finish implementing member type + if(::LLVMIsOpaqueStruct(member_type.type)) + throw Parser_error(this_->instruction_start_index, + this_->instruction_start_index, + "recursive struct has infinite size"); + } + explicit Member_type_visitor(LLVM_type_and_alignment &member_type, + std::size_t &size, + Struct_type_descriptor *this_) noexcept + : member_type(member_type), + size(size), + this_(this_) + { + } + }; + member.type->visit(Member_type_visitor(member_type, size, this)); if(::LLVMGetTypeKind(member_type.type) == ::LLVMStructTypeKind && ::LLVMIsOpaqueStruct(member_type.type)) { - if(dynamic_cast(member.type.get())) - throw Parser_error(instruction_start_index, - instruction_start_index, - "recursive struct has infinite size"); throw Parser_error(instruction_start_index, instruction_start_index, "struct can't have opaque struct members"); } assert(is_power_of_2(member_type.alignment)); - std::size_t size = ::LLVMABISizeOfType(target_data, member_type.type); if(member_type.alignment > total_alignment) total_alignment = member_type.alignment; member_descriptors.push_back( @@ -450,17 +496,24 @@ void Spirv_to_llvm::handle_header(unsigned version_number_major, id_states.resize(id_bound - 1); } } +} -Converted_module spirv_to_llvm(::LLVMContextRef context, - ::LLVMTargetMachineRef target_machine, - const spirv::Word *shader_words, - std::size_t shader_size, - std::uint64_t shader_id, - spirv::Execution_model execution_model, - util::string_view entry_point_name) +spirv_to_llvm::Converted_module spirv_to_llvm::spirv_to_llvm( + ::LLVMContextRef context, + ::LLVMTargetMachineRef target_machine, + const spirv::Word *shader_words, + std::size_t shader_size, + std::uint64_t shader_id, + spirv::Execution_model execution_model, + util::string_view entry_point_name, + const VkPipelineVertexInputStateCreateInfo *vertex_input_state) { - return Spirv_to_llvm(context, target_machine, shader_id, execution_model, entry_point_name) + return Spirv_to_llvm(context, + target_machine, + shader_id, + execution_model, + entry_point_name, + vertex_input_state) .run(shader_words, shader_size); } } -} diff --git a/src/spirv_to_llvm/spirv_to_llvm.h b/src/spirv_to_llvm/spirv_to_llvm.h index 1171b7a..adabced 100644 --- a/src/spirv_to_llvm/spirv_to_llvm.h +++ b/src/spirv_to_llvm/spirv_to_llvm.h @@ -34,6 +34,7 @@ #include #include "llvm_wrapper/llvm_wrapper.h" #include "util/string_view.h" +#include "vulkan/vulkan.h" namespace vulkan_cpu { @@ -615,7 +616,8 @@ Converted_module spirv_to_llvm(::LLVMContextRef context, std::size_t shader_size, std::uint64_t shader_id, spirv::Execution_model execution_model, - util::string_view entry_point_name); + util::string_view entry_point_name, + const VkPipelineVertexInputStateCreateInfo *vertex_input_state); } } diff --git a/src/spirv_to_llvm/spirv_to_llvm_implementation.h b/src/spirv_to_llvm/spirv_to_llvm_implementation.h index 3efd13d..dad8879 100644 --- a/src/spirv_to_llvm/spirv_to_llvm_implementation.h +++ b/src/spirv_to_llvm/spirv_to_llvm_implementation.h @@ -232,6 +232,7 @@ private: spirv::Execution_model execution_model; util::string_view entry_point_name; Op_entry_point_state *entry_point_state_pointer = nullptr; + const VkPipelineVertexInputStateCreateInfo *vertex_input_state; private: Id_state &get_id_state(spirv::Id id) @@ -248,7 +249,8 @@ private: throw spirv::Parser_error( instruction_start_index, instruction_start_index, "id is not a type"); if(!retval) - throw spirv::Parser_error(instruction_start_index, instruction_start_index, "type mismatch"); + throw spirv::Parser_error( + instruction_start_index, instruction_start_index, "type mismatch"); return retval; } unsigned long long get_unsigned_integer_constant(spirv::Id id, @@ -263,8 +265,8 @@ private: auto llvm_type = type->get_or_make_type(); if(::LLVMGetTypeKind(llvm_type.type) != ::LLVMIntegerTypeKind) throw spirv::Parser_error(instruction_start_index, - instruction_start_index, - "id is not a constant integer"); + instruction_start_index, + "id is not a constant integer"); } else { @@ -284,8 +286,8 @@ private: auto llvm_type = type->get_or_make_type(); if(::LLVMGetTypeKind(llvm_type.type) != ::LLVMIntegerTypeKind) throw spirv::Parser_error(instruction_start_index, - instruction_start_index, - "id is not a constant integer"); + instruction_start_index, + "id is not a constant integer"); } else { @@ -351,25 +353,26 @@ private: || entry_point.entry_point.execution_model != execution_model) continue; if(entry_point_state_pointer) - throw spirv::Parser_error(entry_point.instruction_start_index, - entry_point.instruction_start_index, - "duplicate entry point: " - + std::string(spirv::get_enumerant_name(execution_model)) - + " \"" - + std::string(entry_point_name) - + "\""); + throw spirv::Parser_error( + entry_point.instruction_start_index, + entry_point.instruction_start_index, + "duplicate entry point: " + + std::string(spirv::get_enumerant_name(execution_model)) + + " \"" + + std::string(entry_point_name) + + "\""); entry_point_state_pointer = &entry_point; } } if(entry_point_state_pointer) return *entry_point_state_pointer; throw spirv::Parser_error(0, - 0, - "can't find entry point: " - + std::string(spirv::get_enumerant_name(execution_model)) - + " \"" - + std::string(entry_point_name) - + "\""); + 0, + "can't find entry point: " + + std::string(spirv::get_enumerant_name(execution_model)) + + " \"" + + std::string(entry_point_name) + + "\""); } public: @@ -377,13 +380,15 @@ public: ::LLVMTargetMachineRef target_machine, std::uint64_t shader_id, spirv::Execution_model execution_model, - util::string_view entry_point_name) + util::string_view entry_point_name, + const VkPipelineVertexInputStateCreateInfo *vertex_input_state) : context(context), target_machine(target_machine), shader_id(shader_id), stage(), execution_model(execution_model), - entry_point_name(entry_point_name) + entry_point_name(entry_point_name), + vertex_input_state(vertex_input_state) { { std::ostringstream ss; @@ -395,35 +400,36 @@ public: target_data = ::LLVMGetModuleDataLayout(module.get()); builder = llvm_wrapper::Builder::create(context); constexpr std::size_t no_instruction_index = 0; - io_struct = - std::make_shared(std::vector{}, - context, - target_data, - get_prefixed_name("Io_struct", true).c_str(), - no_instruction_index); + io_struct = std::make_shared( + std::vector{}, + context, + target_data, + get_prefixed_name("Io_struct", true).c_str(), + no_instruction_index); assert(implicit_function_arguments.size() == 1); static_assert(io_struct_argument_index == 0, ""); implicit_function_arguments[io_struct_argument_index] = - std::make_shared(std::vector{}, - io_struct, - no_instruction_index, - target_data); - inputs_struct = - std::make_shared(std::vector{}, - context, - target_data, - get_prefixed_name("Inputs", true).c_str(), - no_instruction_index); + std::make_shared( + std::vector{}, + io_struct, + no_instruction_index, + target_data); + inputs_struct = std::make_shared( + std::vector{}, + context, + target_data, + get_prefixed_name("Inputs", true).c_str(), + no_instruction_index); inputs_member = io_struct->add_member(Struct_type_descriptor::Member( {}, std::make_shared( std::vector{}, inputs_struct, 0, target_data))); - outputs_struct = - std::make_shared(std::vector{}, - context, - target_data, - get_prefixed_name("Outputs", true).c_str(), - no_instruction_index); + outputs_struct = std::make_shared( + std::vector{}, + context, + target_data, + get_prefixed_name("Outputs", true).c_str(), + no_instruction_index); outputs_struct_pointer_type = std::make_shared( std::vector{}, outputs_struct, 0, target_data); outputs_member = @@ -432,7 +438,7 @@ public: ::LLVMValueRef generate_vertex_entry_function(Op_entry_point_state &entry_point, ::LLVMValueRef main_function); ::LLVMValueRef generate_fragment_entry_function(Op_entry_point_state &entry_point, - ::LLVMValueRef main_function); + ::LLVMValueRef main_function); std::string generate_entry_function(Op_entry_point_state &entry_point, ::LLVMValueRef main_function) { @@ -444,37 +450,42 @@ public: break; case spirv::Execution_model::tessellation_control: #warning implement execution model - throw spirv::Parser_error(entry_point.instruction_start_index, - entry_point.instruction_start_index, - "unimplemented execution model: " - + std::string(spirv::get_enumerant_name(execution_model))); + throw spirv::Parser_error( + entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); case spirv::Execution_model::tessellation_evaluation: #warning implement execution model - throw spirv::Parser_error(entry_point.instruction_start_index, - entry_point.instruction_start_index, - "unimplemented execution model: " - + std::string(spirv::get_enumerant_name(execution_model))); + throw spirv::Parser_error( + entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); case spirv::Execution_model::geometry: #warning implement execution model - throw spirv::Parser_error(entry_point.instruction_start_index, - entry_point.instruction_start_index, - "unimplemented execution model: " - + std::string(spirv::get_enumerant_name(execution_model))); + throw spirv::Parser_error( + entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); case spirv::Execution_model::fragment: entry_function = generate_fragment_entry_function(entry_point, main_function); break; case spirv::Execution_model::gl_compute: #warning implement execution model - throw spirv::Parser_error(entry_point.instruction_start_index, - entry_point.instruction_start_index, - "unimplemented execution model: " - + std::string(spirv::get_enumerant_name(execution_model))); + throw spirv::Parser_error( + entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); case spirv::Execution_model::kernel: // TODO: implement execution model as extension - throw spirv::Parser_error(entry_point.instruction_start_index, - entry_point.instruction_start_index, - "unimplemented execution model: " - + std::string(spirv::get_enumerant_name(execution_model))); + throw spirv::Parser_error( + entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); } assert(entry_function); return ::LLVMGetValueName(entry_function); @@ -495,8 +506,8 @@ public: auto &entry_point_id_state = get_id_state(entry_point_state.entry_point.entry_point); if(!entry_point_id_state.function) throw spirv::Parser_error(entry_point_state.instruction_start_index, - entry_point_state.instruction_start_index, - "No definition for function referenced in OpEntryPoint"); + entry_point_state.instruction_start_index, + "No definition for function referenced in OpEntryPoint"); auto entry_function_name = generate_entry_function(entry_point_state, entry_point_id_state.function->function); return Converted_module(std::move(module), diff --git a/src/spirv_to_llvm/vertex_entry_point.cpp b/src/spirv_to_llvm/vertex_entry_point.cpp index b04049d..1b73100 100644 --- a/src/spirv_to_llvm/vertex_entry_point.cpp +++ b/src/spirv_to_llvm/vertex_entry_point.cpp @@ -21,6 +21,7 @@ * */ #include "spirv_to_llvm_implementation.h" +#include namespace vulkan_cpu { @@ -31,16 +32,24 @@ using namespace spirv; ::LLVMValueRef Spirv_to_llvm::generate_vertex_entry_function(Op_entry_point_state &entry_point, ::LLVMValueRef main_function) { + assert(vertex_input_state); typedef std::uint32_t Vertex_index_type; auto llvm_vertex_index_type = llvm_wrapper::Create_llvm_type()(context); + auto llvm_size_t_type = llvm_wrapper::Create_llvm_type()(context); + auto llvm_unsigned_char_pointer_type = + llvm_wrapper::Create_llvm_type()(context); + auto llvm_float_type = llvm_wrapper::Create_llvm_type()(context); + auto llvm_float_type_alignment = ::LLVMPreferredAlignmentOfType(target_data, llvm_float_type); typedef void (*Vertex_shader_function)(Vertex_index_type vertex_start_index, Vertex_index_type vertex_end_index, std::uint32_t instance_id, - void *output_buffer); + void *output_buffer, + void *const *bindings); constexpr std::size_t arg_vertex_start_index = 0; constexpr std::size_t arg_vertex_end_index = 1; constexpr std::size_t arg_instance_id = 2; constexpr std::size_t arg_output_buffer = 3; + constexpr std::size_t arg_bindings = 4; static_assert(std::is_same::value, "vertex shader function signature mismatch"); @@ -53,6 +62,7 @@ using namespace spirv; ::LLVMSetValueName(::LLVMGetParam(entry_function, arg_vertex_end_index), "vertex_end_index"); ::LLVMSetValueName(::LLVMGetParam(entry_function, arg_instance_id), "instance_id"); ::LLVMSetValueName(::LLVMGetParam(entry_function, arg_output_buffer), "output_buffer_"); + ::LLVMSetValueName(::LLVMGetParam(entry_function, arg_bindings), "bindings"); auto entry_block = ::LLVMAppendBasicBlockInContext(context, entry_function, "entry"); auto loop_block = ::LLVMAppendBasicBlockInContext(context, entry_function, "loop"); auto exit_block = ::LLVMAppendBasicBlockInContext(context, entry_function, "exit"); @@ -70,6 +80,23 @@ using namespace spirv; io_struct->get_members(true)[inputs_member].llvm_member_index, "inputs_pointer"); ::LLVMBuildStore(builder.get(), inputs_struct_pointer, inputs_pointer); + std::unordered_map input_bindings; + for(std::size_t i = 0; i < vertex_input_state->vertexBindingDescriptionCount; i++) + { + auto binding = vertex_input_state->pVertexBindingDescriptions[i].binding; + const std::size_t index_count = 1; + ::LLVMValueRef indexes[index_count] = {::LLVMConstInt(llvm_size_t_type, binding, false)}; + auto input_binding = + ::LLVMBuildLoad(builder.get(), + ::LLVMBuildGEP(builder.get(), + ::LLVMGetParam(entry_function, arg_bindings), + indexes, + index_count, + ""), + "input_binding"); + if(!std::get<1>(input_bindings.emplace(binding, input_binding))) + throw Parser_error(0, 0, "duplicate vertex input binding"); + } auto start_output_buffer = ::LLVMBuildBitCast(builder.get(), ::LLVMGetParam(entry_function, arg_output_buffer), @@ -134,6 +161,7 @@ using namespace spirv; builder.get(), inputs_struct_pointer, input_member.llvm_member_index, "input"); ::LLVMDumpType(::LLVMTypeOf(input_pointer)); util::optional built_in; + util::optional location; static_cast(input_pointer); for(auto &decoration : input_member.decorations) { @@ -176,9 +204,8 @@ using namespace spirv; if(built_in) throw Parser_error( 0, 0, "multiple BuiltIn decorations on the same variable"); - built_in = - util::get(decoration.parameters) - .built_in; + built_in = util::get(decoration.parameters) + .built_in; continue; case Decoration::no_perspective: #warning finish implementing Decoration::no_perspective @@ -229,8 +256,12 @@ using namespace spirv; #warning finish implementing Decoration::stream break; case Decoration::location: -#warning finish implementing Decoration::location - break; + if(location) + throw Parser_error( + 0, 0, "multiple Location decorations on the same variable"); + location = util::get(decoration.parameters) + .location; + continue; case Decoration::component: #warning finish implementing Decoration::component break; @@ -295,199 +326,351 @@ using namespace spirv; #warning finish implementing Decoration::secondary_viewport_relative_nv break; } - throw Parser_error( - 0, - 0, - "unimplemented member decoration on shader input variable: " - + std::string(get_enumerant_name(decoration.value))); + throw Parser_error(0, + 0, + "unimplemented member decoration on shader input variable: " + + std::string(get_enumerant_name(decoration.value))); } + auto input_type = input_member.type->get_or_make_type(); if(!built_in) - throw Parser_error( - 0, 0, "non-built-in shader input variables are not implemented"); - do { - switch(*built_in) + if(!location) + throw Parser_error( + 0, + 0, + "non-built-in shader input variable is missing Location decoration"); + ::LLVMValueRef input_value = ::LLVMGetUndef(input_type.type); + bool found = false; + for(std::size_t i = 0; i < vertex_input_state->vertexAttributeDescriptionCount; + i++) { - case Built_in::position: + auto &vertex_attribute_description = + vertex_input_state->pVertexAttributeDescriptions[i]; + if(*location == vertex_attribute_description.location) + { + found = true; + assert(vertex_attribute_description.binding + < vertex_input_state->vertexBindingDescriptionCount); + ::LLVMValueRef input_binding; + { + auto iter = + input_bindings.find(vertex_attribute_description.binding); + if(iter == input_bindings.end()) + throw Parser_error(0, + 0, + "vertex input binding number not found in " + "VkPipelineVertexInputStateCreateInfo::" + "pVertexBindingDescriptions"); + input_binding = std::get<1>(*iter); + } + auto &vertex_binding_description = + vertex_input_state->pVertexBindingDescriptions + [vertex_attribute_description.binding]; + ::LLVMValueRef input_element_index = nullptr; + switch(vertex_binding_description.inputRate) + { + case VK_VERTEX_INPUT_RATE_INSTANCE: + input_element_index = + ::LLVMGetParam(entry_function, arg_instance_id); + break; + case VK_VERTEX_INPUT_RATE_VERTEX: + input_element_index = vertex_index; + break; + // so compiler doesn't complain about missing enum values + case VK_VERTEX_INPUT_RATE_RANGE_SIZE: + case VK_VERTEX_INPUT_RATE_MAX_ENUM: + break; + } + if(!input_element_index) + throw Parser_error(0, 0, "unimplemented vertex input rate"); + ::LLVMValueRef input_element; + if(vertex_binding_description.stride != 0) + { + auto input_element_as_unsigned_char_array_type = ::LLVMArrayType( + llvm_wrapper::Create_llvm_type()(context), + vertex_binding_description.stride); + constexpr unsigned default_address_space = 0; + auto input_element_as_unsigned_char_array_pointer_type = + ::LLVMPointerType(input_element_as_unsigned_char_array_type, + default_address_space); + auto bitcasted_input_binding = ::LLVMBuildBitCast( + builder.get(), + input_binding, + input_element_as_unsigned_char_array_pointer_type, + "bitcasted_input_binding"); + { + const std::size_t index_count = 1; + ::LLVMValueRef indexes[index_count] = {input_element_index}; + input_element = ::LLVMBuildGEP(builder.get(), + bitcasted_input_binding, + indexes, + index_count, + ""); + } + } + else + { + input_element = input_binding; + } + input_element = ::LLVMBuildBitCast(builder.get(), + input_element, + llvm_unsigned_char_pointer_type, + "input_element"); + ::LLVMValueRef input_value_ptr; + { + const std::size_t index_count = 1; + ::LLVMValueRef indexes[index_count] = {::LLVMConstInt( + llvm_size_t_type, vertex_attribute_description.offset, false)}; + input_value_ptr = ::LLVMBuildGEP(builder.get(), + input_element, + indexes, + index_count, + "input_value_ptr"); + } + std::function<::LLVMValueRef(::LLVMValueRef)> run_type_conversion = + nullptr; + LLVM_type_and_alignment format_type; + switch(vertex_attribute_description.format) + { + case VK_FORMAT_R32G32B32A32_SFLOAT: + { + constexpr std::size_t vector_element_count = 4; + format_type = + Vector_type_descriptor( + std::vector{}, + std::make_shared( + std::vector{}, + LLVM_type_and_alignment(llvm_float_type, + llvm_float_type_alignment)), + vector_element_count, + target_data) + .get_or_make_type(); + if(input_type.type != format_type.type) + throw Parser_error( + 0, + 0, + "unimplemented vertex input variable type conversion"); + break; + } +#warning implement all required formats + default: + throw Parser_error(0, 0, "unimplemented vertex input format"); + } + constexpr unsigned default_address_space = 0; + auto format_pointer_type = + ::LLVMPointerType(format_type.type, default_address_space); + auto unconverted_input_value = ::LLVMBuildLoad( + builder.get(), + ::LLVMBuildBitCast( + builder.get(), input_value_ptr, format_pointer_type, ""), + "unconverted_input_value"); + ::LLVMSetAlignment(unconverted_input_value, format_type.alignment); + if(run_type_conversion) + input_value = run_type_conversion(unconverted_input_value); + else + input_value = unconverted_input_value; + break; + } + } + ::LLVMSetAlignment(::LLVMBuildStore(builder.get(), input_value, input_pointer), + input_type.alignment); + if(!found) + throw Parser_error( + 0, + 0, + "non-exactly-matched shader input variable Location not implemented"); + } + else + { + if(location) + throw Parser_error(0, + 0, + "Location decoration not implemented on built-in shader " + "input variables"); + do + { + switch(*built_in) + { + case Built_in::position: #warning finish implementing Built_in::position - break; - case Built_in::point_size: + break; + case Built_in::point_size: #warning finish implementing Built_in::point_size - break; - case Built_in::clip_distance: + break; + case Built_in::clip_distance: #warning finish implementing Built_in::clip_distance - break; - case Built_in::cull_distance: + break; + case Built_in::cull_distance: #warning finish implementing Built_in::cull_distance - break; - case Built_in::vertex_id: + break; + case Built_in::vertex_id: #warning finish implementing Built_in::vertex_id - break; - case Built_in::instance_id: + break; + case Built_in::instance_id: #warning finish implementing Built_in::instance_id - break; - case Built_in::primitive_id: + break; + case Built_in::primitive_id: #warning finish implementing Built_in::primitive_id - break; - case Built_in::invocation_id: + break; + case Built_in::invocation_id: #warning finish implementing Built_in::invocation_id - break; - case Built_in::layer: + break; + case Built_in::layer: #warning finish implementing Built_in::layer - break; - case Built_in::viewport_index: + break; + case Built_in::viewport_index: #warning finish implementing Built_in::viewport_index - break; - case Built_in::tess_level_outer: + break; + case Built_in::tess_level_outer: #warning finish implementing Built_in::tess_level_outer - break; - case Built_in::tess_level_inner: + break; + case Built_in::tess_level_inner: #warning finish implementing Built_in::tess_level_inner - break; - case Built_in::tess_coord: + break; + case Built_in::tess_coord: #warning finish implementing Built_in::tess_coord - break; - case Built_in::patch_vertices: + break; + case Built_in::patch_vertices: #warning finish implementing Built_in::patch_vertices - break; - case Built_in::frag_coord: + break; + case Built_in::frag_coord: #warning finish implementing Built_in::frag_coord - break; - case Built_in::point_coord: + break; + case Built_in::point_coord: #warning finish implementing Built_in::point_coord - break; - case Built_in::front_facing: + break; + case Built_in::front_facing: #warning finish implementing Built_in::front_facing - break; - case Built_in::sample_id: + break; + case Built_in::sample_id: #warning finish implementing Built_in::sample_id - break; - case Built_in::sample_position: + break; + case Built_in::sample_position: #warning finish implementing Built_in::sample_position - break; - case Built_in::sample_mask: + break; + case Built_in::sample_mask: #warning finish implementing Built_in::sample_mask - break; - case Built_in::frag_depth: + break; + case Built_in::frag_depth: #warning finish implementing Built_in::frag_depth - break; - case Built_in::helper_invocation: + break; + case Built_in::helper_invocation: #warning finish implementing Built_in::helper_invocation - break; - case Built_in::num_workgroups: + break; + case Built_in::num_workgroups: #warning finish implementing Built_in::num_workgroups - break; - case Built_in::workgroup_size: + break; + case Built_in::workgroup_size: #warning finish implementing Built_in::workgroup_size - break; - case Built_in::workgroup_id: + break; + case Built_in::workgroup_id: #warning finish implementing Built_in::workgroup_id - break; - case Built_in::local_invocation_id: + break; + case Built_in::local_invocation_id: #warning finish implementing Built_in::local_invocation_id - break; - case Built_in::global_invocation_id: + break; + case Built_in::global_invocation_id: #warning finish implementing Built_in::global_invocation_id - break; - case Built_in::local_invocation_index: + break; + case Built_in::local_invocation_index: #warning finish implementing Built_in::local_invocation_index - break; - case Built_in::work_dim: + break; + case Built_in::work_dim: #warning finish implementing Built_in::work_dim - break; - case Built_in::global_size: + break; + case Built_in::global_size: #warning finish implementing Built_in::global_size - break; - case Built_in::enqueued_workgroup_size: + break; + case Built_in::enqueued_workgroup_size: #warning finish implementing Built_in::enqueued_workgroup_size - break; - case Built_in::global_offset: + break; + case Built_in::global_offset: #warning finish implementing Built_in::global_offset - break; - case Built_in::global_linear_id: + break; + case Built_in::global_linear_id: #warning finish implementing Built_in::global_linear_id - break; - case Built_in::subgroup_size: + break; + case Built_in::subgroup_size: #warning finish implementing Built_in::subgroup_size - break; - case Built_in::subgroup_max_size: + break; + case Built_in::subgroup_max_size: #warning finish implementing Built_in::subgroup_max_size - break; - case Built_in::num_subgroups: + break; + case Built_in::num_subgroups: #warning finish implementing Built_in::num_subgroups - break; - case Built_in::num_enqueued_subgroups: + break; + case Built_in::num_enqueued_subgroups: #warning finish implementing Built_in::num_enqueued_subgroups - break; - case Built_in::subgroup_id: + break; + case Built_in::subgroup_id: #warning finish implementing Built_in::subgroup_id - break; - case Built_in::subgroup_local_invocation_id: + break; + case Built_in::subgroup_local_invocation_id: #warning finish implementing Built_in::subgroup_local_invocation_id - break; - case Built_in::vertex_index: - { - if(::LLVMGetElementType(::LLVMTypeOf(input_pointer)) - != llvm_vertex_index_type) - throw Parser_error( - 0, 0, "invalid type for vertex index built-in variable"); - ::LLVMBuildStore(builder.get(), vertex_index, input_pointer); - continue; - } - case Built_in::instance_index: + break; + case Built_in::vertex_index: + { + if(input_type.type != llvm_vertex_index_type) + throw Parser_error( + 0, 0, "invalid type for vertex index built-in variable"); + ::LLVMBuildStore(builder.get(), vertex_index, input_pointer); + continue; + } + case Built_in::instance_index: #warning finish implementing Built_in::instance_index - break; - case Built_in::subgroup_eq_mask_khr: + break; + case Built_in::subgroup_eq_mask_khr: #warning finish implementing Built_in::subgroup_eq_mask_khr - break; - case Built_in::subgroup_ge_mask_khr: + break; + case Built_in::subgroup_ge_mask_khr: #warning finish implementing Built_in::subgroup_ge_mask_khr - break; - case Built_in::subgroup_gt_mask_khr: + break; + case Built_in::subgroup_gt_mask_khr: #warning finish implementing Built_in::subgroup_gt_mask_khr - break; - case Built_in::subgroup_le_mask_khr: + break; + case Built_in::subgroup_le_mask_khr: #warning finish implementing Built_in::subgroup_le_mask_khr - break; - case Built_in::subgroup_lt_mask_khr: + break; + case Built_in::subgroup_lt_mask_khr: #warning finish implementing Built_in::subgroup_lt_mask_khr - break; - case Built_in::base_vertex: + break; + case Built_in::base_vertex: #warning finish implementing Built_in::base_vertex - break; - case Built_in::base_instance: + break; + case Built_in::base_instance: #warning finish implementing Built_in::base_instance - break; - case Built_in::draw_index: + break; + case Built_in::draw_index: #warning finish implementing Built_in::draw_index - break; - case Built_in::device_index: + break; + case Built_in::device_index: #warning finish implementing Built_in::device_index - break; - case Built_in::view_index: + break; + case Built_in::view_index: #warning finish implementing Built_in::view_index - break; - case Built_in::viewport_mask_nv: + break; + case Built_in::viewport_mask_nv: #warning finish implementing Built_in::viewport_mask_nv - break; - case Built_in::secondary_position_nv: + break; + case Built_in::secondary_position_nv: #warning finish implementing Built_in::secondary_position_nv - break; - case Built_in::secondary_viewport_mask_nv: + break; + case Built_in::secondary_viewport_mask_nv: #warning finish implementing Built_in::secondary_viewport_mask_nv - break; - case Built_in::position_per_view_nv: + break; + case Built_in::position_per_view_nv: #warning finish implementing Built_in::position_per_view_nv - break; - case Built_in::viewport_mask_per_view_nv: + break; + case Built_in::viewport_mask_per_view_nv: #warning finish implementing Built_in::viewport_mask_per_view_nv - break; - } - throw Parser_error(0, - 0, - "unimplemented built in shader input variable: " - + std::string(get_enumerant_name(*built_in))); - } while(false); + break; + } + throw Parser_error(0, + 0, + "unimplemented built in shader input variable: " + + std::string(get_enumerant_name(*built_in))); + } while(false); + } } } else if(member_index == outputs_member) @@ -660,11 +843,10 @@ using namespace spirv; #warning finish implementing Decoration::secondary_viewport_relative_nv break; } - throw Parser_error( - 0, - 0, - "unimplemented member decoration on shader output variable: " - + std::string(get_enumerant_name(decoration.value))); + throw Parser_error(0, + 0, + "unimplemented member decoration on shader output variable: " + + std::string(get_enumerant_name(decoration.value))); } } } @@ -694,9 +876,10 @@ using namespace spirv; "next_iteration_condition"); ::LLVMBuildCondBr(builder.get(), next_iteration_condition, loop_block, exit_block); ::LLVMPositionBuilderAtEnd(builder.get(), exit_block); - static_assert(std::is_same()(0, 0, 0, nullptr)), - void>::value, - ""); + static_assert( + std::is_same()(0, 0, 0, nullptr, nullptr)), + void>::value, + ""); ::LLVMBuildRetVoid(builder.get()); return entry_function; } diff --git a/test-files/demo-text.obj b/test-files/demo-text.obj new file mode 100644 index 0000000..7ca75ba --- /dev/null +++ b/test-files/demo-text.obj @@ -0,0 +1,2214 @@ +# Blender v2.78 (sub 0) OBJ File: 'demo-text.blend' +# www.blender.org +v 0.333078 0.069515 0.213613 +v 0.334979 0.068824 0.213613 +v 0.337041 0.068076 0.213616 +v 0.339236 0.067285 0.213625 +v 0.341532 0.066465 0.213642 +v 0.343900 0.065628 0.213671 +v 0.346309 0.064789 0.213713 +v 0.348731 0.063961 0.213772 +v 0.351133 0.063156 0.213851 +v 0.353488 0.062390 0.213952 +v 0.355764 0.061674 0.214078 +v 0.357931 0.061023 0.214232 +v 0.359960 0.060449 0.214417 +v 0.353648 0.043107 0.192423 +v 0.351691 0.043939 0.192557 +v 0.349554 0.044835 0.192689 +v 0.347273 0.045779 0.192817 +v 0.344888 0.046757 0.192940 +v 0.342437 0.047752 0.193055 +v 0.339959 0.048748 0.193161 +v 0.337490 0.049731 0.193255 +v 0.335071 0.050685 0.193337 +v 0.332738 0.051593 0.193404 +v 0.330531 0.052441 0.193454 +v 0.328488 0.053213 0.193485 +v 0.326647 0.053893 0.193496 +v 0.215766 0.094250 0.193496 +v 0.199447 0.049414 0.136633 +v 0.284993 0.018277 0.136633 +v 0.287795 0.017267 0.136643 +v 0.290454 0.016327 0.136674 +v 0.292982 0.015448 0.136721 +v 0.295394 0.014625 0.136782 +v 0.297704 0.013848 0.136854 +v 0.299927 0.013111 0.136934 +v 0.302076 0.012406 0.137021 +v 0.304165 0.011725 0.137110 +v 0.306208 0.011061 0.137198 +v 0.308219 0.010406 0.137285 +v 0.310214 0.009752 0.137365 +v 0.312204 0.009092 0.137437 +v 0.306046 -0.007827 0.115980 +v 0.304234 -0.007048 0.116113 +v 0.302341 -0.006242 0.116245 +v 0.300370 -0.005410 0.116374 +v 0.298322 -0.004555 0.116496 +v 0.296198 -0.003679 0.116611 +v 0.294001 -0.002785 0.116717 +v 0.291733 -0.001875 0.116812 +v 0.289394 -0.000951 0.116894 +v 0.286987 -0.000015 0.116960 +v 0.284513 0.000930 0.117010 +v 0.281975 0.001882 0.117042 +v 0.279374 0.002838 0.117052 +v 0.122758 0.059842 0.117052 +v 0.119992 0.060839 0.117042 +v 0.117285 0.061796 0.117010 +v 0.114635 0.062716 0.116960 +v 0.112038 0.063602 0.116894 +v 0.109491 0.064456 0.116812 +v 0.106992 0.065281 0.116717 +v 0.104538 0.066079 0.116611 +v 0.102126 0.066855 0.116496 +v 0.099753 0.067609 0.116374 +v 0.097416 0.068345 0.116245 +v 0.095112 0.069066 0.116113 +v 0.092838 0.069774 0.115980 +v 0.098996 0.086693 0.137437 +v 0.101195 0.085778 0.137309 +v 0.103427 0.084861 0.137192 +v 0.105697 0.083940 0.137085 +v 0.108008 0.083014 0.136990 +v 0.110363 0.082082 0.136907 +v 0.112766 0.081143 0.136834 +v 0.115220 0.080195 0.136772 +v 0.117728 0.079237 0.136722 +v 0.120295 0.078267 0.136683 +v 0.122923 0.077286 0.136655 +v 0.125616 0.076291 0.136638 +v 0.128378 0.075281 0.136633 +v 0.172138 0.059353 0.136633 +v 0.188457 0.104190 0.193496 +v 0.124626 0.127422 0.193496 +v 0.122310 0.128251 0.193480 +v 0.119825 0.129114 0.193434 +v 0.117205 0.130003 0.193362 +v 0.114483 0.130910 0.193267 +v 0.111691 0.131825 0.193154 +v 0.108863 0.132740 0.193027 +v 0.106032 0.133647 0.192887 +v 0.103230 0.134536 0.192741 +v 0.100492 0.135398 0.192591 +v 0.097849 0.136226 0.192440 +v 0.095336 0.137010 0.192294 +v 0.092984 0.137741 0.192155 +v 0.099450 0.155507 0.214686 +v 0.101799 0.154533 0.214552 +v 0.104294 0.153507 0.214420 +v 0.106905 0.152442 0.214292 +v 0.109599 0.151352 0.214169 +v 0.112346 0.150249 0.214054 +v 0.115114 0.149147 0.213948 +v 0.117871 0.148059 0.213853 +v 0.120587 0.146998 0.213772 +v 0.123229 0.145976 0.213705 +v 0.125766 0.145008 0.213655 +v 0.128166 0.144107 0.213624 +v 0.130400 0.143284 0.213613 +v 0.194230 0.120052 0.213613 +v 0.211627 0.167849 0.274231 +v 0.213490 0.171933 0.279564 +v 0.215964 0.175485 0.284550 +v 0.219106 0.178464 0.289168 +v 0.222976 0.180830 0.293394 +v 0.227632 0.182540 0.297207 +v 0.233132 0.183554 0.300584 +v 0.239537 0.183829 0.303503 +v 0.246903 0.183325 0.305941 +v 0.255291 0.182000 0.307876 +v 0.264758 0.179814 0.309286 +v 0.275363 0.176724 0.310149 +v 0.287166 0.172689 0.310441 +v 0.295052 0.169799 0.310419 +v 0.302906 0.166882 0.310354 +v 0.310708 0.163948 0.310248 +v 0.318436 0.161006 0.310103 +v 0.326071 0.158064 0.309921 +v 0.333593 0.155132 0.309704 +v 0.340982 0.152218 0.309452 +v 0.348219 0.149332 0.309170 +v 0.355282 0.146482 0.308857 +v 0.362152 0.143678 0.308516 +v 0.368809 0.140927 0.308150 +v 0.375232 0.138240 0.307759 +v 0.370411 0.119876 0.285228 +v 0.363544 0.122945 0.285866 +v 0.356694 0.125949 0.286438 +v 0.349842 0.128897 0.286946 +v 0.342968 0.131798 0.287394 +v 0.336055 0.134661 0.287782 +v 0.329083 0.137493 0.288112 +v 0.322033 0.140304 0.288386 +v 0.314886 0.143102 0.288606 +v 0.307624 0.145895 0.288774 +v 0.300228 0.148692 0.288891 +v 0.292678 0.151502 0.288961 +v 0.284956 0.154333 0.288983 +v 0.277727 0.156815 0.288817 +v 0.271161 0.158766 0.288325 +v 0.265235 0.160200 0.287516 +v 0.259928 0.161136 0.286400 +v 0.255215 0.161588 0.284986 +v 0.251076 0.161574 0.283284 +v 0.247487 0.161111 0.281301 +v 0.244425 0.160214 0.279049 +v 0.241870 0.158900 0.276536 +v 0.239797 0.157186 0.273772 +v 0.238185 0.155087 0.270765 +v 0.237012 0.152622 0.267525 +v 0.221539 0.110112 0.213613 +v -0.007781 0.114779 0.125367 +v -0.010424 0.113197 0.122519 +v -0.013292 0.111543 0.119497 +v -0.016345 0.109839 0.116344 +v -0.019540 0.108104 0.113099 +v -0.022837 0.106359 0.109801 +v -0.026195 0.104626 0.106491 +v -0.029572 0.102924 0.103209 +v -0.032927 0.101276 0.099995 +v -0.036220 0.099701 0.096890 +v -0.039408 0.098220 0.093932 +v -0.042451 0.096854 0.091162 +v -0.045307 0.095624 0.088621 +v -0.060975 0.106836 0.094790 +v -0.057963 0.108064 0.097393 +v -0.054816 0.109438 0.100214 +v -0.051571 0.110935 0.103214 +v -0.048261 0.112534 0.106353 +v -0.044922 0.114212 0.109593 +v -0.041590 0.115947 0.112895 +v -0.038299 0.117717 0.116219 +v -0.035085 0.119501 0.119526 +v -0.031983 0.121275 0.122777 +v -0.029028 0.123018 0.125934 +v -0.026256 0.124708 0.128956 +v -0.023701 0.126322 0.131805 +v -0.080622 0.147039 0.131805 +v -0.078196 0.146161 0.131810 +v -0.075699 0.145267 0.131827 +v -0.073143 0.144362 0.131855 +v -0.070543 0.143451 0.131894 +v -0.067912 0.142538 0.131944 +v -0.065265 0.141629 0.132006 +v -0.062614 0.140729 0.132079 +v -0.059974 0.139843 0.132162 +v -0.057358 0.138976 0.132257 +v -0.054780 0.138132 0.132364 +v -0.052253 0.137318 0.132481 +v -0.049792 0.136537 0.132609 +v -0.056181 0.118983 0.110347 +v -0.058538 0.120070 0.110604 +v -0.060980 0.121168 0.110839 +v -0.063490 0.122272 0.111051 +v -0.066051 0.123373 0.111241 +v -0.068646 0.124468 0.111409 +v -0.071258 0.125548 0.111554 +v -0.073869 0.126608 0.111677 +v -0.076463 0.127642 0.111777 +v -0.079021 0.128643 0.111856 +v -0.081528 0.129605 0.111912 +v -0.083967 0.130523 0.111945 +v -0.086318 0.131389 0.111956 +v -0.200161 0.172824 0.111956 +v -0.202784 0.173764 0.111940 +v -0.205390 0.174671 0.111893 +v -0.207979 0.175546 0.111818 +v -0.210551 0.176393 0.111718 +v -0.213106 0.177214 0.111595 +v -0.215646 0.178011 0.111453 +v -0.218170 0.178788 0.111295 +v -0.220678 0.179546 0.111122 +v -0.223171 0.180290 0.110938 +v -0.225650 0.181020 0.110745 +v -0.228114 0.181740 0.110548 +v -0.230564 0.182453 0.110347 +v -0.224175 0.200007 0.132609 +v -0.222026 0.199110 0.132481 +v -0.219787 0.198190 0.132364 +v -0.217464 0.197250 0.132257 +v -0.215066 0.196292 0.132162 +v -0.212601 0.195320 0.132079 +v -0.210077 0.194336 0.132006 +v -0.207501 0.193344 0.131944 +v -0.204882 0.192346 0.131894 +v -0.202228 0.191345 0.131855 +v -0.199547 0.190344 0.131827 +v -0.196847 0.189347 0.131810 +v -0.194135 0.188355 0.131805 +v -0.027938 0.084992 0.083793 +v -0.024776 0.086202 0.086437 +v -0.021538 0.087539 0.089254 +v -0.018246 0.088986 0.092217 +v -0.014924 0.090527 0.095297 +v -0.011595 0.092146 0.098466 +v -0.008282 0.093824 0.101697 +v -0.005007 0.095547 0.104961 +v -0.001793 0.097297 0.108231 +v 0.001337 0.099058 0.111478 +v 0.004360 0.100813 0.114676 +v 0.007253 0.102545 0.117795 +v 0.009994 0.104238 0.120808 +v 0.025913 0.092695 0.114370 +v 0.023468 0.091247 0.111752 +v 0.020718 0.089695 0.108893 +v 0.017713 0.088064 0.105842 +v 0.014506 0.086380 0.102648 +v 0.011150 0.084666 0.099361 +v 0.007695 0.082950 0.096030 +v 0.004194 0.081255 0.092705 +v 0.000698 0.079608 0.089435 +v -0.002741 0.078032 0.086270 +v -0.006070 0.076554 0.083258 +v -0.009238 0.075199 0.080449 +v -0.012193 0.073992 0.077892 +v -0.221057 0.240307 0.179012 +v -0.223597 0.241222 0.179001 +v -0.226115 0.242110 0.178970 +v -0.228610 0.242974 0.178920 +v -0.231083 0.243814 0.178853 +v -0.233533 0.244633 0.178771 +v -0.235960 0.245432 0.178677 +v -0.238362 0.246212 0.178571 +v -0.240739 0.246974 0.178456 +v -0.243091 0.247721 0.178333 +v -0.245418 0.248453 0.178205 +v -0.247717 0.249172 0.178073 +v -0.249990 0.249880 0.177939 +v -0.243678 0.267222 0.199933 +v -0.241479 0.266312 0.199810 +v -0.239247 0.265407 0.199707 +v -0.236981 0.264508 0.199623 +v -0.234684 0.263611 0.199556 +v -0.232354 0.262717 0.199503 +v -0.229994 0.261823 0.199464 +v -0.227603 0.260927 0.199436 +v -0.225182 0.260029 0.199417 +v -0.222731 0.259127 0.199405 +v -0.220251 0.258219 0.199399 +v -0.217743 0.257304 0.199397 +v -0.215207 0.256381 0.199397 +v -0.116829 0.220574 0.199397 +v -0.115343 0.225611 0.205644 +v -0.114028 0.230607 0.211775 +v -0.112914 0.235570 0.217787 +v -0.112030 0.240507 0.223676 +v -0.111407 0.245426 0.229438 +v -0.111074 0.250334 0.235071 +v -0.111060 0.255239 0.240568 +v -0.111396 0.260147 0.245929 +v -0.112110 0.265067 0.251147 +v -0.113233 0.270006 0.256220 +v -0.114794 0.274971 0.261145 +v -0.116822 0.279970 0.265916 +v -0.119048 0.284524 0.270109 +v -0.121717 0.289173 0.274227 +v -0.124803 0.293889 0.278250 +v -0.128283 0.298645 0.282159 +v -0.132130 0.303415 0.285933 +v -0.136319 0.308173 0.289553 +v -0.140826 0.312892 0.293001 +v -0.145624 0.317544 0.296255 +v -0.150689 0.322104 0.299297 +v -0.155995 0.326545 0.302108 +v -0.161517 0.330840 0.304666 +v -0.167230 0.334962 0.306954 +v -0.138649 0.337732 0.321706 +v -0.132615 0.332766 0.318605 +v -0.126820 0.327636 0.315221 +v -0.121293 0.322377 0.311585 +v -0.116058 0.317029 0.307729 +v -0.111143 0.311627 0.303683 +v -0.106573 0.306208 0.299478 +v -0.102377 0.300811 0.295144 +v -0.098580 0.295472 0.290712 +v -0.095209 0.290228 0.286213 +v -0.092291 0.285116 0.281678 +v -0.089851 0.280173 0.277137 +v -0.087918 0.275437 0.272622 +v -0.086241 0.270311 0.267565 +v -0.084936 0.265151 0.262317 +v -0.083989 0.259951 0.256880 +v -0.083387 0.254707 0.251253 +v -0.083119 0.249416 0.245436 +v -0.083172 0.244071 0.239429 +v -0.083533 0.238668 0.233232 +v -0.084190 0.233204 0.226845 +v -0.085129 0.227673 0.220268 +v -0.086339 0.222071 0.213501 +v -0.087807 0.216393 0.206544 +v -0.089520 0.210634 0.199397 +v -0.000025 0.178061 0.199397 +v 0.002002 0.177328 0.199402 +v 0.004121 0.176571 0.199418 +v 0.006311 0.175796 0.199443 +v 0.008552 0.175010 0.199476 +v 0.010822 0.174220 0.199517 +v 0.013101 0.173433 0.199565 +v 0.015368 0.172655 0.199617 +v 0.017602 0.171893 0.199675 +v 0.019783 0.171155 0.199736 +v 0.021888 0.170445 0.199800 +v 0.023898 0.169773 0.199866 +v 0.025792 0.169143 0.199933 +v 0.019480 0.151801 0.177939 +v 0.017503 0.152690 0.178129 +v 0.015420 0.153599 0.178298 +v 0.013256 0.154519 0.178446 +v 0.011035 0.155442 0.178575 +v 0.008781 0.156361 0.178685 +v 0.006519 0.157267 0.178777 +v 0.004272 0.158152 0.178853 +v 0.002065 0.159008 0.178913 +v -0.000077 0.159828 0.178957 +v -0.002131 0.160603 0.178988 +v -0.004072 0.161326 0.179006 +v -0.005876 0.161987 0.179012 +v 0.335514 -0.187407 -0.073118 +v 0.346172 -0.191802 -0.073694 +v 0.356193 -0.196979 -0.075407 +v 0.365463 -0.202874 -0.078231 +v 0.373870 -0.209423 -0.082138 +v 0.381302 -0.216561 -0.087103 +v 0.387646 -0.224225 -0.093100 +v 0.392790 -0.232351 -0.100103 +v 0.396620 -0.240873 -0.108086 +v 0.399026 -0.249729 -0.117022 +v 0.399894 -0.258853 -0.126886 +v 0.399111 -0.268181 -0.137652 +v 0.396566 -0.277649 -0.149293 +v 0.392410 -0.286592 -0.161001 +v 0.386995 -0.294292 -0.171832 +v 0.380447 -0.300774 -0.181760 +v 0.372894 -0.306060 -0.190758 +v 0.364465 -0.310172 -0.198798 +v 0.355287 -0.313132 -0.205854 +v 0.345487 -0.314962 -0.211899 +v 0.335193 -0.315686 -0.216905 +v 0.324534 -0.315325 -0.220845 +v 0.313636 -0.313902 -0.223694 +v 0.302628 -0.311439 -0.225422 +v 0.291637 -0.307958 -0.226005 +v 0.280980 -0.303559 -0.225422 +v 0.270964 -0.298370 -0.223694 +v 0.261701 -0.292455 -0.220845 +v 0.253303 -0.285880 -0.216905 +v 0.245883 -0.278709 -0.211899 +v 0.239553 -0.271008 -0.205854 +v 0.234424 -0.262841 -0.198798 +v 0.230610 -0.254273 -0.190758 +v 0.228222 -0.245369 -0.181760 +v 0.227372 -0.236195 -0.171832 +v 0.228174 -0.226814 -0.161001 +v 0.230738 -0.217293 -0.149293 +v 0.234875 -0.208404 -0.137652 +v 0.240271 -0.200755 -0.126886 +v 0.246801 -0.194323 -0.117022 +v 0.254336 -0.189086 -0.108086 +v 0.262749 -0.185020 -0.100103 +v 0.271912 -0.182102 -0.093100 +v 0.281698 -0.180308 -0.087103 +v 0.291980 -0.179617 -0.082138 +v 0.302630 -0.180004 -0.078231 +v 0.313520 -0.181447 -0.075407 +v 0.324524 -0.183923 -0.073694 +v 0.329663 -0.203481 -0.093502 +v 0.322019 -0.201107 -0.093960 +v 0.314580 -0.199602 -0.095307 +v 0.307395 -0.198950 -0.097505 +v 0.300512 -0.199133 -0.100516 +v 0.293978 -0.200136 -0.104302 +v 0.287840 -0.201940 -0.108825 +v 0.282145 -0.204530 -0.114046 +v 0.276942 -0.207888 -0.119927 +v 0.272279 -0.211998 -0.126431 +v 0.268201 -0.216843 -0.133519 +v 0.264757 -0.222406 -0.141152 +v 0.261995 -0.228670 -0.149293 +v 0.260082 -0.235252 -0.157444 +v 0.259136 -0.241750 -0.165107 +v 0.259132 -0.248117 -0.172238 +v 0.260047 -0.254307 -0.178797 +v 0.261856 -0.260273 -0.184742 +v 0.264535 -0.265970 -0.190029 +v 0.268058 -0.271350 -0.194618 +v 0.272401 -0.276367 -0.198467 +v 0.277540 -0.280976 -0.201533 +v 0.283451 -0.285129 -0.203776 +v 0.290108 -0.288781 -0.205152 +v 0.297487 -0.291885 -0.205620 +v 0.305141 -0.294253 -0.205152 +v 0.312606 -0.295741 -0.203776 +v 0.319830 -0.296368 -0.201533 +v 0.326763 -0.296153 -0.198467 +v 0.333354 -0.295116 -0.194618 +v 0.339552 -0.293274 -0.190029 +v 0.345306 -0.290646 -0.184742 +v 0.350566 -0.287253 -0.178797 +v 0.355279 -0.283112 -0.172238 +v 0.359397 -0.278242 -0.165107 +v 0.362866 -0.272663 -0.157444 +v 0.365638 -0.266393 -0.149293 +v 0.367542 -0.259816 -0.141152 +v 0.368462 -0.253335 -0.133519 +v 0.368426 -0.246993 -0.126431 +v 0.367461 -0.240834 -0.119927 +v 0.365595 -0.234903 -0.114046 +v 0.362857 -0.229244 -0.108825 +v 0.359274 -0.223902 -0.104302 +v 0.354874 -0.218920 -0.100516 +v 0.349685 -0.214342 -0.097505 +v 0.343735 -0.210214 -0.095307 +v 0.337052 -0.206579 -0.093960 +v -0.039587 -0.053995 -0.076604 +v -0.009646 -0.064893 -0.076604 +v -0.039975 -0.148221 -0.182284 +v -0.036921 -0.152541 -0.185878 +v -0.033831 -0.156587 -0.189149 +v -0.030706 -0.160360 -0.192100 +v -0.027547 -0.163860 -0.194732 +v -0.024357 -0.167088 -0.197047 +v -0.021138 -0.170047 -0.199048 +v -0.017890 -0.172736 -0.200736 +v -0.014616 -0.175157 -0.202113 +v -0.011317 -0.177311 -0.203180 +v -0.007995 -0.179199 -0.203941 +v -0.004651 -0.180822 -0.204396 +v -0.001288 -0.182181 -0.204547 +v 0.004205 -0.183964 -0.204304 +v 0.009338 -0.185173 -0.203566 +v 0.014122 -0.185799 -0.202317 +v 0.018567 -0.185833 -0.200543 +v 0.022682 -0.185265 -0.198229 +v 0.026478 -0.184084 -0.195360 +v 0.029964 -0.182282 -0.191921 +v 0.033151 -0.179849 -0.187897 +v 0.036049 -0.176775 -0.183273 +v 0.038667 -0.173050 -0.178035 +v 0.041016 -0.168665 -0.172167 +v 0.043105 -0.163610 -0.165654 +v 0.068661 -0.093395 -0.076604 +v 0.098603 -0.104292 -0.076604 +v 0.068274 -0.187621 -0.182284 +v 0.071390 -0.191964 -0.185878 +v 0.074509 -0.196020 -0.189149 +v 0.077636 -0.199793 -0.192100 +v 0.080775 -0.203286 -0.194732 +v 0.083932 -0.206502 -0.197047 +v 0.087111 -0.209446 -0.199048 +v 0.090319 -0.212121 -0.200736 +v 0.093560 -0.214530 -0.202113 +v 0.096840 -0.216677 -0.203180 +v 0.100163 -0.218565 -0.203941 +v 0.103535 -0.220199 -0.204396 +v 0.106961 -0.221581 -0.204547 +v 0.112454 -0.223363 -0.204304 +v 0.117587 -0.224572 -0.203566 +v 0.122371 -0.225199 -0.202317 +v 0.126815 -0.225232 -0.200543 +v 0.130931 -0.224664 -0.198229 +v 0.134727 -0.223484 -0.195360 +v 0.138213 -0.221682 -0.191921 +v 0.141400 -0.219248 -0.187897 +v 0.144298 -0.216174 -0.183273 +v 0.146916 -0.212449 -0.178035 +v 0.149265 -0.208065 -0.172167 +v 0.151354 -0.203010 -0.165654 +v 0.176910 -0.132794 -0.076604 +v 0.206852 -0.143692 -0.076604 +v 0.180371 -0.216445 -0.168873 +v 0.177437 -0.223375 -0.177829 +v 0.173979 -0.229457 -0.186051 +v 0.169995 -0.234685 -0.193529 +v 0.165479 -0.239048 -0.200255 +v 0.160428 -0.242537 -0.206222 +v 0.154836 -0.245143 -0.211420 +v 0.148699 -0.246858 -0.215841 +v 0.142013 -0.247671 -0.219478 +v 0.134773 -0.247575 -0.222321 +v 0.126975 -0.246559 -0.224362 +v 0.118614 -0.244615 -0.225593 +v 0.109686 -0.241734 -0.226005 +v 0.104386 -0.239593 -0.225768 +v 0.099330 -0.237134 -0.225074 +v 0.094504 -0.234370 -0.223947 +v 0.089892 -0.231318 -0.222408 +v 0.085479 -0.227992 -0.220483 +v 0.081247 -0.224407 -0.218193 +v 0.077182 -0.220578 -0.215562 +v 0.073267 -0.216520 -0.212613 +v 0.069487 -0.212249 -0.209371 +v 0.065826 -0.207779 -0.205857 +v 0.062267 -0.203125 -0.202095 +v 0.058797 -0.198302 -0.198109 +v 0.055634 -0.200861 -0.202264 +v 0.052220 -0.203076 -0.206136 +v 0.048543 -0.204929 -0.209710 +v 0.044588 -0.206401 -0.212971 +v 0.040343 -0.207475 -0.215904 +v 0.035796 -0.208133 -0.218494 +v 0.030933 -0.208357 -0.220727 +v 0.025742 -0.208129 -0.222587 +v 0.020210 -0.207430 -0.224060 +v 0.014324 -0.206244 -0.225130 +v 0.008071 -0.204551 -0.225784 +v 0.001438 -0.202334 -0.226005 +v -0.003790 -0.200231 -0.225780 +v -0.008781 -0.197830 -0.225125 +v -0.013543 -0.195153 -0.224068 +v -0.018081 -0.192223 -0.222637 +v -0.022400 -0.189063 -0.220859 +v -0.026508 -0.185696 -0.218763 +v -0.030408 -0.182145 -0.216376 +v -0.034107 -0.178433 -0.213726 +v -0.037611 -0.174582 -0.210842 +v -0.040926 -0.170615 -0.207751 +v -0.044056 -0.166556 -0.204481 +v -0.047009 -0.162427 -0.201060 +v -0.047996 -0.162068 -0.201060 +v -0.056709 -0.177817 -0.222249 +v -0.081386 -0.168836 -0.222249 +v -0.148810 -0.011128 -0.073118 +v -0.142871 -0.013412 -0.073254 +v -0.137219 -0.015825 -0.073653 +v -0.131843 -0.018355 -0.074295 +v -0.126731 -0.020991 -0.075164 +v -0.121871 -0.023723 -0.076241 +v -0.117250 -0.026537 -0.077510 +v -0.112858 -0.029423 -0.078951 +v -0.108681 -0.032369 -0.080548 +v -0.104709 -0.035364 -0.082283 +v -0.100928 -0.038397 -0.084138 +v -0.097328 -0.041455 -0.086096 +v -0.093896 -0.044528 -0.088138 +v -0.109373 -0.053265 -0.104231 +v -0.112183 -0.050681 -0.102483 +v -0.115079 -0.048180 -0.100862 +v -0.118070 -0.045762 -0.099374 +v -0.121166 -0.043429 -0.098023 +v -0.124375 -0.041180 -0.096813 +v -0.127708 -0.039017 -0.095749 +v -0.131173 -0.036941 -0.094836 +v -0.134779 -0.034952 -0.094079 +v -0.138537 -0.033051 -0.093482 +v -0.142455 -0.031239 -0.093049 +v -0.146543 -0.029516 -0.092786 +v -0.150810 -0.027884 -0.092698 +v -0.159174 -0.025205 -0.093106 +v -0.167290 -0.023327 -0.094312 +v -0.175113 -0.022242 -0.096285 +v -0.182595 -0.021939 -0.098996 +v -0.189691 -0.022409 -0.102415 +v -0.196355 -0.023642 -0.106511 +v -0.202539 -0.025628 -0.111256 +v -0.208199 -0.028357 -0.116619 +v -0.213287 -0.031820 -0.122571 +v -0.217757 -0.036007 -0.129082 +v -0.221563 -0.040907 -0.136121 +v -0.224660 -0.046512 -0.143660 +v -0.104237 -0.090342 -0.143660 +v -0.104332 -0.091115 -0.144565 +v -0.104448 -0.091937 -0.145532 +v -0.104585 -0.092802 -0.146556 +v -0.104744 -0.093706 -0.147634 +v -0.104926 -0.094646 -0.148760 +v -0.105132 -0.095615 -0.149930 +v -0.105362 -0.096611 -0.151139 +v -0.105619 -0.097628 -0.152382 +v -0.105903 -0.098662 -0.153656 +v -0.106214 -0.099708 -0.154954 +v -0.106554 -0.100762 -0.156273 +v -0.106924 -0.101819 -0.157608 +v -0.110348 -0.109573 -0.167687 +v -0.114632 -0.116428 -0.177110 +v -0.119744 -0.122358 -0.185834 +v -0.125651 -0.127337 -0.193818 +v -0.132321 -0.131340 -0.201019 +v -0.139720 -0.134341 -0.207397 +v -0.147817 -0.136315 -0.212908 +v -0.156579 -0.137237 -0.217511 +v -0.165973 -0.137079 -0.221164 +v -0.175966 -0.135818 -0.223825 +v -0.186527 -0.133428 -0.225453 +v -0.197622 -0.129883 -0.226005 +v -0.207743 -0.125656 -0.225397 +v -0.217298 -0.120574 -0.223601 +v -0.226172 -0.114716 -0.220657 +v -0.234249 -0.108159 -0.216607 +v -0.241413 -0.100984 -0.211491 +v -0.247547 -0.093269 -0.205351 +v -0.252534 -0.085093 -0.198228 +v -0.256260 -0.076534 -0.190162 +v -0.258607 -0.067673 -0.181195 +v -0.259460 -0.058586 -0.171367 +v -0.258702 -0.049354 -0.160719 +v -0.256217 -0.040056 -0.149293 +v -0.252114 -0.031205 -0.137708 +v -0.246767 -0.023570 -0.126979 +v -0.240285 -0.017140 -0.117135 +v -0.232776 -0.011898 -0.108205 +v -0.224349 -0.007833 -0.100217 +v -0.215114 -0.004929 -0.093201 +v -0.205178 -0.003173 -0.087185 +v -0.194652 -0.002551 -0.082197 +v -0.183643 -0.003049 -0.078268 +v -0.172260 -0.004654 -0.075426 +v -0.160613 -0.007352 -0.073699 +v -0.229992 -0.060139 -0.161095 +v -0.230692 -0.066065 -0.168016 +v -0.230516 -0.071845 -0.174418 +v -0.229516 -0.077449 -0.180285 +v -0.227740 -0.082843 -0.185602 +v -0.225240 -0.087996 -0.190353 +v -0.222065 -0.092873 -0.194522 +v -0.218266 -0.097445 -0.198093 +v -0.213894 -0.101677 -0.201050 +v -0.208998 -0.105537 -0.203377 +v -0.203630 -0.108993 -0.205060 +v -0.197838 -0.112013 -0.206080 +v -0.191674 -0.114563 -0.206424 +v -0.184830 -0.116761 -0.206096 +v -0.178297 -0.118263 -0.205115 +v -0.172093 -0.119071 -0.203491 +v -0.166237 -0.119182 -0.201229 +v -0.160749 -0.118598 -0.198337 +v -0.155648 -0.117317 -0.194824 +v -0.150953 -0.115339 -0.190695 +v -0.146683 -0.112665 -0.185960 +v -0.142859 -0.109293 -0.180625 +v -0.139498 -0.105223 -0.174697 +v -0.136621 -0.100455 -0.168185 +v -0.134246 -0.094988 -0.161095 +v -0.445274 0.093662 -0.076604 +v -0.383418 0.071149 -0.076604 +v -0.366146 0.064185 -0.077363 +v -0.350698 0.056552 -0.079614 +v -0.337086 0.048290 -0.083318 +v -0.325322 0.039439 -0.088436 +v -0.315420 0.030037 -0.094928 +v -0.307392 0.020125 -0.102756 +v -0.301251 0.009743 -0.111880 +v -0.297009 -0.001071 -0.122262 +v -0.294680 -0.012277 -0.133862 +v -0.294277 -0.023835 -0.146640 +v -0.295811 -0.035705 -0.160559 +v -0.299296 -0.047848 -0.175579 +v -0.304441 -0.059414 -0.190628 +v -0.310891 -0.069463 -0.204511 +v -0.318618 -0.077981 -0.217199 +v -0.327595 -0.084954 -0.228667 +v -0.337795 -0.090367 -0.238887 +v -0.349191 -0.094206 -0.247831 +v -0.361756 -0.096457 -0.255474 +v -0.375462 -0.097106 -0.261787 +v -0.390282 -0.096139 -0.266745 +v -0.406190 -0.093541 -0.270320 +v -0.423158 -0.089298 -0.272484 +v -0.441158 -0.083396 -0.273212 +v -0.501698 -0.061362 -0.273212 +v -0.420525 0.066452 -0.096989 +v -0.465326 -0.056637 -0.253095 +v -0.438017 -0.066576 -0.253095 +v -0.424225 -0.071085 -0.252523 +v -0.411311 -0.074263 -0.250818 +v -0.399277 -0.076126 -0.247999 +v -0.388124 -0.076690 -0.244085 +v -0.377856 -0.075971 -0.239094 +v -0.368473 -0.073985 -0.233045 +v -0.359978 -0.070748 -0.225957 +v -0.352372 -0.066275 -0.217849 +v -0.345658 -0.060583 -0.208738 +v -0.339837 -0.053688 -0.198643 +v -0.334911 -0.045606 -0.187584 +v -0.330882 -0.036352 -0.175579 +v -0.328030 -0.026701 -0.163608 +v -0.326602 -0.017326 -0.152528 +v -0.326609 -0.008249 -0.142365 +v -0.328064 0.000509 -0.133150 +v -0.330978 0.008927 -0.124910 +v -0.335363 0.016983 -0.117676 +v -0.341231 0.024656 -0.111475 +v -0.348593 0.031923 -0.106337 +v -0.357460 0.038764 -0.102291 +v -0.367846 0.045157 -0.099365 +v -0.379760 0.051080 -0.097588 +v -0.393216 0.056512 -0.096989 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vn 0.2620 0.7198 -0.6428 +vn 0.2620 0.7199 -0.6428 +vn 0.2607 0.7197 -0.6435 +vn 0.2633 0.7197 -0.6425 +vn 0.2618 0.7205 -0.6421 +vn 0.2627 0.7189 -0.6436 +vn 0.2620 0.7199 -0.6427 +vn 0.2619 0.7199 -0.6428 +vn 0.2621 0.7198 -0.6428 +vn 0.2621 0.7199 -0.6427 +vn 0.2620 0.7198 -0.6429 +vn 0.2619 0.7198 -0.6429 +vn 0.2620 0.7197 -0.6429 +vn 0.2625 0.7198 -0.6427 +vn 0.2620 0.7196 -0.6430 +vn 0.2620 0.7200 -0.6427 +vn 0.2621 0.7198 -0.6427 +vn 0.2617 0.7193 -0.6435 +s off +f 68/1/1 66/2/1 67/3/1 +f 43/4/1 41/5/1 42/6/1 +f 68/1/1 65/7/1 66/2/1 +f 44/8/2 41/5/2 43/4/2 +f 68/1/1 64/9/1 65/7/1 +f 45/10/1 41/5/1 44/8/1 +f 68/1/1 63/11/1 64/9/1 +f 46/12/1 41/5/1 45/10/1 +f 68/1/1 62/13/1 63/11/1 +f 47/14/2 41/5/2 46/12/2 +f 68/1/1 61/15/1 62/13/1 +f 48/16/2 41/5/2 47/14/2 +f 68/1/1 60/17/1 61/15/1 +f 49/18/1 41/5/1 48/16/1 +f 68/1/1 59/19/1 60/17/1 +f 50/20/1 41/5/1 49/18/1 +f 68/1/1 58/21/1 59/19/1 +f 51/22/2 41/5/2 50/20/2 +f 68/1/1 57/23/1 58/21/1 +f 52/24/1 41/5/1 51/22/1 +f 68/1/1 56/25/1 57/23/1 +f 53/26/1 41/5/1 52/24/1 +f 68/1/1 55/27/1 56/25/1 +f 54/28/1 41/5/1 53/26/1 +f 68/1/1 54/28/1 55/27/1 +f 68/1/2 69/29/2 54/28/2 +f 69/29/2 70/30/2 54/28/2 +f 70/30/1 71/31/1 54/28/1 +f 71/31/1 72/32/1 54/28/1 +f 72/32/2 73/33/2 54/28/2 +f 73/33/1 74/34/1 54/28/1 +f 74/34/1 75/35/1 54/28/1 +f 75/35/2 76/36/2 54/28/2 +f 76/36/1 77/37/1 54/28/1 +f 77/37/2 78/38/2 54/28/2 +f 78/38/2 79/39/2 54/28/2 +f 79/39/1 80/40/1 54/28/1 +f 80/40/1 81/41/1 54/28/1 +f 81/41/1 28/42/1 54/28/1 +f 28/42/1 29/43/1 54/28/1 +f 29/43/2 30/44/2 54/28/2 +f 30/44/1 31/45/1 54/28/1 +f 31/45/1 32/46/1 54/28/1 +f 32/46/2 33/47/2 54/28/2 +f 33/47/2 34/48/2 54/28/2 +f 34/48/1 35/49/1 54/28/1 +f 35/49/1 36/50/1 54/28/1 +f 36/50/1 41/5/1 54/28/1 +f 82/51/1 28/42/1 81/41/1 +f 82/51/1 27/52/1 28/42/1 +f 37/53/3 41/5/3 36/50/3 +f 38/54/4 41/5/4 37/53/4 +f 39/55/5 41/5/5 38/54/5 +f 40/56/6 41/5/6 39/55/6 +f 96/57/1 94/58/1 95/59/1 +f 96/57/1 93/60/1 94/58/1 +f 15/61/2 13/62/2 14/63/2 +f 96/57/1 92/64/1 93/60/1 +f 16/65/1 13/62/1 15/61/1 +f 96/57/1 91/66/1 92/64/1 +f 17/67/1 13/62/1 16/65/1 +f 96/57/1 90/68/1 91/66/1 +f 18/69/1 13/62/1 17/67/1 +f 96/57/1 89/70/1 90/68/1 +f 19/71/1 13/62/1 18/69/1 +f 96/57/1 88/72/1 89/70/1 +f 20/73/1 13/62/1 19/71/1 +f 96/57/1 87/74/1 88/72/1 +f 21/75/2 13/62/2 20/73/2 +f 22/76/1 13/62/1 21/75/1 +f 96/57/2 86/77/2 87/74/2 +f 23/78/1 13/62/1 22/76/1 +f 96/57/1 85/79/1 86/77/1 +f 24/80/2 13/62/2 23/78/2 +f 96/57/1 84/81/1 85/79/1 +f 25/82/2 13/62/2 24/80/2 +f 96/57/2 83/83/2 84/81/2 +f 26/84/1 13/62/1 25/82/1 +f 96/57/1 82/51/1 83/83/1 +f 96/57/1 27/52/1 82/51/1 +f 96/57/1 26/84/1 27/52/1 +f 96/57/7 97/85/7 26/84/7 +f 97/85/8 98/86/8 26/84/8 +f 98/86/9 99/87/9 26/84/9 +f 99/87/2 100/88/2 26/84/2 +f 100/88/10 101/89/10 26/84/10 +f 101/89/11 102/90/11 26/84/11 +f 102/90/1 103/91/1 26/84/1 +f 103/91/1 104/92/1 26/84/1 +f 104/92/2 105/93/2 26/84/2 +f 105/93/1 106/94/1 26/84/1 +f 106/94/10 107/95/10 26/84/10 +f 107/95/1 108/96/1 26/84/1 +f 108/96/1 109/97/1 26/84/1 +f 109/97/1 160/98/1 26/84/1 +f 160/98/1 1/99/1 26/84/1 +f 1/99/1 2/100/1 26/84/1 +f 2/100/2 3/101/2 26/84/2 +f 3/101/1 4/102/1 26/84/1 +f 4/102/1 5/103/1 26/84/1 +f 5/103/2 6/104/2 26/84/2 +f 6/104/1 7/105/1 26/84/1 +f 7/105/1 8/106/1 26/84/1 +f 8/106/1 9/107/1 26/84/1 +f 9/107/1 10/108/1 26/84/1 +f 10/108/1 11/109/1 26/84/1 +f 11/109/1 12/110/1 26/84/1 +f 12/110/2 13/62/2 26/84/2 +f 110/111/1 160/98/1 109/97/1 +f 110/111/1 159/112/1 160/98/1 +f 110/111/1 158/113/1 159/112/1 +f 110/111/1 157/114/1 158/113/1 +f 110/111/1 156/115/1 157/114/1 +f 111/116/1 156/115/1 110/111/1 +f 111/116/1 155/117/1 156/115/1 +f 111/116/1 154/118/1 155/117/1 +f 112/119/1 154/118/1 111/116/1 +f 112/119/1 153/120/1 154/118/1 +f 112/119/1 152/121/1 153/120/1 +f 113/122/2 152/121/2 112/119/2 +f 113/122/1 151/123/1 152/121/1 +f 136/124/2 134/125/2 135/126/2 +f 137/127/1 134/125/1 136/124/1 +f 113/122/2 150/128/2 151/123/2 +f 138/129/1 134/125/1 137/127/1 +f 139/130/1 134/125/1 138/129/1 +f 140/131/1 134/125/1 139/130/1 +f 113/122/1 149/132/1 150/128/1 +f 141/133/2 134/125/2 140/131/2 +f 142/134/1 134/125/1 141/133/1 +f 113/122/2 148/135/2 149/132/2 +f 143/136/1 134/125/1 142/134/1 +f 144/137/1 134/125/1 143/136/1 +f 145/138/2 134/125/2 144/137/2 +f 113/122/1 147/139/1 148/135/1 +f 146/140/1 134/125/1 145/138/1 +f 147/139/1 134/125/1 146/140/1 +f 113/122/1 134/125/1 147/139/1 +f 114/141/1 134/125/1 113/122/1 +f 115/142/1 134/125/1 114/141/1 +f 116/143/1 134/125/1 115/142/1 +f 117/144/1 134/125/1 116/143/1 +f 118/145/1 134/125/1 117/144/1 +f 119/146/1 134/125/1 118/145/1 +f 119/146/2 133/147/2 134/125/2 +f 120/148/2 133/147/2 119/146/2 +f 120/148/12 132/149/12 133/147/12 +f 120/148/7 131/150/7 132/149/7 +f 120/148/1 130/151/1 131/150/1 +f 120/148/2 129/152/2 130/151/2 +f 121/153/1 129/152/1 120/148/1 +f 121/153/9 128/154/9 129/152/9 +f 121/153/1 127/155/1 128/154/1 +f 121/153/1 126/156/1 127/155/1 +f 121/153/7 125/157/7 126/156/7 +f 122/158/2 125/157/2 121/153/2 +f 122/158/13 124/159/13 125/157/13 +f 122/158/14 123/160/14 124/159/14 +f 278/161/1 276/162/1 277/163/1 +f 355/164/1 353/165/1 354/166/1 +f 278/161/1 275/167/1 276/162/1 +f 356/168/1 353/165/1 355/164/1 +f 278/161/1 274/169/1 275/167/1 +f 357/170/1 353/165/1 356/168/1 +f 278/161/1 273/171/1 274/169/1 +f 358/172/1 353/165/1 357/170/1 +f 278/161/1 272/173/1 273/171/1 +f 278/161/1 271/174/1 272/173/1 +f 359/175/1 353/165/1 358/172/1 +f 278/161/1 270/176/1 271/174/1 +f 360/177/1 353/165/1 359/175/1 +f 278/161/1 269/178/1 270/176/1 +f 361/179/2 353/165/2 360/177/2 +f 362/180/1 353/165/1 361/179/1 +f 278/161/1 268/181/1 269/178/1 +f 363/182/2 353/165/2 362/180/2 +f 278/161/1 267/183/1 268/181/1 +f 364/184/1 353/165/1 363/182/1 +f 278/161/1 266/185/1 267/183/1 +f 365/186/1 353/165/1 364/184/1 +f 278/161/1 265/187/1 266/185/1 +f 366/188/2 353/165/2 365/186/2 +f 278/161/1 366/188/1 265/187/1 +f 278/161/10 279/189/10 366/188/10 +f 279/189/15 280/190/15 366/188/15 +f 280/190/16 281/191/16 366/188/16 +f 281/191/9 282/192/9 366/188/9 +f 282/192/1 283/193/1 366/188/1 +f 283/193/1 284/194/1 366/188/1 +f 284/194/1 285/195/1 366/188/1 +f 285/195/10 286/196/10 366/188/10 +f 286/196/1 287/197/1 366/188/1 +f 287/197/2 288/198/2 366/188/2 +f 288/198/1 289/199/1 366/188/1 +f 289/199/7 290/200/7 366/188/7 +f 290/200/1 291/201/1 366/188/1 +f 291/201/1 340/202/1 366/188/1 +f 340/202/1 341/203/1 366/188/1 +f 341/203/1 342/204/1 366/188/1 +f 342/204/1 343/205/1 366/188/1 +f 343/205/1 344/206/1 366/188/1 +f 344/206/1 345/207/1 366/188/1 +f 345/207/1 346/208/1 366/188/1 +f 346/208/1 347/209/1 366/188/1 +f 347/209/1 348/210/1 366/188/1 +f 348/210/1 349/211/1 366/188/1 +f 349/211/1 350/212/1 366/188/1 +f 350/212/2 351/213/2 366/188/2 +f 351/213/1 352/214/1 366/188/1 +f 352/214/1 353/165/1 366/188/1 +f 292/215/1 340/202/1 291/201/1 +f 292/215/1 339/216/1 340/202/1 +f 293/217/1 339/216/1 292/215/1 +f 293/217/1 338/218/1 339/216/1 +f 294/219/1 338/218/1 293/217/1 +f 294/219/1 337/220/1 338/218/1 +f 295/221/1 337/220/1 294/219/1 +f 295/221/1 336/222/1 337/220/1 +f 296/223/1 336/222/1 295/221/1 +f 296/223/1 335/224/1 336/222/1 +f 297/225/1 335/224/1 296/223/1 +f 297/225/1 334/226/1 335/224/1 +f 298/227/1 334/226/1 297/225/1 +f 298/227/1 333/228/1 334/226/1 +f 299/229/1 333/228/1 298/227/1 +f 299/229/1 332/230/1 333/228/1 +f 300/231/1 332/230/1 299/229/1 +f 301/232/1 332/230/1 300/231/1 +f 301/232/1 331/233/1 332/230/1 +f 302/234/1 331/233/1 301/232/1 +f 302/234/1 330/235/1 331/233/1 +f 303/236/1 330/235/1 302/234/1 +f 303/236/2 329/237/2 330/235/2 +f 304/238/1 329/237/1 303/236/1 +f 304/238/1 328/239/1 329/237/1 +f 305/240/1 328/239/1 304/238/1 +f 305/240/1 327/241/1 328/239/1 +f 306/242/1 327/241/1 305/240/1 +f 306/242/1 326/243/1 327/241/1 +f 307/244/1 326/243/1 306/242/1 +f 307/244/2 325/245/2 326/243/2 +f 308/246/1 325/245/1 307/244/1 +f 309/247/1 325/245/1 308/246/1 +f 309/247/1 324/248/1 325/245/1 +f 310/249/1 324/248/1 309/247/1 +f 310/249/2 323/250/2 324/248/2 +f 311/251/1 323/250/1 310/249/1 +f 311/251/1 322/252/1 323/250/1 +f 312/253/1 322/252/1 311/251/1 +f 313/254/2 322/252/2 312/253/2 +f 313/254/1 321/255/1 322/252/1 +f 314/256/1 321/255/1 313/254/1 +f 314/256/1 320/257/1 321/255/1 +f 315/258/1 320/257/1 314/256/1 +f 316/259/1 320/257/1 315/258/1 +f 316/259/2 319/260/2 320/257/2 +f 316/259/1 318/261/1 319/260/1 +f 316/259/17 317/262/17 318/261/17 +f 239/263/1 263/264/1 264/265/1 +f 239/263/1 262/266/1 263/264/1 +f 239/263/1 261/267/1 262/266/1 +f 240/268/1 261/267/1 239/263/1 +f 240/268/1 260/269/1 261/267/1 +f 241/270/1 260/269/1 240/268/1 +f 174/271/1 172/272/1 173/273/1 +f 242/274/1 260/269/1 241/270/1 +f 242/274/1 259/275/1 260/269/1 +f 174/271/1 171/276/1 172/272/1 +f 243/277/1 259/275/1 242/274/1 +f 243/277/1 258/278/1 259/275/1 +f 174/271/1 170/279/1 171/276/1 +f 175/280/1 170/279/1 174/271/1 +f 244/281/1 258/278/1 243/277/1 +f 244/281/1 257/282/1 258/278/1 +f 175/280/1 169/283/1 170/279/1 +f 176/284/1 169/283/1 175/280/1 +f 245/285/1 257/282/1 244/281/1 +f 245/285/1 256/286/1 257/282/1 +f 176/284/1 168/287/1 169/283/1 +f 177/288/1 168/287/1 176/284/1 +f 246/289/1 256/286/1 245/285/1 +f 246/289/1 255/290/1 256/286/1 +f 177/288/1 167/291/1 168/287/1 +f 178/292/1 167/291/1 177/288/1 +f 247/293/1 255/290/1 246/289/1 +f 247/293/1 254/294/1 255/290/1 +f 179/295/1 167/291/1 178/292/1 +f 179/295/1 166/296/1 167/291/1 +f 248/297/1 254/294/1 247/293/1 +f 248/297/1 253/298/1 254/294/1 +f 180/299/1 166/296/1 179/295/1 +f 180/299/1 165/300/1 166/296/1 +f 226/301/1 224/302/1 225/303/1 +f 201/304/1 199/305/1 200/306/1 +f 226/301/1 223/307/1 224/302/1 +f 202/308/1 199/305/1 201/304/1 +f 226/301/1 222/309/1 223/307/1 +f 203/310/1 199/305/1 202/308/1 +f 226/301/2 221/311/2 222/309/2 +f 204/312/1 199/305/1 203/310/1 +f 226/301/1 220/313/1 221/311/1 +f 205/314/1 199/305/1 204/312/1 +f 226/301/1 219/315/1 220/313/1 +f 206/316/1 199/305/1 205/314/1 +f 226/301/1 218/317/1 219/315/1 +f 249/318/1 253/298/1 248/297/1 +f 207/319/1 199/305/1 206/316/1 +f 226/301/1 217/320/1 218/317/1 +f 208/321/1 199/305/1 207/319/1 +f 226/301/1 216/322/1 217/320/1 +f 249/318/1 252/323/1 253/298/1 +f 209/324/1 199/305/1 208/321/1 +f 226/301/2 215/325/2 216/322/2 +f 210/326/2 199/305/2 209/324/2 +f 226/301/1 214/327/1 215/325/1 +f 211/328/1 199/305/1 210/326/1 +f 226/301/1 213/329/1 214/327/1 +f 212/330/1 199/305/1 211/328/1 +f 226/301/1 212/330/1 213/329/1 +f 226/301/1 227/331/1 212/330/1 +f 227/331/7 228/332/7 212/330/7 +f 228/332/1 229/333/1 212/330/1 +f 229/333/7 230/334/7 212/330/7 +f 230/334/1 231/335/1 212/330/1 +f 231/335/2 232/336/2 212/330/2 +f 232/336/1 233/337/1 212/330/1 +f 233/337/2 234/338/2 212/330/2 +f 234/338/1 235/339/1 212/330/1 +f 235/339/2 236/340/2 212/330/2 +f 236/340/1 237/341/1 212/330/1 +f 237/341/7 238/342/7 212/330/7 +f 238/342/1 187/343/1 212/330/1 +f 187/343/1 188/344/1 212/330/1 +f 188/344/1 189/345/1 212/330/1 +f 189/345/1 190/346/1 212/330/1 +f 190/346/1 191/347/1 212/330/1 +f 191/347/1 192/348/1 212/330/1 +f 192/348/1 193/349/1 212/330/1 +f 193/349/1 194/350/1 212/330/1 +f 194/350/2 195/351/2 212/330/2 +f 195/351/1 196/352/1 212/330/1 +f 196/352/1 197/353/1 212/330/1 +f 197/353/2 198/354/2 212/330/2 +f 198/354/1 199/305/1 212/330/1 +f 181/355/1 165/300/1 180/299/1 +f 181/355/1 164/356/1 165/300/1 +f 249/318/1 250/357/1 252/323/1 +f 250/357/1 251/358/1 252/323/1 +f 182/359/1 164/356/1 181/355/1 +f 182/359/1 163/360/1 164/356/1 +f 182/359/1 162/361/1 163/360/1 +f 183/362/1 162/361/1 182/359/1 +f 183/362/1 161/363/1 162/361/1 +f 184/364/1 161/363/1 183/362/1 +f 184/364/1 185/365/1 161/363/1 +f 185/365/1 186/366/1 161/363/1 +f 392/367/1 390/368/1 391/369/1 +f 393/370/1 390/368/1 392/367/1 +f 393/370/2 389/371/2 390/368/2 +f 394/372/1 389/371/1 393/370/1 +f 394/372/1 388/373/1 389/371/1 +f 395/374/1 388/373/1 394/372/1 +f 395/374/2 387/375/2 388/373/2 +f 396/376/1 387/375/1 395/374/1 +f 396/376/1 386/377/1 387/375/1 +f 397/378/1 386/377/1 396/376/1 +f 397/378/1 385/379/1 386/377/1 +f 398/380/1 438/381/1 397/378/1 +f 438/381/2 439/382/2 397/378/2 +f 439/382/13 385/379/13 397/378/13 +f 439/382/2 440/383/2 385/379/2 +f 440/383/1 384/384/1 385/379/1 +f 441/385/7 384/384/7 440/383/7 +f 398/380/1 437/386/1 438/381/1 +f 442/387/1 384/384/1 441/385/1 +f 398/380/2 436/388/2 437/386/2 +f 443/389/1 384/384/1 442/387/1 +f 398/380/1 435/390/1 436/388/1 +f 399/391/1 435/390/1 398/380/1 +f 443/389/1 383/392/1 384/384/1 +f 444/393/2 383/392/2 443/389/2 +f 399/391/1 434/394/1 435/390/1 +f 445/395/1 383/392/1 444/393/1 +f 399/391/1 433/396/1 434/394/1 +f 400/397/1 433/396/1 399/391/1 +f 445/395/1 382/398/1 383/392/1 +f 446/399/1 382/398/1 445/395/1 +f 400/397/1 432/400/1 433/396/1 +f 447/401/1 382/398/1 446/399/1 +f 400/397/2 431/402/2 432/400/2 +f 401/403/1 431/402/1 400/397/1 +f 447/401/1 381/404/1 382/398/1 +f 448/405/1 381/404/1 447/401/1 +f 401/403/1 430/406/1 431/402/1 +f 449/407/1 381/404/1 448/405/1 +f 401/403/1 429/408/1 430/406/1 +f 402/409/1 429/408/1 401/403/1 +f 449/407/1 380/410/1 381/404/1 +f 450/411/1 380/410/1 449/407/1 +f 402/409/1 428/412/1 429/408/1 +f 403/413/1 428/412/1 402/409/1 +f 450/411/1 379/414/1 380/410/1 +f 451/415/1 379/414/1 450/411/1 +f 403/413/1 427/416/1 428/412/1 +f 404/417/1 427/416/1 403/413/1 +f 404/417/1 426/418/1 427/416/1 +f 452/419/1 379/414/1 451/415/1 +f 452/419/1 378/420/1 379/414/1 +f 453/421/1 378/420/1 452/419/1 +f 404/417/1 425/422/1 426/418/1 +f 405/423/1 425/422/1 404/417/1 +f 453/421/1 377/424/1 378/420/1 +f 454/425/1 377/424/1 453/421/1 +f 405/423/1 424/426/1 425/422/1 +f 406/427/1 424/426/1 405/423/1 +f 454/425/1 376/428/1 377/424/1 +f 455/429/1 376/428/1 454/425/1 +f 406/427/1 423/430/1 424/426/1 +f 406/427/1 422/431/1 423/430/1 +f 456/432/1 376/428/1 455/429/1 +f 407/433/1 422/431/1 406/427/1 +f 456/432/1 375/434/1 376/428/1 +f 407/433/1 421/435/1 422/431/1 +f 457/436/1 375/434/1 456/432/1 +f 407/433/1 420/437/1 421/435/1 +f 458/438/1 375/434/1 457/436/1 +f 408/439/1 420/437/1 407/433/1 +f 458/438/1 374/440/1 375/434/1 +f 408/439/1 419/441/1 420/437/1 +f 459/442/1 374/440/1 458/438/1 +f 408/439/1 418/443/1 419/441/1 +f 460/444/1 374/440/1 459/442/1 +f 409/445/1 418/443/1 408/439/1 +f 460/444/1 373/446/1 374/440/1 +f 409/445/1 417/447/1 418/443/1 +f 461/448/1 373/446/1 460/444/1 +f 462/449/1 373/446/1 461/448/1 +f 409/445/2 416/450/2 417/447/2 +f 415/451/1 373/446/1 462/449/1 +f 409/445/2 415/451/2 416/450/2 +f 409/445/2 373/446/2 415/451/2 +f 409/445/1 372/452/1 373/446/1 +f 410/453/1 372/452/1 409/445/1 +f 410/453/1 371/454/1 372/452/1 +f 411/455/1 371/454/1 410/453/1 +f 412/456/1 371/454/1 411/455/1 +f 412/456/1 370/457/1 371/454/1 +f 413/458/1 370/457/1 412/456/1 +f 413/458/1 369/459/1 370/457/1 +f 414/460/1 369/459/1 413/458/1 +f 414/460/1 368/461/1 369/459/1 +f 367/462/2 368/461/2 414/460/2 +f 556/463/1 554/464/1 555/465/1 +f 532/466/1 530/467/1 531/468/1 +f 556/463/2 553/469/2 554/464/2 +f 557/470/2 553/469/2 556/463/2 +f 533/471/1 530/467/1 532/466/1 +f 533/471/1 529/472/1 530/467/1 +f 557/470/1 552/473/1 553/469/1 +f 558/474/1 552/473/1 557/470/1 +f 534/475/1 529/472/1 533/471/1 +f 534/475/1 528/476/1 529/472/1 +f 559/477/1 552/473/1 558/474/1 +f 559/477/2 551/478/2 552/473/2 +f 535/479/2 528/476/2 534/475/2 +f 560/480/1 551/478/1 559/477/1 +f 560/480/1 550/481/1 551/478/1 +f 536/482/1 528/476/1 535/479/1 +f 536/482/1 527/483/1 528/476/1 +f 463/484/1 569/485/1 570/486/1 +f 463/484/1 568/487/1 569/485/1 +f 561/488/1 550/481/1 560/480/1 +f 561/488/1 549/489/1 550/481/1 +f 537/490/1 527/483/1 536/482/1 +f 537/490/1 526/491/1 527/483/1 +f 562/492/1 549/489/1 561/488/1 +f 562/492/1 548/493/1 549/489/1 +f 538/494/1 526/491/1 537/490/1 +f 563/495/2 548/493/2 562/492/2 +f 563/495/1 547/496/1 548/493/1 +f 538/494/1 525/497/1 526/491/1 +f 539/498/1 525/497/1 538/494/1 +f 564/499/1 547/496/1 563/495/1 +f 564/499/1 546/500/1 547/496/1 +f 540/501/1 525/497/1 539/498/1 +f 540/501/1 524/502/1 525/497/1 +f 565/503/1 546/500/1 564/499/1 +f 565/503/1 545/504/1 546/500/1 +f 541/505/1 524/502/1 540/501/1 +f 566/506/1 545/504/1 565/503/1 +f 541/505/1 504/507/1 524/502/1 +f 504/507/1 505/508/1 524/502/1 +f 505/508/1 523/509/1 524/502/1 +f 566/506/2 477/510/2 545/504/2 +f 477/510/1 544/511/1 545/504/1 +f 542/512/1 503/513/1 541/505/1 +f 503/513/7 504/507/7 541/505/7 +f 566/506/7 476/514/7 477/510/7 +f 478/515/18 544/511/18 477/510/18 +f 567/516/1 476/514/1 566/506/1 +f 567/516/1 475/517/1 476/514/1 +f 542/512/1 502/518/1 503/513/1 +f 479/519/1 544/511/1 478/515/1 +f 506/520/1 523/509/1 505/508/1 +f 567/516/2 474/521/2 475/517/2 +f 542/512/1 501/522/1 502/518/1 +f 480/523/2 544/511/2 479/519/2 +f 507/524/2 523/509/2 506/520/2 +f 567/516/1 473/525/1 474/521/1 +f 542/512/2 500/526/2 501/522/2 +f 481/527/1 544/511/1 480/523/1 +f 508/528/1 523/509/1 507/524/1 +f 481/527/1 543/529/1 544/511/1 +f 567/516/1 472/530/1 473/525/1 +f 542/512/1 499/531/1 500/526/1 +f 543/529/1 499/531/1 542/512/1 +f 463/484/1 567/516/1 568/487/1 +f 463/484/1 465/532/1 567/516/1 +f 465/532/1 466/533/1 567/516/1 +f 466/533/1 467/534/1 567/516/1 +f 467/534/1 468/535/1 567/516/1 +f 468/535/1 469/536/1 567/516/1 +f 469/536/1 470/537/1 567/516/1 +f 470/537/1 471/538/1 567/516/1 +f 471/538/2 472/530/2 567/516/2 +f 543/529/1 498/539/1 499/531/1 +f 482/540/1 543/529/1 481/527/1 +f 509/541/1 523/509/1 508/528/1 +f 509/541/1 522/542/1 523/509/1 +f 543/529/1 497/543/1 498/539/1 +f 483/544/1 543/529/1 482/540/1 +f 510/545/1 522/542/1 509/541/1 +f 483/544/1 497/543/1 543/529/1 +f 483/544/1 496/546/1 497/543/1 +f 484/547/1 496/546/1 483/544/1 +f 511/548/1 522/542/1 510/545/1 +f 484/547/2 495/549/2 496/546/2 +f 511/548/1 521/550/1 522/542/1 +f 484/547/1 494/551/1 495/549/1 +f 485/552/1 494/551/1 484/547/1 +f 512/553/1 521/550/1 511/548/1 +f 485/552/1 493/554/1 494/551/1 +f 486/555/1 493/554/1 485/552/1 +f 513/556/1 521/550/1 512/553/1 +f 513/556/1 520/557/1 521/550/1 +f 486/555/1 492/558/1 493/554/1 +f 487/559/1 492/558/1 486/555/1 +f 514/560/1 520/557/1 513/556/1 +f 463/484/1 464/561/1 465/532/1 +f 487/559/1 491/562/1 492/558/1 +f 488/563/1 491/562/1 487/559/1 +f 515/564/1 520/557/1 514/560/1 +f 515/564/1 519/565/1 520/557/1 +f 489/566/1 491/562/1 488/563/1 +f 516/567/1 519/565/1 515/564/1 +f 516/567/1 518/568/1 519/565/1 +f 490/569/1 491/562/1 489/566/1 +f 517/570/1 518/568/1 516/567/1 +f 634/571/1 632/572/1 633/573/1 +f 634/571/1 631/574/1 632/572/1 +f 635/575/1 631/574/1 634/571/1 +f 635/575/1 630/576/1 631/574/1 +f 636/577/1 630/576/1 635/575/1 +f 636/577/1 629/578/1 630/576/1 +f 637/579/1 629/578/1 636/577/1 +f 637/579/1 628/580/1 629/578/1 +f 638/581/1 628/580/1 637/579/1 +f 638/581/1 627/582/1 628/580/1 +f 639/583/1 669/584/1 638/581/1 +f 669/584/1 627/582/1 638/581/1 +f 669/584/1 670/585/1 627/582/1 +f 670/585/1 626/586/1 627/582/1 +f 639/583/1 668/587/1 669/584/1 +f 671/588/1 626/586/1 670/585/1 +f 639/583/2 667/589/2 668/587/2 +f 640/590/1 667/589/1 639/583/1 +f 672/591/1 626/586/1 671/588/1 +f 640/590/1 666/592/1 667/589/1 +f 673/593/1 626/586/1 672/591/1 +f 640/590/1 665/594/1 666/592/1 +f 674/595/1 626/586/1 673/593/1 +f 640/590/1 664/596/1 665/594/1 +f 674/595/1 625/597/1 626/586/1 +f 675/598/1 625/597/1 674/595/1 +f 641/599/1 664/596/1 640/590/1 +f 641/599/1 663/600/1 664/596/1 +f 676/601/1 625/597/1 675/598/1 +f 641/599/1 662/602/1 663/600/1 +f 676/601/1 624/603/1 625/597/1 +f 677/604/1 624/603/1 676/601/1 +f 641/599/1 661/605/1 662/602/1 +f 642/606/1 661/605/1 641/599/1 +f 678/607/1 624/603/1 677/604/1 +f 678/607/1 623/608/1 624/603/1 +f 642/606/1 660/609/1 661/605/1 +f 643/610/1 660/609/1 642/606/1 +f 679/611/1 623/608/1 678/607/1 +f 643/610/1 659/612/1 660/609/1 +f 679/611/1 622/613/1 623/608/1 +f 680/614/1 622/613/1 679/611/1 +f 643/610/1 658/615/1 659/612/1 +f 644/616/1 658/615/1 643/610/1 +f 681/617/1 622/613/1 680/614/1 +f 644/616/1 657/618/1 658/615/1 +f 681/617/1 621/619/1 622/613/1 +f 644/616/1 681/617/1 657/618/1 +f 644/616/1 621/619/1 681/617/1 +f 645/620/1 621/619/1 644/616/1 +f 645/620/1 620/621/1 621/619/1 +f 645/620/1 619/622/1 620/621/1 +f 645/620/1 618/623/1 619/622/1 +f 645/620/1 617/624/1 618/623/1 +f 645/620/1 616/625/1 617/624/1 +f 645/620/1 615/626/1 616/625/1 +f 645/620/1 614/627/1 615/626/1 +f 646/628/1 608/629/1 645/620/1 +f 608/629/1 614/627/1 645/620/1 +f 608/629/2 613/630/2 614/627/2 +f 608/629/1 612/631/1 613/630/1 +f 608/629/1 611/632/1 612/631/1 +f 608/629/1 610/633/1 611/632/1 +f 608/629/1 609/634/1 610/633/1 +f 646/628/1 607/635/1 608/629/1 +f 647/636/1 607/635/1 646/628/1 +f 647/636/1 606/637/1 607/635/1 +f 647/636/1 605/638/1 606/637/1 +f 648/639/1 605/638/1 647/636/1 +f 648/639/1 604/640/1 605/638/1 +f 649/641/1 604/640/1 648/639/1 +f 649/641/1 603/642/1 604/640/1 +f 649/641/1 602/643/1 603/642/1 +f 650/644/1 602/643/1 649/641/1 +f 650/644/1 601/645/1 602/643/1 +f 585/646/1 583/647/1 584/648/1 +f 586/649/1 583/647/1 585/646/1 +f 650/644/1 600/650/1 601/645/1 +f 587/651/1 583/647/1 586/649/1 +f 651/652/1 600/650/1 650/644/1 +f 588/653/1 583/647/1 587/651/1 +f 651/652/1 599/654/1 600/650/1 +f 589/655/1 583/647/1 588/653/1 +f 590/656/1 583/647/1 589/655/1 +f 651/652/1 598/657/1 599/654/1 +f 591/658/1 583/647/1 590/656/1 +f 592/659/1 583/647/1 591/658/1 +f 651/652/1 597/660/1 598/657/1 +f 593/661/1 583/647/1 592/659/1 +f 594/662/1 583/647/1 593/661/1 +f 652/663/1 597/660/1 651/652/1 +f 652/663/1 596/664/1 597/660/1 +f 595/665/1 583/647/1 594/662/1 +f 596/664/2 583/647/2 595/665/2 +f 652/663/1 583/647/1 596/664/1 +f 652/663/1 582/666/1 583/647/1 +f 653/667/1 582/666/1 652/663/1 +f 653/667/1 581/668/1 582/666/1 +f 653/667/1 580/669/1 581/668/1 +f 653/667/1 579/670/1 580/669/1 +f 654/671/1 579/670/1 653/667/1 +f 654/671/1 578/672/1 579/670/1 +f 654/671/1 577/673/1 578/672/1 +f 655/674/1 577/673/1 654/671/1 +f 655/674/1 576/675/1 577/673/1 +f 655/674/1 575/676/1 576/675/1 +f 656/677/1 575/676/1 655/674/1 +f 656/677/1 574/678/1 575/676/1 +f 656/677/1 573/679/1 574/678/1 +f 571/680/1 573/679/1 656/677/1 +f 571/680/1 572/681/1 573/679/1 +f 682/682/1 710/683/1 708/684/1 +f 710/683/1 707/685/1 708/684/1 +f 710/683/1 706/686/1 707/685/1 +f 710/683/1 705/687/1 706/686/1 +f 710/683/1 704/688/1 705/687/1 +f 710/683/1 703/689/1 704/688/1 +f 710/683/1 702/690/1 703/689/1 +f 710/683/1 711/691/1 702/690/1 +f 711/691/1 712/692/1 702/690/1 +f 712/692/1 701/693/1 702/690/1 +f 682/682/1 709/694/1 710/683/1 +f 713/695/1 701/693/1 712/692/1 +f 714/696/1 701/693/1 713/695/1 +f 715/697/1 701/693/1 714/696/1 +f 715/697/1 700/698/1 701/693/1 +f 716/699/1 700/698/1 715/697/1 +f 717/700/1 700/698/1 716/699/1 +f 717/700/1 699/701/1 700/698/1 +f 718/702/1 699/701/1 717/700/1 +f 718/702/1 698/703/1 699/701/1 +f 719/704/1 698/703/1 718/702/1 +f 720/705/1 698/703/1 719/704/1 +f 720/705/1 697/706/1 698/703/1 +f 721/707/1 697/706/1 720/705/1 +f 721/707/1 696/708/1 697/706/1 +f 722/709/1 696/708/1 721/707/1 +f 722/709/1 695/710/1 696/708/1 +f 723/711/1 695/710/1 722/709/1 +f 724/712/1 695/710/1 723/711/1 +f 724/712/1 694/713/1 695/710/1 +f 725/714/1 694/713/1 724/712/1 +f 725/714/1 693/715/1 694/713/1 +f 726/716/1 693/715/1 725/714/1 +f 726/716/1 692/717/1 693/715/1 +f 727/718/1 692/717/1 726/716/1 +f 727/718/1 691/719/1 692/717/1 +f 728/720/1 691/719/1 727/718/1 +f 729/721/1 691/719/1 728/720/1 +f 729/721/1 690/722/1 691/719/1 +f 730/723/1 690/722/1 729/721/1 +f 730/723/1 689/724/1 690/722/1 +f 731/725/1 689/724/1 730/723/1 +f 732/726/1 689/724/1 731/725/1 +f 732/726/1 688/727/1 689/724/1 +f 733/728/1 688/727/1 732/726/1 +f 734/729/1 688/727/1 733/728/1 +f 735/730/1 688/727/1 734/729/1 +f 682/682/1 735/730/1 709/694/1 +f 682/682/1 688/727/1 735/730/1 +f 682/682/1 687/731/1 688/727/1 +f 682/682/1 686/732/1 687/731/1 +f 682/682/1 685/733/1 686/732/1 +f 682/682/1 684/734/1 685/733/1 +f 682/682/2 683/735/2 684/734/2 diff --git a/test-files/tri.vert b/test-files/tri.vert index 4635b2e..9fefd0c 100644 --- a/test-files/tri.vert +++ b/test-files/tri.vert @@ -1,642 +1,13 @@ #version 450 +out gl_PerVertex +{ + vec4 gl_Position; +}; + +layout(location = 0) in vec4 position; // location must match demo.cpp + void main() { - const int vertex_count = 633; - const vec4 vertices[vertex_count] = vec4[]( - vec4(0.262847, -0.208541, 0.0, 1), - vec4(0.266826, -0.211157, 0.0, 1), - vec4(0.264865, -0.212128, 0.0, 1), - vec4(0.262847, -0.208541, 0.0, 1), - vec4(0.268003, -0.208243, 0.0, 1), - vec4(0.266826, -0.211157, 0.0, 1), - vec4(0.259485, -0.202265, 0.0, 1), - vec4(0.268003, -0.208243, 0.0, 1), - vec4(0.262847, -0.208541, 0.0, 1), - vec4(0.259485, -0.202265, 0.0, 1), - vec4(0.268395, -0.203386, 0.0, 1), - vec4(0.268003, -0.208243, 0.0, 1), - vec4(0.259485, -0.202265, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.268395, -0.203386, 0.0, 1), - vec4(0.254777, -0.193298, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.259485, -0.202265, 0.0, 1), - vec4(0.246595, -0.178354, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.254777, -0.193298, 0.0, 1), - vec4(0.238861, -0.164904, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.246595, -0.178354, 0.0, 1), - vec4(0.231576, -0.152949, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.238861, -0.164904, 0.0, 1), - vec4(0.225019, -0.142898, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.231576, -0.152949, 0.0, 1), - vec4(0.219471, -0.135165, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.225019, -0.142898, 0.0, 1), - vec4(0.214932, -0.129747, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.219471, -0.135165, 0.0, 1), - vec4(0.211093, -0.125787, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.214932, -0.129747, 0.0, 1), - vec4(0.207646, -0.122425, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.211093, -0.125787, 0.0, 1), - vec4(0.207646, -0.122425, 0.0, 1), - vec4(0.319337, -0.125376, 0.0, 1), - vec4(0.268395, -0.125376, 0.0, 1), - vec4(0.207646, -0.122425, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.319337, -0.125376, 0.0, 1), - vec4(0.204592, -0.119660, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.207646, -0.122425, 0.0, 1), - vec4(0.202042, -0.117381, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.204592, -0.119660, 0.0, 1), - vec4(0.200109, -0.115476, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.202042, -0.117381, 0.0, 1), - vec4(0.198792, -0.113944, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.200109, -0.115476, 0.0, 1), - vec4(0.197951, -0.112449, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.198792, -0.113944, 0.0, 1), - vec4(0.197447, -0.110656, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.197951, -0.112449, 0.0, 1), - vec4(0.197279, -0.108564, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.197447, -0.110656, 0.0, 1), - vec4(0.197503, -0.106845, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.197279, -0.108564, 0.0, 1), - vec4(0.198175, -0.105276, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.197503, -0.106845, 0.0, 1), - vec4(0.199296, -0.103856, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.198175, -0.105276, 0.0, 1), - vec4(0.226028, -0.103856, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.199296, -0.103856, 0.0, 1), - vec4(0.226028, 0.098565, 0.0, 1), - vec4(0.268395, -0.103856, 0.0, 1), - vec4(0.226028, -0.103856, 0.0, 1), - vec4(0.268395, -0.103856, 0.0, 1), - vec4(0.319337, -0.103856, 0.0, 1), - vec4(0.226028, -0.103856, 0.0, 1), - vec4(0.226028, 0.098565, 0.0, 1), - vec4(0.268395, 0.088477, 0.0, 1), - vec4(0.268395, -0.103856, 0.0, 1), - vec4(0.226028, 0.098565, 0.0, 1), - vec4(0.269068, 0.107643, 0.0, 1), - vec4(0.268395, 0.088477, 0.0, 1), - vec4(0.231016, 0.146013, 0.0, 1), - vec4(0.269068, 0.107643, 0.0, 1), - vec4(0.226028, 0.098565, 0.0, 1), - vec4(0.231016, 0.146013, 0.0, 1), - vec4(0.271085, 0.122999, 0.0, 1), - vec4(0.269068, 0.107643, 0.0, 1), - vec4(0.231016, 0.146013, 0.0, 1), - vec4(0.274448, 0.134543, 0.0, 1), - vec4(0.271085, 0.122999, 0.0, 1), - vec4(0.315021, 0.138541, 0.0, 1), - vec4(0.331442, 0.132862, 0.0, 1), - vec4(0.324885, 0.125464, 0.0, 1), - vec4(0.315021, 0.138541, 0.0, 1), - vec4(0.313957, 0.161256, 0.0, 1), - vec4(0.331442, 0.132862, 0.0, 1), - vec4(0.231016, 0.146013, 0.0, 1), - vec4(0.279379, 0.142576, 0.0, 1), - vec4(0.274448, 0.134543, 0.0, 1), - vec4(0.304934, 0.146386, 0.0, 1), - vec4(0.313957, 0.161256, 0.0, 1), - vec4(0.315021, 0.138541, 0.0, 1), - vec4(0.231016, 0.146013, 0.0, 1), - vec4(0.286104, 0.147395, 0.0, 1), - vec4(0.279379, 0.142576, 0.0, 1), - vec4(0.245979, 0.174482, 0.0, 1), - vec4(0.286104, 0.147395, 0.0, 1), - vec4(0.231016, 0.146013, 0.0, 1), - vec4(0.294622, 0.149002, 0.0, 1), - vec4(0.313957, 0.161256, 0.0, 1), - vec4(0.304934, 0.146386, 0.0, 1), - vec4(0.245979, 0.174482, 0.0, 1), - vec4(0.294622, 0.149002, 0.0, 1), - vec4(0.286104, 0.147395, 0.0, 1), - vec4(0.245979, 0.174482, 0.0, 1), - vec4(0.313957, 0.161256, 0.0, 1), - vec4(0.294622, 0.149002, 0.0, 1), - vec4(0.245979, 0.174482, 0.0, 1), - vec4(0.293782, 0.178293, 0.0, 1), - vec4(0.313957, 0.161256, 0.0, 1), - vec4(0.270917, 0.183971, 0.0, 1), - vec4(0.293782, 0.178293, 0.0, 1), - vec4(0.245979, 0.174482, 0.0, 1), - vec4(0.071158, -0.128851, 0.0, 1), - vec4(0.100720, -0.130719, 0.0, 1), - vec4(0.089848, -0.131429, 0.0, 1), - vec4(0.071158, -0.128851, 0.0, 1), - vec4(0.111143, -0.128589, 0.0, 1), - vec4(0.100720, -0.130719, 0.0, 1), - vec4(0.054766, -0.121117, 0.0, 1), - vec4(0.111143, -0.128589, 0.0, 1), - vec4(0.071158, -0.128851, 0.0, 1), - vec4(0.054766, -0.121117, 0.0, 1), - vec4(0.121119, -0.125040, 0.0, 1), - vec4(0.111143, -0.128589, 0.0, 1), - vec4(0.142582, -0.121640, 0.0, 1), - vec4(0.152390, -0.125376, 0.0, 1), - vec4(0.146842, -0.125376, 0.0, 1), - vec4(0.142582, -0.121640, 0.0, 1), - vec4(0.154407, -0.033917, 0.0, 1), - vec4(0.152390, -0.125376, 0.0, 1), - vec4(0.054766, -0.121117, 0.0, 1), - vec4(0.129581, -0.121491, 0.0, 1), - vec4(0.121119, -0.125040, 0.0, 1), - vec4(0.139893, -0.119398, 0.0, 1), - vec4(0.154407, -0.033917, 0.0, 1), - vec4(0.142582, -0.121640, 0.0, 1), - vec4(0.054766, -0.121117, 0.0, 1), - vec4(0.135465, -0.119361, 0.0, 1), - vec4(0.129581, -0.121491, 0.0, 1), - vec4(0.040672, -0.108228, 0.0, 1), - vec4(0.080629, -0.115214, 0.0, 1), - vec4(0.054766, -0.121117, 0.0, 1), - vec4(0.080629, -0.115214, 0.0, 1), - vec4(0.091361, -0.116634, 0.0, 1), - vec4(0.054766, -0.121117, 0.0, 1), - vec4(0.091361, -0.116634, 0.0, 1), - vec4(0.135465, -0.119361, 0.0, 1), - vec4(0.054766, -0.121117, 0.0, 1), - vec4(0.138772, -0.118651, 0.0, 1), - vec4(0.154407, -0.033917, 0.0, 1), - vec4(0.139893, -0.119398, 0.0, 1), - vec4(0.091361, -0.116634, 0.0, 1), - vec4(0.138772, -0.118651, 0.0, 1), - vec4(0.135465, -0.119361, 0.0, 1), - vec4(0.091361, -0.116634, 0.0, 1), - vec4(0.104811, -0.114542, 0.0, 1), - vec4(0.138772, -0.118651, 0.0, 1), - vec4(0.104811, -0.114542, 0.0, 1), - vec4(0.116243, -0.108265, 0.0, 1), - vec4(0.138772, -0.118651, 0.0, 1), - vec4(0.116243, -0.108265, 0.0, 1), - vec4(0.125658, -0.097804, 0.0, 1), - vec4(0.138772, -0.118651, 0.0, 1), - vec4(0.125658, -0.097804, 0.0, 1), - vec4(0.133616, -0.082337, 0.0, 1), - vec4(0.138772, -0.118651, 0.0, 1), - vec4(0.133616, -0.082337, 0.0, 1), - vec4(0.154407, -0.033917, 0.0, 1), - vec4(0.138772, -0.118651, 0.0, 1), - vec4(0.040672, -0.108228, 0.0, 1), - vec4(0.071298, -0.110955, 0.0, 1), - vec4(0.080629, -0.115214, 0.0, 1), - vec4(0.040672, -0.108228, 0.0, 1), - vec4(0.063368, -0.103856, 0.0, 1), - vec4(0.071298, -0.110955, 0.0, 1), - vec4(0.029884, -0.091303, 0.0, 1), - vec4(0.063368, -0.103856, 0.0, 1), - vec4(0.040672, -0.108228, 0.0, 1), - vec4(0.029884, -0.091303, 0.0, 1), - vec4(0.057344, -0.094516, 0.0, 1), - vec4(0.063368, -0.103856, 0.0, 1), - vec4(0.029884, -0.091303, 0.0, 1), - vec4(0.053729, -0.083532, 0.0, 1), - vec4(0.057344, -0.094516, 0.0, 1), - vec4(0.023411, -0.071465, 0.0, 1), - vec4(0.053729, -0.083532, 0.0, 1), - vec4(0.029884, -0.091303, 0.0, 1), - vec4(0.023411, -0.071465, 0.0, 1), - vec4(0.052524, -0.070904, 0.0, 1), - vec4(0.053729, -0.083532, 0.0, 1), - vec4(0.140677, -0.061041, 0.0, 1), - vec4(0.154407, -0.033917, 0.0, 1), - vec4(0.133616, -0.082337, 0.0, 1), - vec4(0.021253, -0.048712, 0.0, 1), - vec4(0.052524, -0.070904, 0.0, 1), - vec4(0.023411, -0.071465, 0.0, 1), - vec4(0.021253, -0.048712, 0.0, 1), - vec4(0.054934, -0.052971, 0.0, 1), - vec4(0.052524, -0.070904, 0.0, 1), - vec4(0.146842, -0.033917, 0.0, 1), - vec4(0.154407, -0.033917, 0.0, 1), - vec4(0.140677, -0.061041, 0.0, 1), - vec4(0.021253, -0.048712, 0.0, 1), - vec4(0.062163, -0.037728, 0.0, 1), - vec4(0.054934, -0.052971, 0.0, 1), - vec4(0.022738, -0.030554, 0.0, 1), - vec4(0.062163, -0.037728, 0.0, 1), - vec4(0.021253, -0.048712, 0.0, 1), - vec4(0.022738, -0.030554, 0.0, 1), - vec4(0.074212, -0.025174, 0.0, 1), - vec4(0.062163, -0.037728, 0.0, 1), - vec4(0.027194, -0.013742, 0.0, 1), - vec4(0.074212, -0.025174, 0.0, 1), - vec4(0.022738, -0.030554, 0.0, 1), - vec4(0.027194, -0.013742, 0.0, 1), - vec4(0.128684, 0.017865, 0.0, 1), - vec4(0.074212, -0.025174, 0.0, 1), - vec4(0.034619, 0.001725, 0.0, 1), - vec4(0.128684, 0.017865, 0.0, 1), - vec4(0.027194, -0.013742, 0.0, 1), - vec4(0.045631, 0.016744, 0.0, 1), - vec4(0.128684, 0.017865, 0.0, 1), - vec4(0.034619, 0.001725, 0.0, 1), - vec4(0.060846, 0.032212, 0.0, 1), - vec4(0.128684, 0.017865, 0.0, 1), - vec4(0.045631, 0.016744, 0.0, 1), - vec4(0.060846, 0.032212, 0.0, 1), - vec4(0.142386, 0.030007, 0.0, 1), - vec4(0.128684, 0.017865, 0.0, 1), - vec4(0.060846, 0.032212, 0.0, 1), - vec4(0.153230, 0.042224, 0.0, 1), - vec4(0.142386, 0.030007, 0.0, 1), - vec4(0.080265, 0.048127, 0.0, 1), - vec4(0.153230, 0.042224, 0.0, 1), - vec4(0.060846, 0.032212, 0.0, 1), - vec4(0.080265, 0.048127, 0.0, 1), - vec4(0.161216, 0.054516, 0.0, 1), - vec4(0.153230, 0.042224, 0.0, 1), - vec4(0.109518, 0.070320, 0.0, 1), - vec4(0.161216, 0.054516, 0.0, 1), - vec4(0.080265, 0.048127, 0.0, 1), - vec4(0.109518, 0.070320, 0.0, 1), - vec4(0.166680, 0.067555, 0.0, 1), - vec4(0.161216, 0.054516, 0.0, 1), - vec4(0.109518, 0.070320, 0.0, 1), - vec4(0.169959, 0.082014, 0.0, 1), - vec4(0.166680, 0.067555, 0.0, 1), - vec4(0.124089, 0.084891, 0.0, 1), - vec4(0.169959, 0.082014, 0.0, 1), - vec4(0.109518, 0.070320, 0.0, 1), - vec4(0.021758, 0.179936, 0.0, 1), - vec4(0.029828, 0.075027, 0.0, 1), - vec4(0.021758, 0.075027, 0.0, 1), - vec4(0.021758, 0.179936, 0.0, 1), - vec4(0.035544, 0.103347, 0.0, 1), - vec4(0.029828, 0.075027, 0.0, 1), - vec4(0.124089, 0.084891, 0.0, 1), - vec4(0.171051, 0.097892, 0.0, 1), - vec4(0.169959, 0.082014, 0.0, 1), - vec4(0.132831, 0.101703, 0.0, 1), - vec4(0.171051, 0.097892, 0.0, 1), - vec4(0.124089, 0.084891, 0.0, 1), - vec4(0.132831, 0.101703, 0.0, 1), - vec4(0.168726, 0.120159, 0.0, 1), - vec4(0.171051, 0.097892, 0.0, 1), - vec4(0.135745, 0.120757, 0.0, 1), - vec4(0.168726, 0.120159, 0.0, 1), - vec4(0.132831, 0.101703, 0.0, 1), - vec4(0.021758, 0.179936, 0.0, 1), - vec4(0.041932, 0.125539, 0.0, 1), - vec4(0.035544, 0.103347, 0.0, 1), - vec4(0.135745, 0.120757, 0.0, 1), - vec4(0.161749, 0.140334, 0.0, 1), - vec4(0.168726, 0.120159, 0.0, 1), - vec4(0.134484, 0.134543, 0.0, 1), - vec4(0.161749, 0.140334, 0.0, 1), - vec4(0.135745, 0.120757, 0.0, 1), - vec4(0.021758, 0.179936, 0.0, 1), - vec4(0.048994, 0.141604, 0.0, 1), - vec4(0.041932, 0.125539, 0.0, 1), - vec4(0.130702, 0.146312, 0.0, 1), - vec4(0.161749, 0.140334, 0.0, 1), - vec4(0.134484, 0.134543, 0.0, 1), - vec4(0.130702, 0.146312, 0.0, 1), - vec4(0.150120, 0.158417, 0.0, 1), - vec4(0.161749, 0.140334, 0.0, 1), - vec4(0.021758, 0.179936, 0.0, 1), - vec4(0.061155, 0.156922, 0.0, 1), - vec4(0.048994, 0.141604, 0.0, 1), - vec4(0.124397, 0.156063, 0.0, 1), - vec4(0.150120, 0.158417, 0.0, 1), - vec4(0.130702, 0.146312, 0.0, 1), - vec4(0.115963, 0.163348, 0.0, 1), - vec4(0.150120, 0.158417, 0.0, 1), - vec4(0.124397, 0.156063, 0.0, 1), - vec4(0.021758, 0.179936, 0.0, 1), - vec4(0.035264, 0.172763, 0.0, 1), - vec4(0.061155, 0.156922, 0.0, 1), - vec4(0.035264, 0.172763, 0.0, 1), - vec4(0.039915, 0.171867, 0.0, 1), - vec4(0.061155, 0.156922, 0.0, 1), - vec4(0.039915, 0.171867, 0.0, 1), - vec4(0.076118, 0.166113, 0.0, 1), - vec4(0.061155, 0.156922, 0.0, 1), - vec4(0.115963, 0.163348, 0.0, 1), - vec4(0.135241, 0.172614, 0.0, 1), - vec4(0.150120, 0.158417, 0.0, 1), - vec4(0.105791, 0.167719, 0.0, 1), - vec4(0.135241, 0.172614, 0.0, 1), - vec4(0.115963, 0.163348, 0.0, 1), - vec4(0.039915, 0.171867, 0.0, 1), - vec4(0.093883, 0.169177, 0.0, 1), - vec4(0.076118, 0.166113, 0.0, 1), - vec4(0.093883, 0.169177, 0.0, 1), - vec4(0.135241, 0.172614, 0.0, 1), - vec4(0.105791, 0.167719, 0.0, 1), - vec4(0.039915, 0.171867, 0.0, 1), - vec4(0.135241, 0.172614, 0.0, 1), - vec4(0.093883, 0.169177, 0.0, 1), - vec4(0.045071, 0.172539, 0.0, 1), - vec4(0.135241, 0.172614, 0.0, 1), - vec4(0.039915, 0.171867, 0.0, 1), - vec4(0.053813, 0.174557, 0.0, 1), - vec4(0.135241, 0.172614, 0.0, 1), - vec4(0.045071, 0.172539, 0.0, 1), - vec4(0.053813, 0.174557, 0.0, 1), - vec4(0.118513, 0.181132, 0.0, 1), - vec4(0.135241, 0.172614, 0.0, 1), - vec4(0.021758, 0.179936, 0.0, 1), - vec4(0.031397, 0.175453, 0.0, 1), - vec4(0.035264, 0.172763, 0.0, 1), - vec4(0.066142, 0.177919, 0.0, 1), - vec4(0.118513, 0.181132, 0.0, 1), - vec4(0.053813, 0.174557, 0.0, 1), - vec4(0.021758, 0.179936, 0.0, 1), - vec4(0.028314, 0.179936, 0.0, 1), - vec4(0.031397, 0.175453, 0.0, 1), - vec4(0.079312, 0.181281, 0.0, 1), - vec4(0.118513, 0.181132, 0.0, 1), - vec4(0.066142, 0.177919, 0.0, 1), - vec4(0.079312, 0.181281, 0.0, 1), - vec4(0.099935, 0.183971, 0.0, 1), - vec4(0.118513, 0.181132, 0.0, 1), - vec4(0.090576, 0.183299, 0.0, 1), - vec4(0.099935, 0.183971, 0.0, 1), - vec4(0.079312, 0.181281, 0.0, 1), - vec4(-0.131375, -0.127057, 0.0, 1), - vec4(-0.078668, -0.128701, 0.0, 1), - vec4(-0.102318, -0.132101, 0.0, 1), - vec4(-0.131375, -0.127057, 0.0, 1), - vec4(-0.058830, -0.118502, 0.0, 1), - vec4(-0.078668, -0.128701, 0.0, 1), - vec4(-0.156678, -0.111926, 0.0, 1), - vec4(-0.058830, -0.118502, 0.0, 1), - vec4(-0.131375, -0.127057, 0.0, 1), - vec4(-0.156678, -0.111926, 0.0, 1), - vec4(-0.042802, -0.101503, 0.0, 1), - vec4(-0.058830, -0.118502, 0.0, 1), - vec4(-0.178226, -0.086708, 0.0, 1), - vec4(-0.143060, -0.099298, 0.0, 1), - vec4(-0.156678, -0.111926, 0.0, 1), - vec4(-0.143060, -0.099298, 0.0, 1), - vec4(-0.116945, -0.107891, 0.0, 1), - vec4(-0.156678, -0.111926, 0.0, 1), - vec4(-0.116945, -0.107891, 0.0, 1), - vec4(-0.042802, -0.101503, 0.0, 1), - vec4(-0.156678, -0.111926, 0.0, 1), - vec4(-0.102878, -0.106023, 0.0, 1), - vec4(-0.042802, -0.101503, 0.0, 1), - vec4(-0.116945, -0.107891, 0.0, 1), - vec4(-0.091614, -0.100419, 0.0, 1), - vec4(-0.042802, -0.101503, 0.0, 1), - vec4(-0.102878, -0.106023, 0.0, 1), - vec4(-0.091614, -0.100419, 0.0, 1), - vec4(-0.030417, -0.077629, 0.0, 1), - vec4(-0.042802, -0.101503, 0.0, 1), - vec4(-0.083152, -0.091079, 0.0, 1), - vec4(-0.030417, -0.077629, 0.0, 1), - vec4(-0.091614, -0.100419, 0.0, 1), - vec4(-0.178226, -0.086708, 0.0, 1), - vec4(-0.160881, -0.073519, 0.0, 1), - vec4(-0.143060, -0.099298, 0.0, 1), - vec4(-0.076707, -0.076882, 0.0, 1), - vec4(-0.030417, -0.077629, 0.0, 1), - vec4(-0.083152, -0.091079, 0.0, 1), - vec4(-0.194618, -0.053195, 0.0, 1), - vec4(-0.160881, -0.073519, 0.0, 1), - vec4(-0.178226, -0.086708, 0.0, 1), - vec4(-0.076707, -0.076882, 0.0, 1), - vec4(-0.021506, -0.046806, 0.0, 1), - vec4(-0.030417, -0.077629, 0.0, 1), - vec4(-0.071495, -0.056707, 0.0, 1), - vec4(-0.021506, -0.046806, 0.0, 1), - vec4(-0.076707, -0.076882, 0.0, 1), - vec4(-0.194618, -0.053195, 0.0, 1), - vec4(-0.170408, -0.030554, 0.0, 1), - vec4(-0.160881, -0.073519, 0.0, 1), - vec4(-0.067516, -0.030554, 0.0, 1), - vec4(-0.021506, -0.046806, 0.0, 1), - vec4(-0.071495, -0.056707, 0.0, 1), - vec4(-0.204453, -0.013182, 0.0, 1), - vec4(-0.170408, -0.030554, 0.0, 1), - vec4(-0.194618, -0.053195, 0.0, 1), - vec4(-0.067516, -0.030554, 0.0, 1), - vec4(-0.016070, -0.009035, 0.0, 1), - vec4(-0.021506, -0.046806, 0.0, 1), - vec4(-0.204453, -0.013182, 0.0, 1), - vec4(-0.067516, -0.030554, 0.0, 1), - vec4(-0.170408, -0.030554, 0.0, 1), - vec4(-0.204453, -0.013182, 0.0, 1), - vec4(-0.016070, -0.009035, 0.0, 1), - vec4(-0.067516, -0.030554, 0.0, 1), - vec4(-0.207731, 0.033333, 0.0, 1), - vec4(-0.171417, -0.009035, 0.0, 1), - vec4(-0.204453, -0.013182, 0.0, 1), - vec4(-0.171417, -0.009035, 0.0, 1), - vec4(-0.016070, -0.009035, 0.0, 1), - vec4(-0.204453, -0.013182, 0.0, 1), - vec4(-0.207731, 0.033333, 0.0, 1), - vec4(-0.170016, 0.017903, 0.0, 1), - vec4(-0.171417, -0.009035, 0.0, 1), - vec4(-0.207731, 0.033333, 0.0, 1), - vec4(-0.167157, 0.042224, 0.0, 1), - vec4(-0.170016, 0.017903, 0.0, 1), - vec4(-0.204901, 0.076335, 0.0, 1), - vec4(-0.167157, 0.042224, 0.0, 1), - vec4(-0.207731, 0.033333, 0.0, 1), - vec4(-0.204901, 0.076335, 0.0, 1), - vec4(-0.162842, 0.063931, 0.0, 1), - vec4(-0.167157, 0.042224, 0.0, 1), - vec4(-0.204901, 0.076335, 0.0, 1), - vec4(-0.157294, 0.082612, 0.0, 1), - vec4(-0.162842, 0.063931, 0.0, 1), - vec4(-0.026634, 0.090046, 0.0, 1), - vec4(-0.006487, 0.071665, 0.0, 1), - vec4(-0.014557, 0.066957, 0.0, 1), - vec4(-0.026634, 0.090046, 0.0, 1), - vec4(-0.018256, 0.105140, 0.0, 1), - vec4(-0.006487, 0.071665, 0.0, 1), - vec4(-0.196411, 0.112986, 0.0, 1), - vec4(-0.157294, 0.082612, 0.0, 1), - vec4(-0.204901, 0.076335, 0.0, 1), - vec4(-0.196411, 0.112986, 0.0, 1), - vec4(-0.150737, 0.097855, 0.0, 1), - vec4(-0.157294, 0.082612, 0.0, 1), - vec4(-0.038655, 0.108204, 0.0, 1), - vec4(-0.018256, 0.105140, 0.0, 1), - vec4(-0.026634, 0.090046, 0.0, 1), - vec4(-0.196411, 0.112986, 0.0, 1), - vec4(-0.143172, 0.109661, 0.0, 1), - vec4(-0.150737, 0.097855, 0.0, 1), - vec4(-0.038655, 0.108204, 0.0, 1), - vec4(-0.032715, 0.132937, 0.0, 1), - vec4(-0.018256, 0.105140, 0.0, 1), - vec4(-0.050620, 0.121429, 0.0, 1), - vec4(-0.032715, 0.132937, 0.0, 1), - vec4(-0.038655, 0.108204, 0.0, 1), - vec4(-0.196411, 0.112986, 0.0, 1), - vec4(-0.135074, 0.118777, 0.0, 1), - vec4(-0.143172, 0.109661, 0.0, 1), - vec4(-0.182261, 0.143285, 0.0, 1), - vec4(-0.135074, 0.118777, 0.0, 1), - vec4(-0.196411, 0.112986, 0.0, 1), - vec4(-0.182261, 0.143285, 0.0, 1), - vec4(-0.126920, 0.125950, 0.0, 1), - vec4(-0.135074, 0.118777, 0.0, 1), - vec4(-0.063257, 0.130396, 0.0, 1), - vec4(-0.032715, 0.132937, 0.0, 1), - vec4(-0.050620, 0.121429, 0.0, 1), - vec4(-0.182261, 0.143285, 0.0, 1), - vec4(-0.118710, 0.131181, 0.0, 1), - vec4(-0.126920, 0.125950, 0.0, 1), - vec4(-0.077295, 0.135776, 0.0, 1), - vec4(-0.032715, 0.132937, 0.0, 1), - vec4(-0.063257, 0.130396, 0.0, 1), - vec4(-0.182261, 0.143285, 0.0, 1), - vec4(-0.110332, 0.134730, 0.0, 1), - vec4(-0.118710, 0.131181, 0.0, 1), - vec4(-0.077295, 0.135776, 0.0, 1), - vec4(-0.049863, 0.155054, 0.0, 1), - vec4(-0.032715, 0.132937, 0.0, 1), - vec4(-0.182261, 0.143285, 0.0, 1), - vec4(-0.101673, 0.136859, 0.0, 1), - vec4(-0.110332, 0.134730, 0.0, 1), - vec4(-0.092735, 0.137569, 0.0, 1), - vec4(-0.049863, 0.155054, 0.0, 1), - vec4(-0.077295, 0.135776, 0.0, 1), - vec4(-0.182261, 0.143285, 0.0, 1), - vec4(-0.092735, 0.137569, 0.0, 1), - vec4(-0.101673, 0.136859, 0.0, 1), - vec4(-0.182261, 0.143285, 0.0, 1), - vec4(-0.049863, 0.155054, 0.0, 1), - vec4(-0.092735, 0.137569, 0.0, 1), - vec4(-0.163291, 0.165889, 0.0, 1), - vec4(-0.049863, 0.155054, 0.0, 1), - vec4(-0.182261, 0.143285, 0.0, 1), - vec4(-0.163291, 0.165889, 0.0, 1), - vec4(-0.069253, 0.171119, 0.0, 1), - vec4(-0.049863, 0.155054, 0.0, 1), - vec4(-0.140342, 0.179451, 0.0, 1), - vec4(-0.069253, 0.171119, 0.0, 1), - vec4(-0.163291, 0.165889, 0.0, 1), - vec4(-0.140342, 0.179451, 0.0, 1), - vec4(-0.090437, 0.180758, 0.0, 1), - vec4(-0.069253, 0.171119, 0.0, 1), - vec4(-0.113414, 0.183971, 0.0, 1), - vec4(-0.090437, 0.180758, 0.0, 1), - vec4(-0.140342, 0.179451, 0.0, 1), - vec4(-0.518424, -0.153621, 0.0, 1), - vec4(-0.491860, -0.209513, 0.0, 1), - vec4(-0.515398, -0.267945, 0.0, 1), - vec4(-0.491860, -0.209513, 0.0, 1), - vec4(-0.482866, -0.224233, 0.0, 1), - vec4(-0.515398, -0.267945, 0.0, 1), - vec4(-0.482866, -0.224233, 0.0, 1), - vec4(-0.470172, -0.232826, 0.0, 1), - vec4(-0.515398, -0.267945, 0.0, 1), - vec4(-0.470172, -0.232826, 0.0, 1), - vec4(-0.451259, -0.237982, 0.0, 1), - vec4(-0.515398, -0.267945, 0.0, 1), - vec4(-0.451259, -0.237982, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.515398, -0.267945, 0.0, 1), - vec4(-0.451259, -0.237982, 0.0, 1), - vec4(-0.426124, -0.239700, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.426124, -0.239700, 0.0, 1), - vec4(-0.398888, -0.239700, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.398888, -0.239700, 0.0, 1), - vec4(-0.347442, -0.239700, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.347442, -0.239700, 0.0, 1), - vec4(-0.320206, -0.239700, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.320206, -0.239700, 0.0, 1), - vec4(-0.294791, -0.238019, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.294791, -0.238019, 0.0, 1), - vec4(-0.275709, -0.232975, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.275709, -0.232975, 0.0, 1), - vec4(-0.262960, -0.224569, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.262960, -0.224569, 0.0, 1), - vec4(-0.254021, -0.209961, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.254021, -0.209961, 0.0, 1), - vec4(-0.227906, -0.153621, 0.0, 1), - vec4(-0.230932, -0.267945, 0.0, 1), - vec4(-0.398888, 0.096547, 0.0, 1), - vec4(-0.347442, -0.239700, 0.0, 1), - vec4(-0.398888, -0.239700, 0.0, 1), - vec4(-0.398888, 0.096547, 0.0, 1), - vec4(-0.347442, 0.103945, 0.0, 1), - vec4(-0.347442, -0.239700, 0.0, 1), - vec4(-0.246372, -0.186312, 0.0, 1), - vec4(-0.227906, -0.153621, 0.0, 1), - vec4(-0.254021, -0.209961, 0.0, 1), - vec4(-0.518424, -0.153621, 0.0, 1), - vec4(-0.499678, -0.185976, 0.0, 1), - vec4(-0.491860, -0.209513, 0.0, 1), - vec4(-0.240011, -0.153621, 0.0, 1), - vec4(-0.227906, -0.153621, 0.0, 1), - vec4(-0.246372, -0.186312, 0.0, 1), - vec4(-0.518424, -0.153621, 0.0, 1), - vec4(-0.506319, -0.153621, 0.0, 1), - vec4(-0.499678, -0.185976, 0.0, 1), - vec4(-0.399785, 0.121691, 0.0, 1), - vec4(-0.347442, 0.103945, 0.0, 1), - vec4(-0.398888, 0.096547, 0.0, 1), - vec4(-0.399785, 0.121691, 0.0, 1), - vec4(-0.346489, 0.125689, 0.0, 1), - vec4(-0.347442, 0.103945, 0.0, 1), - vec4(-0.402475, 0.139736, 0.0, 1), - vec4(-0.346489, 0.125689, 0.0, 1), - vec4(-0.399785, 0.121691, 0.0, 1), - vec4(-0.402475, 0.139736, 0.0, 1), - vec4(-0.343631, 0.141604, 0.0, 1), - vec4(-0.346489, 0.125689, 0.0, 1), - vec4(-0.406958, 0.150683, 0.0, 1), - vec4(-0.343631, 0.141604, 0.0, 1), - vec4(-0.402475, 0.139736, 0.0, 1), - vec4(-0.406958, 0.150683, 0.0, 1), - vec4(-0.338868, 0.151692, 0.0, 1), - vec4(-0.343631, 0.141604, 0.0, 1), - vec4(-0.414916, 0.157146, 0.0, 1), - vec4(-0.338868, 0.151692, 0.0, 1), - vec4(-0.406958, 0.150683, 0.0, 1), - vec4(-0.414916, 0.157146, 0.0, 1), - vec4(-0.330630, 0.157894, 0.0, 1), - vec4(-0.338868, 0.151692, 0.0, 1), - vec4(-0.428029, 0.161742, 0.0, 1), - vec4(-0.330630, 0.157894, 0.0, 1), - vec4(-0.414916, 0.157146, 0.0, 1), - vec4(-0.428029, 0.161742, 0.0, 1), - vec4(-0.317348, 0.162153, 0.0, 1), - vec4(-0.330630, 0.157894, 0.0, 1), - vec4(-0.446299, 0.164469, 0.0, 1), - vec4(-0.317348, 0.162153, 0.0, 1), - vec4(-0.428029, 0.161742, 0.0, 1), - vec4(-0.446299, 0.164469, 0.0, 1), - vec4(-0.299022, 0.164469, 0.0, 1), - vec4(-0.317348, 0.162153, 0.0, 1), - vec4(-0.446299, 0.177246, 0.0, 1), - vec4(-0.299022, 0.164469, 0.0, 1), - vec4(-0.446299, 0.164469, 0.0, 1), - vec4(-0.446299, 0.177246, 0.0, 1), - vec4(-0.299022, 0.177246, 0.0, 1), - vec4(-0.299022, 0.164469, 0.0, 1) - ); - gl_Position = vertices[uint(gl_VertexIndex) % vertex_count]; + gl_Position = position; } diff --git a/test-files/tri.vert.spv b/test-files/tri.vert.spv index ea84248060c58320c30a483a85030023296d26a0..4258facfc821a2cb0fd6848442ba9879863de087 100644 GIT binary patch literal 576 zcmYk2K}*9x5QWF4snu$074=ps9);q;iXaLeBpw141g}AoMHXUO+9>+>{8e5A-`7OQ zEW^yac{BTVgVyP$*@jNn_N}s^wN#t+th0_${1i`CWj48(p2O%{uqMJ8n8syo`P+*x z$hYNvd7#r${1&k-G>VgGHjCo>BwZ|$Rr!^>B=?0&GQV_b=|3F2ZiDBGG=I;Ugiws; zU7<8~b;oO-Ji6txTbAxqrO*l|r#D~u($5PEr3rmlsDsYMe^dE`F!o`+Dp;f$Fy0dB zc4kI(??5Q{$@;Yw=SX=+*jRonK0ic_?oqu9Y%F9;k>6zhbzP$m>`*lt#&Uh3oz?Y@ za*X+1MSARGo*I2%^!F6mMgLN7Ln}Hk@E;+e;*C%^13B||LYW=P(Zij$nxKaBs~fK5 Ef5U?`O8@`> literal 15956 zcmZvj37k&l--pM}*oka0_I)W!wy|Y58v7Du9SmbkhRPC>Y*C>UB3p?fOOj=fQd)>o zvQ`vH*&GU6$ z+@)aph{%W*F}+&E#u_=vctgtB)%Gv|gS$B&2~mMEL)PM&+etVCOREaq^h?$NliwmAQK}trGil zM;Y|r1o?QdPu~PKY$?aR^Dj6C?(Xx?D--6pFLK;NkYmR2oV3sxW^yfLxDU93R$f_r zab@T*=hu``$0)6PmFJa&xmG^?-^@BjY4NY3<1CuFry}A=9m(U0YGSY88k}QADVI&h z;6Cd)=J~?0PmVjeyVqqOIHwl>f_-yo9;KUR-`twn2giBtA&=I{Ig=X%oLBtm^PRT` ze2gZH~7 z3SvyQGtK8;h@QzL^qy-ZT-D!Ta5Z z72{I-IBF(8V*Nq8ZgZE#``2wDH)}$ByQh}owz;lax0RR--tV@SEBMR9 z)@>tBj=N~x7%>^V-)$?``)rJL9~Q3}_lI?3#boe)x1C(^m)cmjy?9iQv)1h(CWH68 z9p&EH(Av74#4FpJwr*!J8NA=^A~&OI*zGD__{K@=b`z7q``zwx6Vrv=N5p%(oUm>W zF&Vty?I~BcLD+p%JoCU2>pmtXgZI0=Gi=O40eA2Auc-|Z{c=$;t+nCmCT zrS@^uU;bqBK+DF7aj9ho$PYjEd35lxJkVwF!94`$2FaDwO6@xF@`=?q+I0rIEIznS z@I7mYT+5Hcui**e3(3ct?{^dBM!uL}A2Y+m!zSgk$C@N2gZI0S%dPlwx^;(( zPoKVJ`zDLY;Qj6hx#USRtUFS?e0LVx_X#l>yx)CNZdmIj)_qF6?s#_VjuMl>``yuU zpR8YL-7(^u*)m&qte6bm?>;Tpsq0(T9VcEkD#E(s#boe)cY@rF?TfAZjJQoyY3oiD zlfnDlXXQSLe9^j-#E<`*+q%z*$>9C&WVzU=*R4B6TNte=X z4?frDi^<^q?gF{i&G%XNb#aZO8LYcdOa||F7s=I4`=NE;5O;hfqjeXH$>9C&61hu@ zPFZ)U`1^OmdtN3cgZI13<=S=VZQVD;_h-AF59C&7P&5)BCWesJUuz=ZWEKi``r||_g*byuitj@^0$uLzB|NZ@P2ov+<~Y! zt^1L<{nc~U-6bZ2_q!j^x}S*m9Y1f~-C{C$zx%0N!$LXi@qQ+b`S-GQ_lU{h z{qE;-WmbG|`+gz*_vPQM`=yu+-tT@T_jRuG*4-;cZdq7ME?{~kETl!6A>wYV4yZCME9u$+o``z#4)~26r_x!!Mcl}e=JtQWB_q#vH z<@@ZJ=-}(XVKJ^*D%m4)t-rofKlqw?RGjm%#_ zC?dc=gmmcHOIDGWg)S z!NgvBz^w+&AXtwqW1uVlsHYdqeJte_pkHZ;Icqv(LJ>#ANV(_aC_{yHD7@ zx5ZIq`dIgWVlsHY`>$Ne?sWG0MWoU9?{{;^b^NV}b#sdI{#D8L%_Sy-_q(~}ZuVJj_nb$3AgY;l^NPvf z{q8+-U*{`r`{ol@jOk_F{B*SNe)nFv8?Aq`eG7;$q!3#*Zs2Mk5;Cs#@O7br z{M@;@?eSC;zqaCAyKW^h8GLZvpj%n)e`TxM^H@bZf6N~1Ruz-M``v1CN79GiYws7Y zYPH|G4~WU&{cd%+iJw-oeQSvS$oIE(Yl_L>{cbI}l!&a>eNa3+_L_BTi^<^qZXLN_ zc2>0Ks;)R@X82yVo|p{Y@79-_x+MHOi573#kkelK24XUJzuQo*(g)%D{6=Ej$W*>& zHkQAzx~1J?6Y=th@O|$?VlsGtpQds^V-)$>*^yBdJ@nP|;eZ{OBD<*^YyY1xC zj{DR0Z7<%?w5)YIh{@pnZb!L)l5$zMllb%Bs#&+Qm<-#bV=)W6`#3X)wo*xsF!Ta4_a#!B|!S?Mf zp1QrF?b}C82Jd(K%5817)4Kh{+v-=gZhtWuyx)zJd+hbv)*T?uwI;mhfnqXvzdJ}S z!;tW2)_8HA9pUd&28+qy{q7LC%O6~}eG|m*jILw%JXA~u?{^dBO3jb3?lAF{mDR1A zBqoFRyN}C_9680h!^H!tg};kQ7L&pI-4SvhUp`|$FN_r9Qu}`LgnXyOrMAzL;w?+U z$M=+&4Bp>ol-%Z3U)k5p(PG@(RK6aKkv}_rv+Xlhyls6wdoG?9lfnD@jFYQ4CFAzs z`^|W9y~1g?2jABwh{@pn?lW?0i!4bAx)a3@d=dVh=2pmwQ+bomq zJ6TKy?{}xjZMl|Y-KpZr>%#ZU)5K)(es{WD^`t0!yw8hA*7-Fhc)T;jWbl4>rd*l! zRc+rF#QT2w+PW`_$>9C&OL9L=sAc=k5?`CM&bqV3Wbl4>j$DUvd93@gcxTTqt^10Y z4Bqd~l{+@!g5C40;;UDWS@$(D8NA<}C%0kUH`bj`w!~rUE)bK!``y>&iY?x1-G$=O zZ|}A4A~6}f-+eHX+?4RW`*JZEyx)CO z?siHkd!FAC7oRoP_FW++gZH~{%e`1&q3yd;96Ms6bytbW;Qj79a+g}QuzlYZN1WuwN}!Ta6!<%W%~ zVxO-Y#kkbo+kPN_u-SCG?j|uVwd{xT#e255=VG(C{f(~Mg3r$_VlsIDp0>)>fAd*; zF1CrMWxB_@DPl5szq?&-*rral?+$U*shOjLeRqn<;Qj7Lau=smwdZ1&7?;{UAIq;U zP{sE7MBHv=_cMr*posekz{vh5NHO;z*#boe)_lVqr znXg#)sCaqDL)JYeCWH68$K|dSYh};X32}|MGuHi4Oa||Ff0En#NFnR~EUqyqd|!A{ zOa||FPswfURMbB2e-Y=Lf86%{RZIr&cTdZ$SrC3NIwQXP%1_q)O-u&wchAaIh{$OB z{w`h?75@J?&xy(4{q7%f=eopN_fPRB?_IZj&x^_6{q6<1L+v8%xw(d|kLACWH68SLNDYOJm)?#aV8I?`5xv$>9C&b-7bBp0US! zLp)`22HW?hm<-9C&|KtwEEVAyu;^UdKT9-fCBZK$5 zX>@M;)t{}KR=o1>@I7@pF&VtyO)pnEI>x#g#G^kgYWrpslfnDlOmY|M?6+=a@h7FS zSvQNA4BqcX${jwJV%@CbQzyc1HZd8z-_0(!t7chyeRGKSohWbn<`k2```uh}lMc?b zeRGSysT00G%_Am*_q%!J_HWE-``#l?v+F_IH=mdc-tXp@%kto6+xK4a;sW7&k^*8f zc)wdvZeFwBQi6~DLSkHM?@0>F58IS}NAUHyi1^!w@7o@9?-P^3`}-7?%lq9edwj*j zbEbE(Zj_h|-tQKdi@KD~_AMdKUu~LoONzCtA0>m<-9C_uP3*){7mcC7e~wrU!Q0(8NAx%+#^Teg`Pm)hq{bNOLgcH8%~7Gho> zyno%6az%eWXxUa`ULU-lZ7p}Hh{@pnZdnW%txsT%yhmdoH?&$>9Ba z>MECZ;5zGe6EAu{{C?hDOa||FACaq(d!KcCh_B=ie>dGzOa||FAC((;@jZLa9~0x6 zr1Cwum;BzI`)!}z;x}UoH3*)YK4LO>f1kc`g(s}GZa;CE&V{YpUrYw?cjM%K9CpyU z1H>nP4}ZTrP)r8zcL&LJX}Qw6@#1T1irc<}#boe)cZl4gGDoeOAYT7Q`1fl=#boe) zH&HHW%u?$PgR_>geUrpw@P7Akxwg;zV%_25mj;)!ZnBsR-tUf(i!V5Dd+?f!6ys9M zJ|TZ|d`-LVlVYxm53UPE@u*Rh~h5iRCoj!U>1$6VSmb6Lj~ z+>ER2W?VHl<5;cn zTFet2lX*^y+*B<*=kd>LagM)NWX8?XB10ArbB-AgGr#QkRX5}2Yc14T?B->T-_ntp z^UNz9zpLXKt+iUr8yu7QK#SaFEj;J(+q5{hLu;27j^l1Ob0mY`qeYi%;9<@&f9aUx zJ~wkb;AV~o-OQ2e&}ZL6TI|Vu*zqwpg;q*E(<1)D!7wKjkb9Tqfxg6(pGmbgG zGmh)j)1r@Wphd2cn{i|w z(jwPfiwx(PTRA2ZqeU)O3(xruZpM-6tVNDvH#c+a;b!uWY0>ZFW*nLRTI4vA;XIxh zH_*+v!EVMe4|U8vBx$jKvKF56_>o$idrAw>dFIiMpLR2Dg4VNIlifVc@eCcAInVr} z-*#&OKEpjuCd5PoYZpLxV6*c+TTfv^a-{Ime8LcWUj@!g0hi<9BP}m_Kv;g`08AdmS_Hcl@o6{GRZz z7Bj!QgMZW_LzelZ<6m_oLl)2PzBq^HcUhd{_fpI_GW@QI9KSbW#xY-Wd{amA^zgT} zI2V!juID^HotSg@jP4vhi)PMcbDr~fm~+hJ;hb8`IOaT#^SK$vT);8!_nC3Le~;2C z>5gUG%(1+iIaYEr$14As?|00R_mZ6BSkuiMc`u0P$a_0xj=Wc6=Ge&193OHsN8T%u z;e8O-;@Zru9LMNLhAfXIR*T2eUJK88d`B(L@xFjA*I?#neVCuynQ_egY!35tHZzX7 zzvF>!#xe7=E$8?-l^Ms(&z^9yn{mt|9rJS_Gme>`{op9QyBw{fUeY`N8&>|euJ9P= zI6q!vT$B5F)_F4A-*Z~o<#W1gz+`Ugk=NGxKN7+U AH2?qr -- 2.30.2