feature: write indexed data to file.
This commit is contained in:
@@ -88,12 +88,12 @@ namespace wavefront {
|
|||||||
} else {
|
} else {
|
||||||
target.push_back(0);
|
target.push_back(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
std::copy(
|
std::copy(
|
||||||
source.begin(),
|
source.begin(),
|
||||||
source.end(),
|
source.end(),
|
||||||
std::back_inserter(target)
|
std::back_inserter(target)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
std::index_sequence<1, 2, 3>{}
|
std::index_sequence<1, 2, 3>{}
|
||||||
);
|
);
|
||||||
@@ -227,6 +227,7 @@ namespace wavefront {
|
|||||||
std::array<IndexType, 3> triangle_data;
|
std::array<IndexType, 3> triangle_data;
|
||||||
std::size_t triangle_vertex_index = 0;
|
std::size_t triangle_vertex_index = 0;
|
||||||
for (const auto &vertex : triangle) {
|
for (const auto &vertex : triangle) {
|
||||||
|
if constexpr (VertexDimCount > 1) {
|
||||||
std::array<IndexType, VertexDimCount> coordinate_indices;
|
std::array<IndexType, VertexDimCount> coordinate_indices;
|
||||||
for (std::size_t i = 0; i < VertexDimCount; ++i) {
|
for (std::size_t i = 0; i < VertexDimCount; ++i) {
|
||||||
const auto &wavefront_index = mapper[i].get_vertex_index(vertex);
|
const auto &wavefront_index = mapper[i].get_vertex_index(vertex);
|
||||||
@@ -241,6 +242,13 @@ namespace wavefront {
|
|||||||
assert(index != 0);
|
assert(index != 0);
|
||||||
assert(triangle_vertex_index < 3);
|
assert(triangle_vertex_index < 3);
|
||||||
triangle_data[triangle_vertex_index++] = index;
|
triangle_data[triangle_vertex_index++] = index;
|
||||||
|
} else {
|
||||||
|
const auto &wavefront_index = mapper[0].get_vertex_index(vertex);
|
||||||
|
const auto &line_index = mapper[0].attribute_line_map.at(wavefront_index);
|
||||||
|
const auto &coordinate_index = mapper[0].line_coordinate_map.at(line_index);
|
||||||
|
assert(coordinate_index != 0);
|
||||||
|
triangle_data[triangle_vertex_index++] = coordinate_index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(triangle_vertex_index == 3);
|
assert(triangle_vertex_index == 3);
|
||||||
triangle_data_set.emplace(triangle_data);
|
triangle_data_set.emplace(triangle_data);
|
||||||
|
|||||||
125
src/main.cpp
125
src/main.cpp
@@ -8,6 +8,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
#include "parse.hpp"
|
#include "parse.hpp"
|
||||||
#include "compile.hpp"
|
#include "compile.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
#include "output.hpp"
|
||||||
|
|
||||||
static void usage(const char* prog) {
|
static void usage(const char* prog) {
|
||||||
std::cerr << "Usage: " << prog
|
std::cerr << "Usage: " << prog
|
||||||
@@ -120,7 +122,7 @@ int main(int argc, char** argv) {
|
|||||||
Settings settings = settings_builder.build();
|
Settings settings = settings_builder.build();
|
||||||
|
|
||||||
using FloatType = float;
|
using FloatType = float;
|
||||||
using IndexType = std::size_t;
|
using IndexType = std::uint32_t;
|
||||||
|
|
||||||
CATCH_AND_RETURN(scan_data, wavefront::scan_error, 1, wavefront::scan(
|
CATCH_AND_RETURN(scan_data, wavefront::scan_error, 1, wavefront::scan(
|
||||||
settings.input(),
|
settings.input(),
|
||||||
@@ -173,32 +175,101 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
std::cerr << "Compiled " << index_storage.triangles.size() << " triangles" << std::endl;
|
std::cerr << "Compiled " << index_storage.triangles.size() << " triangles" << std::endl;
|
||||||
|
|
||||||
// TODO: We need to output:
|
auto &output = settings.output();
|
||||||
// 1. Some kind of singature;
|
|
||||||
// 2. A version number;
|
// 0:4: Signature
|
||||||
// 3. Flags describing the data:
|
settings.output().write("\x7F" "3DG", 4);
|
||||||
// 3.1. position: required, always 3 coordinates (no flag needed)
|
// 4:8: Version
|
||||||
// 3.2. normal: optional, always 3 coordinates (single flag needed)
|
wavefront::write_number<std::uint32_t>(output, 1);
|
||||||
// 3.3. texcoord: optional, up to 3 coordinates (two flags needed, 0 = none, 1 = 1D, 2 = 2D, 3 = 3D)
|
|
||||||
// 3.4. type of number data: 0 = float, 1 = double
|
std::uint32_t flags = 0;
|
||||||
// 3.5. vertices: 0 = never used, 1 = one attribute per vertex, 2 = two attributes per vertex, 3 = three attributes per vertex
|
|
||||||
// Flags: (0 = number type, 1 = normals present, 2-3 = texture_coordinate size, 4-7 = number of vertex attributes (up to 16), only 3 supported for now)
|
if (coordinate_storage_index.normal_coordinate_index.size() > 0) {
|
||||||
// 4. Data order: up to attribute_count attributes, 1-byte each, specifying an index of map in file order. 0 is the number_list and therefore reserved.
|
flags |= 1 << 1;
|
||||||
// 5. Sizes:
|
}
|
||||||
// 5.1. Size of the number list (in items): 1 item = 1 float/double (depending on number_type)
|
|
||||||
// 5.2. Size of the position list (in items): 1 item = 3 indices into the float_list
|
std::visit([&](const auto &texture_coordinates) {
|
||||||
// 5.3. Size of the normal list (in items, only if normal flag is set): 1 item = 3 indices into the float_list
|
if constexpr (std::ranges::range<std::decay_t<decltype(texture_coordinates)>>) {
|
||||||
// 5.4. Size of the texcoord list (in items, only if texcoord_size is not 0): 1 item = 1-3 indices into the float_list (depending on texcoord_size)
|
using mapped_type = typename std::decay_t<decltype(texture_coordinates)>::mapped_type;
|
||||||
// 5.5. Size of the vertex list (in items): 1 item = 1-attribute_count indices into different maps.
|
if constexpr (std::ranges::range<mapped_type>) {
|
||||||
// 5.6. Size of the triangle list (in items): 1 item = 3 triangle vertex indices into the vertex list.
|
flags |= std::tuple_size_v<mapped_type> << 2;
|
||||||
// Special references: number_list, triangle_list, vertex_list, position_list
|
} else {
|
||||||
// All other references are additional attributes.
|
flags |= 1 << 2;
|
||||||
// In order for quick load into GPU buffer we want:
|
}
|
||||||
// - each map start file pos to be known
|
}
|
||||||
// - each map size in bytes to be known
|
}, coordinate_data.texture_coordinates);
|
||||||
// - each map type (float32, float64, int8, int16, int32, int64)
|
|
||||||
// - number of elements per item (or stride, i.e. number of bytes per item)
|
// 8:12: flags<0: float_size, 1: has_normals, 2&3: texcoord_ndims (0 = no),
|
||||||
// - each map file pos aligned to 16-bytes (assuming file is loaded aligned to 16-bytes). Elements within the map do not need to be aligned.
|
wavefront::write_number<std::uint32_t>(output, flags);
|
||||||
|
|
||||||
|
// 12:16: number_list item count
|
||||||
|
wavefront::write_number<std::uint32_t>(output, number_list.size());
|
||||||
|
|
||||||
|
// 16:20: 2D storage item count
|
||||||
|
wavefront::write_number<std::uint32_t>(output, std::get<2>(coordinate_storage).size());
|
||||||
|
// 20:24: 3D storage item count
|
||||||
|
wavefront::write_number<std::uint32_t>(output, std::get<3>(coordinate_storage).size());
|
||||||
|
|
||||||
|
// 24:28: Vertex storage item count
|
||||||
|
std::visit([&](const auto &vertex_data) {
|
||||||
|
using value_t = std::decay_t<decltype(vertex_data)>::value_type;
|
||||||
|
if constexpr (std::tuple_size_v<value_t> > 1) {
|
||||||
|
wavefront::write_number<std::uint32_t>(output, vertex_data.size());
|
||||||
|
} else {
|
||||||
|
wavefront::write_number<std::uint32_t>(output, 0);
|
||||||
|
}
|
||||||
|
}, index_storage.vertices);
|
||||||
|
wavefront::write_number<std::uint32_t>(output, index_storage.triangles.size());
|
||||||
|
|
||||||
|
output.write(reinterpret_cast<const char *>(number_list.data()), number_list.size() * sizeof(decltype(number_list)::value_type));
|
||||||
|
|
||||||
|
std::array<char, 16> padding;
|
||||||
|
padding.fill(0);
|
||||||
|
std::size_t required_padding;
|
||||||
|
|
||||||
|
required_padding = (16 - (number_list.size() * sizeof(decltype(number_list)::value_type) % 16)) % 16;
|
||||||
|
output.write(padding.data(), required_padding);
|
||||||
|
|
||||||
|
if (std::get<2>(coordinate_storage).size() > 0) {
|
||||||
|
const auto &value_list = std::get<2>(coordinate_storage);
|
||||||
|
using value_t = std::decay_t<decltype(value_list)>::value_type;
|
||||||
|
output.write(reinterpret_cast<const char *>(value_list.data()), value_list.size() * sizeof(value_t));
|
||||||
|
required_padding = (16 - (value_list.size() * sizeof(value_t) % 16)) % 16;
|
||||||
|
if (required_padding > 0) {
|
||||||
|
output.write(padding.data(), required_padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::get<3>(coordinate_storage).size() > 0) [[likely]] {
|
||||||
|
const auto &value_list = std::get<3>(coordinate_storage);
|
||||||
|
using value_t = std::decay_t<decltype(value_list)>::value_type;
|
||||||
|
output.write(reinterpret_cast<const char *>(value_list.data()), value_list.size() * sizeof(value_t));
|
||||||
|
required_padding = (16 - (value_list.size() * sizeof(value_t) % 16)) % 16;
|
||||||
|
if (required_padding > 0) {
|
||||||
|
output.write(padding.data(), required_padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::visit([&](const auto &vertex_data) {
|
||||||
|
using value_t = std::decay_t<decltype(vertex_data)>::value_type;
|
||||||
|
if constexpr (std::tuple_size_v<value_t> > 1) {
|
||||||
|
output.write(reinterpret_cast<const char *>(vertex_data.data()), vertex_data.size() * sizeof(value_t));
|
||||||
|
required_padding = (16 - (vertex_data.size() * sizeof(value_t) % 16)) % 16;
|
||||||
|
if (required_padding > 0) {
|
||||||
|
output.write(padding.data(), required_padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, index_storage.vertices);
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto &value_list = index_storage.triangles;
|
||||||
|
using value_t = std::decay_t<decltype(value_list)>::value_type;
|
||||||
|
output.write(reinterpret_cast<const char *>(value_list.data()), value_list.size() * sizeof(value_t));
|
||||||
|
required_padding = (16 - (value_list.size() * sizeof(value_t) % 16)) % 16;
|
||||||
|
if (required_padding > 0) {
|
||||||
|
output.write(padding.data(), required_padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
9
src/output.hpp
Normal file
9
src/output.hpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include <array>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace wavefront {
|
||||||
|
template<typename NumericType>
|
||||||
|
void write_number(std::ostream &output, NumericType value) {
|
||||||
|
output.write(reinterpret_cast<char *>(&value), sizeof(NumericType));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user