mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 12:02:47 -05:00
remove glm dependency; split solver and geometry classes
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,9 +1,6 @@
|
|||||||
[submodule "vendor/glfw"]
|
[submodule "vendor/glfw"]
|
||||||
path = vendor/glfw
|
path = vendor/glfw
|
||||||
url = https://github.com/glfw/glfw.git
|
url = https://github.com/glfw/glfw.git
|
||||||
[submodule "vendor/glm"]
|
|
||||||
path = vendor/glm
|
|
||||||
url = https://github.com/g-truc/glm.git
|
|
||||||
[submodule "vendor/toddcox"]
|
[submodule "vendor/toddcox"]
|
||||||
path = vendor/toddcox
|
path = vendor/toddcox
|
||||||
url = https://github.com/JCRaymond/toddcox-faster.git
|
url = https://github.com/JCRaymond/toddcox-faster.git
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ add_subdirectory(vendor/toddcox)
|
|||||||
add_subdirectory(vendor/yaml-cpp)
|
add_subdirectory(vendor/yaml-cpp)
|
||||||
add_subdirectory(vendor/cgl)
|
add_subdirectory(vendor/cgl)
|
||||||
add_subdirectory(vendor/glfw)
|
add_subdirectory(vendor/glfw)
|
||||||
add_subdirectory(vendor/glm)
|
|
||||||
|
|
||||||
add_subdirectory(vis)
|
add_subdirectory(vis)
|
||||||
|
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ add_custom_command(
|
|||||||
|
|
||||||
add_executable(vis src/main.cpp)
|
add_executable(vis src/main.cpp)
|
||||||
target_include_directories(vis PRIVATE include)
|
target_include_directories(vis PRIVATE include)
|
||||||
target_link_libraries(vis PRIVATE tc glm glfw yaml-cpp cgl glad)
|
target_link_libraries(vis PRIVATE tc glfw yaml-cpp cgl glad)
|
||||||
add_dependencies(vis shaders presets)
|
add_dependencies(vis shaders presets)
|
||||||
|
|||||||
@@ -34,223 +34,3 @@ struct Primitive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Produce a list of all generators for the group context. The range [0..group.ngens).
|
|
||||||
*/
|
|
||||||
std::vector<int> generators(const tc::Group &context) {
|
|
||||||
std::vector<int> g_gens(context.ngens);
|
|
||||||
std::iota(g_gens.begin(), g_gens.end(), 0);
|
|
||||||
return g_gens;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine which of g_gens are the correct names for sg_gens within the current context
|
|
||||||
*/
|
|
||||||
std::vector<int> recontext_gens(
|
|
||||||
const tc::Group &context,
|
|
||||||
std::vector<int> g_gens,
|
|
||||||
std::vector<int> sg_gens) {
|
|
||||||
|
|
||||||
std::sort(g_gens.begin(), g_gens.end());
|
|
||||||
|
|
||||||
int inv_gen_map[context.ngens];
|
|
||||||
for (size_t i = 0; i < g_gens.size(); i++) {
|
|
||||||
inv_gen_map[g_gens[i]] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> s_sg_gens;
|
|
||||||
s_sg_gens.reserve(sg_gens.size());
|
|
||||||
for (const auto gen : sg_gens) {
|
|
||||||
s_sg_gens.push_back(inv_gen_map[gen]);
|
|
||||||
}
|
|
||||||
std::sort(s_sg_gens.begin(), s_sg_gens.end());
|
|
||||||
|
|
||||||
return s_sg_gens;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Solve the cosets generated by sg_gens within the subgroup generated by g_gens of the group context
|
|
||||||
*/
|
|
||||||
tc::Cosets solve(
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
|
||||||
return context.subgroup(g_gens).solve(proper_sg_gens);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply some context transformation to all primitives of this mesh.
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
std::vector<Primitive<N>> apply(std::vector<Primitive<N>> prims, const tc::Cosets &table, int gen) {
|
|
||||||
for (auto &prim : prims) {
|
|
||||||
prim.apply(table, gen);
|
|
||||||
}
|
|
||||||
return prims;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the indexes of this mesh to those of a different context, using g_gens to build the parent context and sg_gens to build this context.
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
[[nodiscard]]
|
|
||||||
std::vector<Primitive<N>> recontext(
|
|
||||||
std::vector<Primitive<N>> prims,
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
|
||||||
const auto table = solve(context, g_gens, {});
|
|
||||||
const auto path = solve(context, sg_gens, {}).path;
|
|
||||||
|
|
||||||
auto map = path.template walk<int, int>(0, proper_sg_gens, [table](int coset, int gen) {
|
|
||||||
return table.get(coset, gen);
|
|
||||||
});
|
|
||||||
|
|
||||||
std::vector<Primitive<N>> res(prims);
|
|
||||||
for (Primitive<N> &prim : res) {
|
|
||||||
for (auto &ind : prim.inds) {
|
|
||||||
ind = map[ind];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Union several meshes of the same dimension
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
std::vector<Primitive<N>> merge(const std::vector<std::vector<Primitive<N>>> &meshes) {
|
|
||||||
size_t size = 0;
|
|
||||||
for (const auto &mesh : meshes) {
|
|
||||||
size += mesh.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Primitive<N>> res;
|
|
||||||
res.reserve(size);
|
|
||||||
for (const auto &mesh : meshes) {
|
|
||||||
res.insert(res.end(), mesh.begin(), mesh.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned N>
|
|
||||||
[[nodiscard]]
|
|
||||||
std::vector<std::vector<Primitive<N>>> each_tile(
|
|
||||||
std::vector<Primitive<N>> prims,
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
std::vector<Primitive<N>> base = recontext(prims, context, g_gens, sg_gens);
|
|
||||||
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
|
||||||
|
|
||||||
const auto table = solve(context, g_gens, {});
|
|
||||||
const auto path = solve(context, g_gens, sg_gens).path;
|
|
||||||
|
|
||||||
auto _gens = generators(context);
|
|
||||||
|
|
||||||
auto res = path.walk<std::vector<Primitive<N>>, int>(base, generators(context), [&](auto from, auto gen) {
|
|
||||||
return apply(from, table, gen);
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned N>
|
|
||||||
[[nodiscard]]
|
|
||||||
std::vector<Primitive<N>> tile(
|
|
||||||
std::vector<Primitive<N>> prims,
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens,
|
|
||||||
const std::vector<int> &sg_gens
|
|
||||||
) {
|
|
||||||
auto res = each_tile<N>(prims, context, g_gens, sg_gens);
|
|
||||||
|
|
||||||
return merge(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Produce a mesh of higher dimension by fanning a single point to all primitives in this mesh.
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
[[nodiscard]]
|
|
||||||
std::vector<Primitive<N + 1>> fan(std::vector<Primitive<N>> prims, int root) {
|
|
||||||
std::vector<Primitive<N + 1>> res(prims.size());
|
|
||||||
std::transform(prims.begin(), prims.end(), res.begin(),
|
|
||||||
[root](const Primitive<N> &prim) {
|
|
||||||
return Primitive<N + 1>(prim, root);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Produce a mesh of primitives that fill out the volume of the subgroup generated by generators g_gens within the group context
|
|
||||||
*/
|
|
||||||
template<unsigned N>
|
|
||||||
std::vector<Primitive<N>> triangulate(
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens
|
|
||||||
) {
|
|
||||||
if (g_gens.size() + 1 != N) // todo make static assert
|
|
||||||
throw std::logic_error("g_gens size must be one less than N");
|
|
||||||
|
|
||||||
const auto &combos = Combos(g_gens, g_gens.size() - 1);
|
|
||||||
|
|
||||||
std::vector<std::vector<Primitive<N>>> meshes;
|
|
||||||
|
|
||||||
for (const auto &sg_gens : combos) {
|
|
||||||
auto base = triangulate<N - 1>(context, sg_gens);
|
|
||||||
auto raised = tile(base, context, g_gens, sg_gens);
|
|
||||||
raised.erase(raised.begin(), raised.begin() + base.size());
|
|
||||||
meshes.push_back(fan(raised, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return merge(meshes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Single-index primitives should not be further triangulated.
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
std::vector<Primitive<1>> triangulate(
|
|
||||||
const tc::Group &context,
|
|
||||||
const std::vector<int> &g_gens
|
|
||||||
) {
|
|
||||||
if (not g_gens.empty()) // todo make static assert
|
|
||||||
throw std::logic_error("g_gens must be empty for a trivial Mesh");
|
|
||||||
|
|
||||||
std::vector<Primitive<1>> res;
|
|
||||||
res.emplace_back();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned N, class T>
|
|
||||||
auto hull(const tc::Group &group, T all_sg_gens, const std::vector<std::vector<int>> &exclude) {
|
|
||||||
std::vector<std::vector<Primitive<N>>> parts;
|
|
||||||
auto g_gens = generators(group);
|
|
||||||
for (const std::vector<int> &sg_gens : all_sg_gens) {
|
|
||||||
bool excluded = false;
|
|
||||||
for (const auto &test : exclude) {
|
|
||||||
if (sg_gens == test) {
|
|
||||||
excluded = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (excluded) continue;
|
|
||||||
|
|
||||||
const auto &base = triangulate<N>(group, sg_gens);
|
|
||||||
const auto &tiles = each_tile(base, group, g_gens, sg_gens);
|
|
||||||
for (const auto &tile : tiles) {
|
|
||||||
parts.push_back(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parts;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -226,15 +226,6 @@ std::vector<V> plane_intersections(std::vector<V> normals) {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 utilRotate(const int u, const int v, const float theta) {
|
|
||||||
auto res = glm::identity<glm::mat4>();
|
|
||||||
res[u][u] = std::cos(theta);
|
|
||||||
res[u][v] = std::sin(theta);
|
|
||||||
res[v][u] = -std::sin(theta);
|
|
||||||
res[v][v] = std::cos(theta);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<unsigned N>
|
template<unsigned N>
|
||||||
mat<N> identity() {
|
mat<N> identity() {
|
||||||
mat<N> res{};
|
mat<N> res{};
|
||||||
@@ -252,3 +243,12 @@ mat<N> rot(int u, int v, float theta) {
|
|||||||
res[v][v] = std::cos(theta);
|
res[v][v] = std::cos(theta);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat4 ortho(float left, float right, float bottom, float top, float front, float back) {
|
||||||
|
return {
|
||||||
|
2 / (right - left), 0, 0, -(right + left) / (right - left),
|
||||||
|
0, 2 / (top - bottom), 0, -(top + bottom) / (top - bottom),
|
||||||
|
0, 0, 2 / (front - back), -(front + back) / (front - back),
|
||||||
|
0, 0, 0, 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
231
vis/include/solver.hpp
Normal file
231
vis/include/solver.hpp
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <tc/core.hpp>
|
||||||
|
#include <cmath>
|
||||||
|
#include <optional>
|
||||||
|
#include <numeric>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <geometry.hpp>
|
||||||
|
|
||||||
|
#include "combo_iterator.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce a list of all generators for the group context. The range [0..group.ngens).
|
||||||
|
*/
|
||||||
|
std::vector<int> generators(const tc::Group &context) {
|
||||||
|
std::vector<int> g_gens(context.ngens);
|
||||||
|
std::iota(g_gens.begin(), g_gens.end(), 0);
|
||||||
|
return g_gens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine which of g_gens are the correct names for sg_gens within the current context
|
||||||
|
*/
|
||||||
|
std::vector<int> recontext_gens(
|
||||||
|
const tc::Group &context,
|
||||||
|
std::vector<int> g_gens,
|
||||||
|
std::vector<int> sg_gens) {
|
||||||
|
|
||||||
|
std::sort(g_gens.begin(), g_gens.end());
|
||||||
|
|
||||||
|
int inv_gen_map[context.ngens];
|
||||||
|
for (size_t i = 0; i < g_gens.size(); i++) {
|
||||||
|
inv_gen_map[g_gens[i]] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> s_sg_gens;
|
||||||
|
s_sg_gens.reserve(sg_gens.size());
|
||||||
|
for (const auto gen : sg_gens) {
|
||||||
|
s_sg_gens.push_back(inv_gen_map[gen]);
|
||||||
|
}
|
||||||
|
std::sort(s_sg_gens.begin(), s_sg_gens.end());
|
||||||
|
|
||||||
|
return s_sg_gens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solve the cosets generated by sg_gens within the subgroup generated by g_gens of the group context
|
||||||
|
*/
|
||||||
|
tc::Cosets solve(
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens,
|
||||||
|
const std::vector<int> &sg_gens
|
||||||
|
) {
|
||||||
|
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
||||||
|
return context.subgroup(g_gens).solve(proper_sg_gens);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply some context transformation to all primitives of this mesh.
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
std::vector<Primitive<N>> apply(std::vector<Primitive<N>> prims, const tc::Cosets &table, int gen) {
|
||||||
|
for (auto &prim : prims) {
|
||||||
|
prim.apply(table, gen);
|
||||||
|
}
|
||||||
|
return prims;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the indexes of this mesh to those of a different context, using g_gens to build the parent context and sg_gens to build this context.
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
[[nodiscard]]
|
||||||
|
std::vector<Primitive<N>> recontext(
|
||||||
|
std::vector<Primitive<N>> prims,
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens,
|
||||||
|
const std::vector<int> &sg_gens
|
||||||
|
) {
|
||||||
|
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
||||||
|
const auto table = solve(context, g_gens, {});
|
||||||
|
const auto path = solve(context, sg_gens, {}).path;
|
||||||
|
|
||||||
|
auto map = path.template walk<int, int>(0, proper_sg_gens, [table](int coset, int gen) {
|
||||||
|
return table.get(coset, gen);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<Primitive<N>> res(prims);
|
||||||
|
for (Primitive<N> &prim : res) {
|
||||||
|
for (auto &ind : prim.inds) {
|
||||||
|
ind = map[ind];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Union several meshes of the same dimension
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
std::vector<Primitive<N>> merge(const std::vector<std::vector<Primitive<N>>> &meshes) {
|
||||||
|
size_t size = 0;
|
||||||
|
for (const auto &mesh : meshes) {
|
||||||
|
size += mesh.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Primitive<N>> res;
|
||||||
|
res.reserve(size);
|
||||||
|
for (const auto &mesh : meshes) {
|
||||||
|
res.insert(res.end(), mesh.begin(), mesh.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned N>
|
||||||
|
[[nodiscard]]
|
||||||
|
std::vector<std::vector<Primitive<N>>> each_tile(
|
||||||
|
std::vector<Primitive<N>> prims,
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens,
|
||||||
|
const std::vector<int> &sg_gens
|
||||||
|
) {
|
||||||
|
std::vector<Primitive<N>> base = recontext(prims, context, g_gens, sg_gens);
|
||||||
|
const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens);
|
||||||
|
|
||||||
|
const auto table = solve(context, g_gens, {});
|
||||||
|
const auto path = solve(context, g_gens, sg_gens).path;
|
||||||
|
|
||||||
|
auto _gens = generators(context);
|
||||||
|
|
||||||
|
auto res = path.walk<std::vector<Primitive<N>>, int>(base, generators(context), [&](auto from, auto gen) {
|
||||||
|
return apply(from, table, gen);
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned N>
|
||||||
|
[[nodiscard]]
|
||||||
|
std::vector<Primitive<N>> tile(
|
||||||
|
std::vector<Primitive<N>> prims,
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens,
|
||||||
|
const std::vector<int> &sg_gens
|
||||||
|
) {
|
||||||
|
auto res = each_tile<N>(prims, context, g_gens, sg_gens);
|
||||||
|
|
||||||
|
return merge(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce a mesh of higher dimension by fanning a single point to all primitives in this mesh.
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
[[nodiscard]]
|
||||||
|
std::vector<Primitive<N + 1>> fan(std::vector<Primitive<N>> prims, int root) {
|
||||||
|
std::vector<Primitive<N + 1>> res(prims.size());
|
||||||
|
std::transform(prims.begin(), prims.end(), res.begin(),
|
||||||
|
[root](const Primitive<N> &prim) {
|
||||||
|
return Primitive<N + 1>(prim, root);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce a mesh of primitives that fill out the volume of the subgroup generated by generators g_gens within the group context
|
||||||
|
*/
|
||||||
|
template<unsigned N>
|
||||||
|
std::vector<Primitive<N>> triangulate(
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens
|
||||||
|
) {
|
||||||
|
if (g_gens.size() + 1 != N) // todo make static assert
|
||||||
|
throw std::logic_error("g_gens size must be one less than N");
|
||||||
|
|
||||||
|
const auto &combos = Combos(g_gens, g_gens.size() - 1);
|
||||||
|
|
||||||
|
std::vector<std::vector<Primitive<N>>> meshes;
|
||||||
|
|
||||||
|
for (const auto &sg_gens : combos) {
|
||||||
|
auto base = triangulate<N - 1>(context, sg_gens);
|
||||||
|
auto raised = tile(base, context, g_gens, sg_gens);
|
||||||
|
raised.erase(raised.begin(), raised.begin() + base.size());
|
||||||
|
meshes.push_back(fan(raised, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return merge(meshes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single-index primitives should not be further triangulated.
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
std::vector<Primitive<1>> triangulate(
|
||||||
|
const tc::Group &context,
|
||||||
|
const std::vector<int> &g_gens
|
||||||
|
) {
|
||||||
|
if (not g_gens.empty()) // todo make static assert
|
||||||
|
throw std::logic_error("g_gens must be empty for a trivial Mesh");
|
||||||
|
|
||||||
|
std::vector<Primitive<1>> res;
|
||||||
|
res.emplace_back();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned N, class T>
|
||||||
|
auto hull(const tc::Group &group, T all_sg_gens, const std::vector<std::vector<int>> &exclude) {
|
||||||
|
std::vector<std::vector<Primitive<N>>> parts;
|
||||||
|
auto g_gens = generators(group);
|
||||||
|
for (const std::vector<int> &sg_gens : all_sg_gens) {
|
||||||
|
bool excluded = false;
|
||||||
|
for (const auto &test : exclude) {
|
||||||
|
if (sg_gens == test) {
|
||||||
|
excluded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (excluded) continue;
|
||||||
|
|
||||||
|
const auto &base = triangulate<N>(group, sg_gens);
|
||||||
|
const auto &tiles = each_tile(base, group, g_gens, sg_gens);
|
||||||
|
for (const auto &tile : tiles) {
|
||||||
|
parts.push_back(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
#include <tc/groups.hpp>
|
#include <tc/groups.hpp>
|
||||||
|
|
||||||
#include "util.hpp"
|
|
||||||
#include "mirror.hpp"
|
|
||||||
#include "geometry.hpp"
|
|
||||||
|
|
||||||
#include <cgl/vertexarray.hpp>
|
#include <cgl/vertexarray.hpp>
|
||||||
#include <cgl/shaderprogram.hpp>
|
#include <cgl/shaderprogram.hpp>
|
||||||
#include <cgl/pipeline.hpp>
|
#include <cgl/pipeline.hpp>
|
||||||
#include <random>
|
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <yaml-cpp/yaml.h>
|
|
||||||
|
|
||||||
|
#include <util.hpp>
|
||||||
|
#include <mirror.hpp>
|
||||||
#include <rendering.hpp>
|
#include <rendering.hpp>
|
||||||
|
#include <solver.hpp>
|
||||||
|
#include <geometry.hpp>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -28,12 +27,12 @@ __attribute__((unused)) __declspec(dllexport) int NvOptimusEnablement = 0x000000
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Matrices {
|
struct Matrices {
|
||||||
glm::mat4 proj;
|
mat4 proj;
|
||||||
glm::mat4 view;
|
mat4 view;
|
||||||
|
|
||||||
Matrices() = default;
|
Matrices() = default;
|
||||||
|
|
||||||
Matrices(const glm::mat4 &proj, const glm::mat4 &view)
|
Matrices(const mat4 &proj, const mat4 &view)
|
||||||
: proj(proj), view(view) {
|
: proj(proj), view(view) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -54,13 +53,13 @@ Matrices build(GLFWwindow *window, State &state) {
|
|||||||
auto aspect = (float) width / (float) height;
|
auto aspect = (float) width / (float) height;
|
||||||
auto pheight = 1.4f;
|
auto pheight = 1.4f;
|
||||||
auto pwidth = aspect * pheight;
|
auto pwidth = aspect * pheight;
|
||||||
glm::mat4 proj = glm::ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f);
|
mat4 proj = ortho(-pwidth, pwidth, -pheight, pheight, -10.0f, 10.0f);
|
||||||
|
|
||||||
if (!glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)) {
|
if (!glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)) {
|
||||||
state.st += state.time_delta / 8;
|
state.st += state.time_delta / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto view = glm::identity<glm::mat4>();
|
auto view = identity<4>();
|
||||||
return Matrices(proj, view);
|
return Matrices(proj, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user