feature: vertex and triangle index storage
This commit is contained in:
198
src/compile.hpp
198
src/compile.hpp
@@ -6,6 +6,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "parse.hpp"
|
#include "parse.hpp"
|
||||||
|
#include "repeat.hpp"
|
||||||
|
|
||||||
namespace wavefront {
|
namespace wavefront {
|
||||||
template<typename IndexType, template<typename, typename...> typename ContainerType, typename ... Args>
|
template<typename IndexType, template<typename, typename...> typename ContainerType, typename ... Args>
|
||||||
@@ -26,6 +27,13 @@ namespace wavefront {
|
|||||||
> &source
|
> &source
|
||||||
) {
|
) {
|
||||||
for (const auto &[line_number, coordinates] : source) {
|
for (const auto &[line_number, coordinates] : source) {
|
||||||
|
if constexpr (std::ranges::range<std::decay_t<decltype(coordinates)>>) {
|
||||||
|
for (const auto &coordinate : coordinates) {
|
||||||
|
assert(coordinate != 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(coordinates != 0);
|
||||||
|
}
|
||||||
std::get<NumDims>(target).emplace(coordinates);
|
std::get<NumDims>(target).emplace(coordinates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,7 +81,14 @@ namespace wavefront {
|
|||||||
auto &target,
|
auto &target,
|
||||||
const auto &source
|
const auto &source
|
||||||
) {
|
) {
|
||||||
target.reserve(source.size());
|
target.reserve(source.size() + 1);
|
||||||
|
if (source.size() > 0) {
|
||||||
|
if constexpr (std::ranges::range<typename std::decay_t<decltype(target)>::value_type>) {
|
||||||
|
target.push_back(repeat_value<IndexType, std::tuple_size_v<typename std::decay_t<decltype(target)>::value_type>>(0));
|
||||||
|
} else {
|
||||||
|
target.push_back(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
std::copy(
|
std::copy(
|
||||||
source.begin(),
|
source.begin(),
|
||||||
source.end(),
|
source.end(),
|
||||||
@@ -106,6 +121,7 @@ namespace wavefront {
|
|||||||
auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector);
|
auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector);
|
||||||
assert(data_vector_iterator != data_storage.end());
|
assert(data_vector_iterator != data_storage.end());
|
||||||
auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator);
|
auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator);
|
||||||
|
assert(data_vector_index != 0);
|
||||||
result.position_coordinate_index[line_number] = data_vector_index;
|
result.position_coordinate_index[line_number] = data_vector_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,6 +131,7 @@ namespace wavefront {
|
|||||||
auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector);
|
auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector);
|
||||||
assert(data_vector_iterator != data_storage.end());
|
assert(data_vector_iterator != data_storage.end());
|
||||||
auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator);
|
auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator);
|
||||||
|
assert(data_vector_index != 0);
|
||||||
result.normal_coordinate_index[line_number] = data_vector_index;
|
result.normal_coordinate_index[line_number] = data_vector_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,10 +143,12 @@ namespace wavefront {
|
|||||||
auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector);
|
auto data_vector_iterator = std::lower_bound(data_storage.begin(), data_storage.end(), data_vector);
|
||||||
assert(data_vector_iterator != data_storage.end());
|
assert(data_vector_iterator != data_storage.end());
|
||||||
auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator);
|
auto data_vector_index = std::distance(data_storage.begin(), data_vector_iterator);
|
||||||
|
assert(data_vector_index != 0);
|
||||||
result.texcoord_coordinate_index[line_number] = data_vector_index;
|
result.texcoord_coordinate_index[line_number] = data_vector_index;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const auto &[line_number, data_index] : texture_coordinates) {
|
for (const auto &[line_number, data_index] : texture_coordinates) {
|
||||||
|
assert(data_index != 0);
|
||||||
result.texcoord_coordinate_index[line_number] = data_index;
|
result.texcoord_coordinate_index[line_number] = data_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,4 +157,181 @@ namespace wavefront {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using unwrap_vertex_func_t = std::function<vertex_index_t(const triangle_vertex_indices &)>;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static const unwrap_vertex_func_t get_position_vertex_index = [] (const triangle_vertex_indices &vertex_indices) -> vertex_index_t {
|
||||||
|
return vertex_indices.position_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unwrap_vertex_func_t get_normal_vertex_index = [] (const triangle_vertex_indices &vertex_indices) -> vertex_index_t {
|
||||||
|
return vertex_indices.normal_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unwrap_vertex_func_t get_texcoord_vertex_index = [] (const triangle_vertex_indices &vertex_indices) -> vertex_index_t {
|
||||||
|
return vertex_indices.texcoord_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename IndexType>
|
||||||
|
struct coordinate_mapper_t {
|
||||||
|
const unwrap_vertex_func_t &get_vertex_index;
|
||||||
|
const std::vector<std::size_t> &attribute_line_map;
|
||||||
|
const std::map<file_line_t, IndexType> &line_coordinate_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename IndexType, std::size_t VertexDimCount>
|
||||||
|
std::vector<std::array<IndexType, VertexDimCount>> compile_vertex_storage_impl(
|
||||||
|
const scan_result &scan_data,
|
||||||
|
const wavefront_face_data_result_t &face_data,
|
||||||
|
const std::array<coordinate_mapper_t<IndexType>, VertexDimCount> &mapper
|
||||||
|
) {
|
||||||
|
std::set<std::array<IndexType, VertexDimCount>> vertex_storage_set;
|
||||||
|
|
||||||
|
for (const auto &triangle : face_data.triangle_list) {
|
||||||
|
for (const auto &vertex : triangle) {
|
||||||
|
std::array<IndexType, VertexDimCount> coordinate_indices;
|
||||||
|
for (std::size_t i = 0; i < VertexDimCount; ++i) {
|
||||||
|
const auto &wavefront_index = mapper[i].get_vertex_index(vertex);
|
||||||
|
const auto &line_index = mapper[i].attribute_line_map.at(wavefront_index);
|
||||||
|
const auto &coordinate_index = mapper[i].line_coordinate_map.at(line_index);
|
||||||
|
assert(coordinate_index != 0);
|
||||||
|
coordinate_indices[i] = coordinate_index;
|
||||||
|
}
|
||||||
|
vertex_storage_set.emplace(coordinate_indices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::array<IndexType, VertexDimCount>> result;
|
||||||
|
result.reserve(vertex_storage_set.size() + 1);
|
||||||
|
result.push_back(repeat_value<IndexType, VertexDimCount>(0));
|
||||||
|
std::copy(
|
||||||
|
vertex_storage_set.begin(),
|
||||||
|
vertex_storage_set.end(),
|
||||||
|
std::back_inserter(result)
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename IndexType, std::size_t VertexDimCount>
|
||||||
|
std::vector<std::array<IndexType, 3>> compile_triangle_storage_impl(
|
||||||
|
const scan_result &scan_data,
|
||||||
|
const wavefront_face_data_result_t &face_data,
|
||||||
|
const std::array<coordinate_mapper_t<IndexType>, VertexDimCount> &mapper,
|
||||||
|
const std::vector<std::array<IndexType, VertexDimCount>> &vertex_data
|
||||||
|
) {
|
||||||
|
std::set<std::array<IndexType, 3>> triangle_data_set;
|
||||||
|
|
||||||
|
for (const auto &triangle : face_data.triangle_list) {
|
||||||
|
std::array<IndexType, 3> triangle_data;
|
||||||
|
std::size_t triangle_vertex_index = 0;
|
||||||
|
for (const auto &vertex : triangle) {
|
||||||
|
std::array<IndexType, VertexDimCount> coordinate_indices;
|
||||||
|
for (std::size_t i = 0; i < VertexDimCount; ++i) {
|
||||||
|
const auto &wavefront_index = mapper[i].get_vertex_index(vertex);
|
||||||
|
const auto &line_index = mapper[i].attribute_line_map.at(wavefront_index);
|
||||||
|
const auto &coordinate_index = mapper[i].line_coordinate_map.at(line_index);
|
||||||
|
assert(coordinate_index != 0);
|
||||||
|
coordinate_indices[i] = coordinate_index;
|
||||||
|
}
|
||||||
|
auto iterator = std::lower_bound(vertex_data.begin(), vertex_data.end(), coordinate_indices);
|
||||||
|
assert(iterator != vertex_data.end());
|
||||||
|
auto index = std::distance(vertex_data.begin(), iterator);
|
||||||
|
assert(index != 0);
|
||||||
|
assert(triangle_vertex_index < 3);
|
||||||
|
triangle_data[triangle_vertex_index++] = index;
|
||||||
|
}
|
||||||
|
assert(triangle_vertex_index == 3);
|
||||||
|
triangle_data_set.emplace(triangle_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::array<IndexType, 3>> result;
|
||||||
|
result.reserve(triangle_data_set.size() + 1);
|
||||||
|
result.push_back(repeat_value<IndexType, 3>(0));
|
||||||
|
std::copy(
|
||||||
|
triangle_data_set.begin(),
|
||||||
|
triangle_data_set.end(),
|
||||||
|
std::back_inserter(result)
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename IndexType, template<typename, typename...> typename ContainerType, typename ... Args>
|
||||||
|
using vertex_storage_t = std::variant<
|
||||||
|
ContainerType<std::array<IndexType, 1>>,
|
||||||
|
ContainerType<std::array<IndexType, 2>>,
|
||||||
|
ContainerType<std::array<IndexType, 3>>
|
||||||
|
>;
|
||||||
|
|
||||||
|
template<typename IndexType, template<typename, typename...> typename ContainerType, typename ... Args>
|
||||||
|
struct compile_triangle_data_result_t {
|
||||||
|
vertex_storage_t<IndexType, ContainerType, Args...> vertices;
|
||||||
|
ContainerType<std::array<IndexType, 3>> triangles;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename IndexType>
|
||||||
|
compile_triangle_data_result_t<IndexType, std::vector> compile_vertex_storage(
|
||||||
|
const scan_result &scan_data,
|
||||||
|
const wavefront_face_data_result_t &face_data,
|
||||||
|
const coordinate_storage_line_mapping_t<IndexType> &coordinate_storage_index
|
||||||
|
) {
|
||||||
|
std::vector<coordinate_mapper_t<IndexType>> coordinate_mapper;
|
||||||
|
if (coordinate_storage_index.position_coordinate_index.size() > 0) [[likely]] {
|
||||||
|
coordinate_mapper.push_back(coordinate_mapper_t{
|
||||||
|
.get_vertex_index = get_position_vertex_index,
|
||||||
|
.attribute_line_map = scan_data.category_map.at("v"),
|
||||||
|
.line_coordinate_map = coordinate_storage_index.position_coordinate_index
|
||||||
|
});
|
||||||
|
} else [[unlikely]] {
|
||||||
|
throw parse_error("Expected at least one position coordinate index");
|
||||||
|
}
|
||||||
|
if (coordinate_storage_index.normal_coordinate_index.size() > 0) {
|
||||||
|
coordinate_mapper.push_back(coordinate_mapper_t{
|
||||||
|
.get_vertex_index = get_normal_vertex_index,
|
||||||
|
.attribute_line_map = scan_data.category_map.at("vn"),
|
||||||
|
.line_coordinate_map = coordinate_storage_index.normal_coordinate_index
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (coordinate_storage_index.texcoord_coordinate_index.size() > 0) {
|
||||||
|
coordinate_mapper.push_back(coordinate_mapper_t{
|
||||||
|
.get_vertex_index = get_texcoord_vertex_index,
|
||||||
|
.attribute_line_map = scan_data.category_map.at("vt"),
|
||||||
|
.line_coordinate_map = coordinate_storage_index.texcoord_coordinate_index
|
||||||
|
});
|
||||||
|
}
|
||||||
|
std::variant<
|
||||||
|
std::array<coordinate_mapper_t<IndexType>, 1>,
|
||||||
|
std::array<coordinate_mapper_t<IndexType>, 2>,
|
||||||
|
std::array<coordinate_mapper_t<IndexType>, 3>
|
||||||
|
> coordinate_mapper_data = ([&]() -> std::variant<
|
||||||
|
std::array<coordinate_mapper_t<IndexType>, 1>,
|
||||||
|
std::array<coordinate_mapper_t<IndexType>, 2>,
|
||||||
|
std::array<coordinate_mapper_t<IndexType>, 3>
|
||||||
|
> {
|
||||||
|
auto vertex_size = coordinate_mapper.size();
|
||||||
|
if (vertex_size == 1) {
|
||||||
|
return std::array<coordinate_mapper_t<IndexType>, 1>{coordinate_mapper[0]};
|
||||||
|
} else if (vertex_size == 2) {
|
||||||
|
return std::array<coordinate_mapper_t<IndexType>, 2>{coordinate_mapper[0], coordinate_mapper[1]};
|
||||||
|
} else if (vertex_size == 3) {
|
||||||
|
return std::array<coordinate_mapper_t<IndexType>, 3>{coordinate_mapper[0], coordinate_mapper[1], coordinate_mapper[2]};
|
||||||
|
} else [[unlikely]] {
|
||||||
|
throw std::runtime_error(std::format("Invalid vertex size: {}", vertex_size));
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
auto vertex_data = std::visit([&](const auto &coordinate_mapper) -> vertex_storage_t<IndexType, std::vector> {
|
||||||
|
return compile_vertex_storage_impl<IndexType, std::tuple_size_v<std::decay_t<decltype(coordinate_mapper)>>>(scan_data, face_data, coordinate_mapper);
|
||||||
|
}, coordinate_mapper_data);
|
||||||
|
auto triangle_data = std::visit([&](const auto &coordinate_mapper, const auto &vertex_data) -> std::vector<std::array<IndexType, 3>> {
|
||||||
|
if constexpr (std::tuple_size_v<std::decay_t<decltype(coordinate_mapper)>> == std::tuple_size_v<typename std::decay_t<decltype(vertex_data)>::value_type>) {
|
||||||
|
return compile_triangle_storage_impl<IndexType, std::tuple_size_v<std::decay_t<decltype(coordinate_mapper)>>>(scan_data, face_data, coordinate_mapper, vertex_data);
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Invalid state");
|
||||||
|
}, coordinate_mapper_data, vertex_data);
|
||||||
|
return { vertex_data, triangle_data };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
52
src/main.cpp
52
src/main.cpp
@@ -151,10 +151,54 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
auto coordinate_storage = compile_coordinate_storage(coordinate_index_data);
|
auto coordinate_storage = compile_coordinate_storage(coordinate_index_data);
|
||||||
|
|
||||||
auto coordinate_storage_index = compile_coordinate_storage_line_mapping(coordinate_index_data, coordinate_storage);
|
if (std::get<1>(coordinate_storage).size() > 0) {
|
||||||
|
std::cerr << "Indexed " << 1 << "D coordinates: " << std::get<1>(coordinate_storage).size() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::get<2>(coordinate_storage).size() > 0) {
|
||||||
|
std::cerr << "Indexed " << 2 << "D coordinates: " << std::get<2>(coordinate_storage).size() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::get<3>(coordinate_storage).size() > 0) {
|
||||||
|
std::cerr << "Indexed " << 3 << "D coordinates: " << std::get<3>(coordinate_storage).size() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto coordinate_storage_index = compile_coordinate_storage_line_mapping<IndexType>(coordinate_index_data, coordinate_storage);
|
||||||
|
|
||||||
|
auto index_storage = compile_vertex_storage<IndexType>(scan_data, face_data, coordinate_storage_index);
|
||||||
|
|
||||||
|
std::visit([&](const auto &vertex_storage) {
|
||||||
|
std::cerr << "Compiled " << vertex_storage.size() << " vertices" << std::endl;
|
||||||
|
}, index_storage.vertices);
|
||||||
|
|
||||||
|
std::cerr << "Compiled " << index_storage.triangles.size() << " triangles" << std::endl;
|
||||||
|
|
||||||
|
// TODO: We need to output:
|
||||||
|
// 1. Some kind of singature;
|
||||||
|
// 2. A version number;
|
||||||
|
// 3. Flags describing the data:
|
||||||
|
// 3.1. position: required, always 3 coordinates (no flag needed)
|
||||||
|
// 3.2. normal: optional, always 3 coordinates (single flag needed)
|
||||||
|
// 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
|
||||||
|
// 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)
|
||||||
|
// 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.
|
||||||
|
// 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
|
||||||
|
// 5.3. Size of the normal list (in items, only if normal flag is set): 1 item = 3 indices into the float_list
|
||||||
|
// 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)
|
||||||
|
// 5.5. Size of the vertex list (in items): 1 item = 1-attribute_count indices into different maps.
|
||||||
|
// 5.6. Size of the triangle list (in items): 1 item = 3 triangle vertex indices into the vertex list.
|
||||||
|
// Special references: number_list, triangle_list, vertex_list, position_list
|
||||||
|
// All other references are additional attributes.
|
||||||
|
// 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
|
||||||
|
// - each map type (float32, float64, int8, int16, int32, int64)
|
||||||
|
// - number of elements per item (or stride, i.e. number of bytes per item)
|
||||||
|
// - 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.
|
||||||
|
|
||||||
// Form coordinate_list_data : std::vector variant of coordinate_index_data. Internally, it creates std::set initially, stores everything in the set and then convert to vector.
|
|
||||||
// Then we can form coordinate_line_mapping : std::map<file_line_t, std::size_t> pointing for each entry to entry in coordinate_list_data.
|
|
||||||
// Then using face_data.triangle_list and scan_data.category_map[v/vn/vt], coordinate_line_mapping, we can form vertex_list_data. The vertex here is 1-3 IndexType numbers pointing to coordinate_list_data.
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,21 +270,30 @@ namespace wavefront {
|
|||||||
coordinate_data_t<IndexType> create_coordinate_index(const coordinate_data_t<FloatType> &coordinate_data, const std::vector<FloatType> &float_list) {
|
coordinate_data_t<IndexType> create_coordinate_index(const coordinate_data_t<FloatType> &coordinate_data, const std::vector<FloatType> &float_list) {
|
||||||
coordinate_data_t<IndexType> coordinate_index_data;
|
coordinate_data_t<IndexType> coordinate_index_data;
|
||||||
|
|
||||||
|
static const auto float_compare = float_is_equal<FloatType>{};
|
||||||
|
static const auto float_less = less_with_nan_first_and_nearly_equal<FloatType>{};
|
||||||
|
|
||||||
for (const auto& [line_number, coordinates] : coordinate_data.position_coordinates) {
|
for (const auto& [line_number, coordinates] : coordinate_data.position_coordinates) {
|
||||||
std::array<IndexType, coordinates.size()> position_coordinate_indices;
|
std::array<IndexType, coordinates.size()> position_coordinate_indices;
|
||||||
for (decltype(coordinates.size()) dim = 0; dim < coordinates.size(); ++dim) {
|
for (decltype(coordinates.size()) dim = 0; dim < coordinates.size(); ++dim) {
|
||||||
auto iterator = std::lower_bound(float_list.begin(), float_list.end(), coordinates[dim]);
|
auto iterator = std::lower_bound(float_list.begin(), float_list.end(), coordinates[dim], float_less);
|
||||||
assert(iterator != float_list.end());
|
assert(iterator != float_list.end());
|
||||||
position_coordinate_indices[dim] = std::distance(float_list.begin(), iterator);
|
assert(float_compare(*iterator, coordinates[dim]));
|
||||||
|
auto index = std::distance(float_list.begin(), iterator);
|
||||||
|
assert(index != 0);
|
||||||
|
position_coordinate_indices[dim] = index;
|
||||||
}
|
}
|
||||||
coordinate_index_data.position_coordinates[line_number] = position_coordinate_indices;
|
coordinate_index_data.position_coordinates[line_number] = position_coordinate_indices;
|
||||||
}
|
}
|
||||||
for (const auto& [line_number, coordinates] : coordinate_data.normal_coordinates) {
|
for (const auto& [line_number, coordinates] : coordinate_data.normal_coordinates) {
|
||||||
std::array<IndexType, coordinates.size()> normal_coordinate_indices;
|
std::array<IndexType, coordinates.size()> normal_coordinate_indices;
|
||||||
for (decltype(coordinates.size()) dim = 0; dim < coordinates.size(); ++dim) {
|
for (decltype(coordinates.size()) dim = 0; dim < coordinates.size(); ++dim) {
|
||||||
auto iterator = std::lower_bound(float_list.begin(), float_list.end(), coordinates[dim]);
|
auto iterator = std::lower_bound(float_list.begin(), float_list.end(), coordinates[dim], float_less);
|
||||||
assert(iterator != float_list.end());
|
assert(iterator != float_list.end());
|
||||||
normal_coordinate_indices[dim] = std::distance(float_list.begin(), iterator);
|
assert(float_compare(*iterator, coordinates[dim]));
|
||||||
|
auto index = std::distance(float_list.begin(), iterator);
|
||||||
|
assert(index != 0);
|
||||||
|
normal_coordinate_indices[dim] = index;
|
||||||
}
|
}
|
||||||
coordinate_index_data.normal_coordinates[line_number] = normal_coordinate_indices;
|
coordinate_index_data.normal_coordinates[line_number] = normal_coordinate_indices;
|
||||||
}
|
}
|
||||||
@@ -309,9 +318,12 @@ namespace wavefront {
|
|||||||
if constexpr (std::ranges::range<std::decay_t<decltype(coordinates)>>) {
|
if constexpr (std::ranges::range<std::decay_t<decltype(coordinates)>>) {
|
||||||
std::array<IndexType, coordinates.size()> texcoord_coordinate_indices;
|
std::array<IndexType, coordinates.size()> texcoord_coordinate_indices;
|
||||||
for (std::size_t dim = 0; dim < coordinates.size(); ++dim) {
|
for (std::size_t dim = 0; dim < coordinates.size(); ++dim) {
|
||||||
auto iterator = std::lower_bound(float_list.begin(), float_list.end(), coordinates[dim]);
|
auto iterator = std::lower_bound(float_list.begin(), float_list.end(), coordinates[dim], float_less);
|
||||||
assert(iterator != float_list.end());
|
assert(iterator != float_list.end());
|
||||||
texcoord_coordinate_indices[dim] = std::distance(float_list.begin(), iterator);
|
assert(float_compare(*iterator, coordinates[dim]));
|
||||||
|
auto index = std::distance(float_list.begin(), iterator);
|
||||||
|
assert(index != 0);
|
||||||
|
texcoord_coordinate_indices[dim] = index;
|
||||||
}
|
}
|
||||||
std::visit([&](auto &target_data) {
|
std::visit([&](auto &target_data) {
|
||||||
if constexpr (std::is_same_v<
|
if constexpr (std::is_same_v<
|
||||||
@@ -328,9 +340,11 @@ namespace wavefront {
|
|||||||
}
|
}
|
||||||
}, coordinate_index_data.texture_coordinates);
|
}, coordinate_index_data.texture_coordinates);
|
||||||
} else {
|
} else {
|
||||||
auto iterator = std::lower_bound(float_list.begin(), float_list.end(), coordinates);
|
auto iterator = std::lower_bound(float_list.begin(), float_list.end(), coordinates, float_less);
|
||||||
assert(iterator != float_list.end());
|
assert(iterator != float_list.end());
|
||||||
|
assert(float_compare(*iterator, coordinates));
|
||||||
auto coordinate = std::distance(float_list.begin(), iterator);
|
auto coordinate = std::distance(float_list.begin(), iterator);
|
||||||
|
assert(coordinate != 0);
|
||||||
std::visit([&](auto &target_data) {
|
std::visit([&](auto &target_data) {
|
||||||
if constexpr (std::is_same_v<
|
if constexpr (std::is_same_v<
|
||||||
std::map<file_line_t, IndexType>,
|
std::map<file_line_t, IndexType>,
|
||||||
|
|||||||
16
src/repeat.hpp
Normal file
16
src/repeat.hpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef __WAVEFRONT_REPEAT_HPP__
|
||||||
|
#define __WAVEFRONT_REPEAT_HPP__
|
||||||
|
|
||||||
|
#include<array>
|
||||||
|
#include<cstdint>
|
||||||
|
|
||||||
|
namespace wavefront {
|
||||||
|
template<typename ValueType, std::size_t Length>
|
||||||
|
std::array<ValueType, Length> repeat_value(ValueType value) {
|
||||||
|
std::array<ValueType, Length> result;
|
||||||
|
result.fill(value);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __WAVEFRONT_REPEAT_HPP__
|
||||||
Reference in New Issue
Block a user