refactor mesh composition
This commit is contained in:
152
simplex/include/mesh.h
Normal file
152
simplex/include/mesh.h
Normal file
@@ -0,0 +1,152 @@
|
||||
#ifndef SIMPLEX_MESH_H
|
||||
#define SIMPLEX_MESH_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
template<unsigned int prim>
|
||||
struct Mesh {
|
||||
std::vector<glm::vec4> verts;
|
||||
std::vector<unsigned> inds;
|
||||
|
||||
Mesh(std::vector<glm::vec4> verts, std::vector<unsigned> inds)
|
||||
: verts(std::move(verts)), inds(std::move(inds)) {}
|
||||
|
||||
unsigned size() {
|
||||
return (unsigned) inds.size() / prim;
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> concat(Mesh<prim> m, Mesh<prim> n) {
|
||||
Mesh<prim> res({}, {});
|
||||
|
||||
for (auto v: m.verts) res.verts.push_back(v);
|
||||
for (auto v: n.verts) res.verts.push_back(v);
|
||||
|
||||
auto off = (unsigned) m.verts.size();
|
||||
|
||||
for (auto i: m.inds) res.inds.push_back(i);
|
||||
for (auto i: n.inds) res.inds.push_back(off + i);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> transform(Mesh<prim> m, glm::mat4 mat) {
|
||||
Mesh<prim> res(m.verts, m.inds);
|
||||
for (auto &vert : res.verts)
|
||||
vert = mat * vert;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> offset(Mesh<prim> m, glm::vec4 off) {
|
||||
Mesh<prim> res(m.verts, m.inds);
|
||||
for (auto &vert : res.verts)
|
||||
vert += off;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> scale(Mesh<prim> m, glm::vec4 scl) {
|
||||
Mesh<prim> res(m.verts, m.inds);
|
||||
for (auto &vert : res.verts)
|
||||
vert *= scl;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> scale(Mesh<prim> m, float scl) {
|
||||
return scale(m, glm::vec4(scl));
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim + 1> pyramid(Mesh<prim> m, glm::vec4 apex) {
|
||||
Mesh<prim + 1> res(m.verts, {});
|
||||
res.verts.push_back(apex);
|
||||
auto apex_ind = (unsigned) res.verts.size() - 1;
|
||||
|
||||
for (int i = 0; i < m.size(); ++i) {
|
||||
for (int j = 0; j < prim; ++j) {
|
||||
res.inds.push_back(m.inds[i * prim + j]);
|
||||
}
|
||||
res.inds.push_back(apex_ind);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim + 1> fill(Mesh<prim> m) {
|
||||
Mesh<prim + 1> res(m.verts, {});
|
||||
|
||||
for (int i = 0; i < m.size(); ++i) {
|
||||
for (int j = 0; j < prim; ++j) {
|
||||
res.inds.push_back(m.inds[i * prim + j]);
|
||||
}
|
||||
res.inds.push_back(0);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim + 1> join(Mesh<prim> m, Mesh<prim> n) {
|
||||
Mesh<prim + 1> res({}, {});
|
||||
|
||||
for (auto v : m.verts) res.verts.push_back(v);
|
||||
for (auto v : n.verts) res.verts.push_back(v);
|
||||
|
||||
auto off = (unsigned) m.verts.size();
|
||||
auto size = (int) std::min(m.inds.size(), n.inds.size());
|
||||
|
||||
for (int i = 0; i < size; i += prim) {
|
||||
for (int j = 0; j < prim; ++j) {
|
||||
for (int x = j; x < prim; ++x)
|
||||
res.inds.push_back(m.inds[i + x]);
|
||||
for (int x = 0; x <= j; ++x)
|
||||
res.inds.push_back(off + n.inds[i + x]);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim + 1> joinCap(Mesh<prim> m, Mesh<prim> n) {
|
||||
return concat(join(m, n), concat(fill(m), fill(n)));
|
||||
}
|
||||
|
||||
Mesh<4> thicken(const Mesh<3> &m, float thickness) {
|
||||
return joinCap(offset(m, glm::vec4(0, 0, 0, -thickness / 2)), offset(m, glm::vec4(0, 0, 0, thickness / 2)));
|
||||
}
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> operator+(Mesh<prim> m, Mesh<prim> n) { return concat(m, n); }
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> operator+(Mesh<prim> m, glm::vec4 off) { return offset(m, off); }
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> operator-(Mesh<prim> m, glm::vec4 off) { return offset(m, -off); }
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> operator*(Mesh<prim> m, glm::vec4 scl) { return scale(m, scl); }
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> operator/(Mesh<prim> m, glm::vec4 scl) { return scale(m, 1.f / scl); }
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> operator*(Mesh<prim> m, float scl) { return scale(m, scl); }
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> operator/(Mesh<prim> m, float scl) { return scale(m, 1.f / scl); }
|
||||
|
||||
template<unsigned int prim>
|
||||
Mesh<prim> operator*(glm::mat4 mat, Mesh<prim> m) { return transform(m, mat); }
|
||||
|
||||
#endif //SIMPLEX_MESH_H
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <glm/vec4.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <vsr/vsr.h>
|
||||
|
||||
glm::mat4 rotor(glm::vec4 u, glm::vec4 v, float angle) {
|
||||
@@ -12,7 +13,7 @@ glm::mat4 rotor(glm::vec4 u, glm::vec4 v, float angle) {
|
||||
auto eu = *((Vec *) (void *) &u);
|
||||
auto ev = *((Vec *) (void *) &v);
|
||||
|
||||
auto biv = (eu ^ ev).unit() * angle;
|
||||
auto biv = (eu ^ ev).unit() * angle / 2;
|
||||
|
||||
Vec col[4] = {
|
||||
Vec(1, 0, 0, 0).rotate(biv),
|
||||
@@ -24,4 +25,16 @@ glm::mat4 rotor(glm::vec4 u, glm::vec4 v, float angle) {
|
||||
return glm::make_mat4((float *) col);
|
||||
}
|
||||
|
||||
glm::mat4 rot_xy(float angle) { return rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 1, 0, 0), angle); }
|
||||
|
||||
glm::mat4 rot_xz(float angle) { return rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 1, 0), angle); }
|
||||
|
||||
glm::mat4 rot_xw(float angle) { return rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 0, 1), angle); }
|
||||
|
||||
glm::mat4 rot_yz(float angle) { return rotor(glm::vec4(0, 1, 0, 0), glm::vec4(0, 0, 1, 0), angle); }
|
||||
|
||||
glm::mat4 rot_yw(float angle) { return rotor(glm::vec4(0, 1, 0, 0), glm::vec4(0, 0, 0, 1), angle); }
|
||||
|
||||
glm::mat4 rot_zw(float angle) { return rotor(glm::vec4(0, 0, 1, 0), glm::vec4(0, 0, 0, 1), angle); }
|
||||
|
||||
#endif //GL_TEMPLATE_ROTOR_H
|
||||
|
||||
50
simplex/include/solids.h
Normal file
50
simplex/include/solids.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef SIMPLEX_SOLIDS_H
|
||||
#define SIMPLEX_SOLIDS_H
|
||||
|
||||
#include "mesh.h"
|
||||
#include "rotor.h"
|
||||
|
||||
static auto T = (float) PI / 2;
|
||||
|
||||
Mesh<2> poly(int sides) {
|
||||
Mesh<2> res({}, {});
|
||||
|
||||
auto t = (float) (PI * 2 / sides);
|
||||
float t0 = t / 2;
|
||||
auto r = 1 / cos(t0);
|
||||
|
||||
for (int i = 0; i < sides; i++) {
|
||||
glm::vec2 p = r * glm::vec2(cos(t0 + t * i), sin(t0 + t * i));
|
||||
res.verts.emplace_back(p, 0, 0);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sides - 1; i++) {
|
||||
res.inds.push_back(i);
|
||||
res.inds.push_back(i + 1);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Mesh<3> cube() {
|
||||
glm::vec4 off = glm::vec4(0, 0, 1, 0);
|
||||
Mesh<3> face = fill(poly(4));
|
||||
Mesh<3> pair = (face + off) + (face - off);
|
||||
|
||||
return pair +
|
||||
rot_xz(T) * pair +
|
||||
rot_yz(T) * pair;
|
||||
}
|
||||
|
||||
Mesh<4> tesseract() {
|
||||
glm::vec4 off = glm::vec4(0, 0, 0, 1);
|
||||
Mesh<4> cell = fill(cube());
|
||||
Mesh<4> pair = (cell + off) + (cell - off);
|
||||
|
||||
return pair +
|
||||
rot_xw(T) * pair +
|
||||
rot_yw(T) * pair +
|
||||
rot_zw(T) * pair;
|
||||
}
|
||||
|
||||
#endif //SIMPLEX_SOLIDS_H
|
||||
Reference in New Issue
Block a user