realtime rotations
This commit is contained in:
@@ -10,7 +10,6 @@ namespace ga {
|
|||||||
|
|
||||||
Vec(float x, float y, float z, float w) :
|
Vec(float x, float y, float z, float w) :
|
||||||
x(x), y(y), z(z), w(w) {}
|
x(x), y(y), z(z), w(w) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Bivec {
|
struct Bivec {
|
||||||
@@ -29,11 +28,11 @@ namespace ga {
|
|||||||
namespace unit {
|
namespace unit {
|
||||||
Vec x() { return Vec(1, 0, 0, 0); };
|
Vec x() { return Vec(1, 0, 0, 0); };
|
||||||
|
|
||||||
Vec y() { return Vec(1, 0, 0, 0); };
|
Vec y() { return Vec(0, 1, 0, 0); };
|
||||||
|
|
||||||
Vec z() { return Vec(1, 0, 0, 0); };
|
Vec z() { return Vec(0, 0, 1, 0); };
|
||||||
|
|
||||||
Vec w() { return Vec(1, 0, 0, 0); };
|
Vec w() { return Vec(0, 0, 0, 1); };
|
||||||
|
|
||||||
Bivec xy() { return Bivec(1, 0, 0, 0, 0, 0); }
|
Bivec xy() { return Bivec(1, 0, 0, 0, 0, 0); }
|
||||||
|
|
||||||
@@ -46,6 +45,8 @@ namespace ga {
|
|||||||
Bivec xz() { return Bivec(0, 0, 0, 0, 1, 0); }
|
Bivec xz() { return Bivec(0, 0, 0, 0, 1, 0); }
|
||||||
|
|
||||||
Bivec yw() { return Bivec(0, 0, 0, 0, 0, 1); }
|
Bivec yw() { return Bivec(0, 0, 0, 0, 0, 1); }
|
||||||
|
|
||||||
|
Mat identity() { return Mat(x(), y(), z(), w()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
float length2(Vec v) {
|
float length2(Vec v) {
|
||||||
@@ -93,6 +94,28 @@ namespace ga {
|
|||||||
c * v.yw);
|
c * v.yw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec mul(Mat m, Vec v) {
|
||||||
|
return add(add(mul(v.x, m.x), mul(v.y, m.y)), add(mul(v.z, m.z), mul(v.w, m.w)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat mul(Mat m, Mat n) {
|
||||||
|
return Mat(
|
||||||
|
mul(m, n.x),
|
||||||
|
mul(m, n.y),
|
||||||
|
mul(m, n.z),
|
||||||
|
mul(m, n.w)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat mul(float c, Mat m) {
|
||||||
|
return Mat(
|
||||||
|
mul(c, m.x),
|
||||||
|
mul(c, m.y),
|
||||||
|
mul(c, m.z),
|
||||||
|
mul(c, m.w)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Vec normalize(Vec v) {
|
Vec normalize(Vec v) {
|
||||||
return mul(1 / length(v), v);
|
return mul(1 / length(v), v);
|
||||||
}
|
}
|
||||||
@@ -101,21 +124,42 @@ namespace ga {
|
|||||||
return mul(1 / length(v), v);
|
return mul(1 / length(v), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec tform(float c, Vec v) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec tform(Vec u, Vec v) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec tform(Bivec u, Vec v) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Mat matrix(float c) {
|
Mat matrix(float c) {
|
||||||
// c as a transformation
|
auto m = unit::identity();
|
||||||
// scale by c
|
m.x = tform(c, m.x);
|
||||||
return Mat(Vec(c, 0, 0, 0), Vec(0, c, 0, 0), Vec(0, 0, c, 0), Vec(0, 0, 0, c));
|
m.y = tform(c, m.y);
|
||||||
|
m.z = tform(c, m.z);
|
||||||
|
m.w = tform(c, m.w);
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat matrix(Vec v) {
|
Mat matrix(Vec v) {
|
||||||
// v as a transformation
|
auto m = unit::identity();
|
||||||
// reflect along v
|
m.x = tform(v, m.x);
|
||||||
return matrix(1); // todo reflection
|
m.y = tform(v, m.y);
|
||||||
|
m.z = tform(v, m.z);
|
||||||
|
m.w = tform(v, m.w);
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat rotor(Bivec v) {
|
Mat matrix(Bivec v) {
|
||||||
// v as a transformation
|
auto m = unit::identity();
|
||||||
// rotate along v
|
m.x = tform(v, m.x);
|
||||||
return matrix(1);
|
m.y = tform(v, m.y);
|
||||||
|
m.z = tform(v, m.z);
|
||||||
|
m.w = tform(v, m.w);
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#define PI 3.14159
|
#define PI 3.14159
|
||||||
|
|
||||||
|
uniform float bright;
|
||||||
|
|
||||||
in vec4 pos;
|
in vec4 pos;
|
||||||
in vec4 pos4;
|
in vec4 pos4;
|
||||||
in vec4 pos3;
|
in vec4 pos3;
|
||||||
@@ -11,7 +13,8 @@ out vec4 color;
|
|||||||
void main() {
|
void main() {
|
||||||
float light = -pos3.y / 10 + .5;
|
float light = -pos3.y / 10 + .5;
|
||||||
|
|
||||||
vec3 col = vec3(1);
|
vec3 col = vec3(bright);
|
||||||
|
|
||||||
color = vec4(col * light, 1);
|
//color = vec4(col * light, 1);
|
||||||
|
color = vec4(col, 1);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#version 440
|
#version 440
|
||||||
|
|
||||||
#define CIRCLE_RES 64
|
#define CIRCLE_RES 128
|
||||||
#define PI 3.14159
|
#define PI 3.14159
|
||||||
|
|
||||||
layout(points) in;
|
layout(points) in;
|
||||||
|
|||||||
@@ -121,13 +121,17 @@ struct HopfCircle {
|
|||||||
struct State {
|
struct State {
|
||||||
GLuint vao{};
|
GLuint vao{};
|
||||||
GLuint vbo{}, ubo{};
|
GLuint vbo{}, ubo{};
|
||||||
|
GLuint unif_bright{};
|
||||||
GLuint ubo_bp = 1;
|
GLuint ubo_bp = 1;
|
||||||
|
|
||||||
GLuint prog{};
|
GLuint prog{};
|
||||||
|
|
||||||
std::vector<HopfCircle> circles{};
|
std::vector<HopfCircle> circles{};
|
||||||
|
ga::Mat rot = ga::unit::identity();
|
||||||
|
float view = 4.f;
|
||||||
|
|
||||||
float t = 0;
|
float t = 0;
|
||||||
|
float dt = 0;
|
||||||
|
|
||||||
void regen() {
|
void regen() {
|
||||||
circles.clear();
|
circles.clear();
|
||||||
@@ -136,10 +140,10 @@ struct State {
|
|||||||
const int M = 4;
|
const int M = 4;
|
||||||
const float PAD = 0.0125;
|
const float PAD = 0.0125;
|
||||||
|
|
||||||
for (int k = 0; k <= N; ++k) {
|
for (int x = 0; x <= N; ++x) {
|
||||||
for (int j = 0; j <= M; ++j) {
|
for (int e = 1; e < M; ++e) {
|
||||||
float xi = 2 * PI * k / N;
|
float xi = 2 * PI * x / N;
|
||||||
float eta = (PI / 2 - 2 * PAD) * j / M + PAD;
|
float eta = (PI / 2 - 2 * PAD) * e / M + PAD;
|
||||||
circles.emplace_back(xi, eta);
|
circles.emplace_back(xi, eta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,6 +156,10 @@ struct State {
|
|||||||
explicit State(GLFWwindow *window) {
|
explicit State(GLFWwindow *window) {
|
||||||
printf("vendor: %s\nrenderer: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
|
printf("vendor: %s\nrenderer: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
|
||||||
|
|
||||||
|
float lw[2];
|
||||||
|
glGetFloatv(GL_LINE_WIDTH_RANGE, lw);
|
||||||
|
printf("line width range: %.2f to %.2f\n", lw[0], lw[1]);
|
||||||
|
|
||||||
glGenBuffers(1, &vbo);
|
glGenBuffers(1, &vbo);
|
||||||
glGenBuffers(1, &ubo);
|
glGenBuffers(1, &ubo);
|
||||||
glGenVertexArrays(1, &vao);
|
glGenVertexArrays(1, &vao);
|
||||||
@@ -165,6 +173,8 @@ struct State {
|
|||||||
GLuint fs = util::buildShader(GL_FRAGMENT_SHADER, "fs", {"shaders/main.frag"});
|
GLuint fs = util::buildShader(GL_FRAGMENT_SHADER, "fs", {"shaders/main.frag"});
|
||||||
prog = util::buildProgram(false, "prog", {vs, gs, fs});
|
prog = util::buildProgram(false, "prog", {vs, gs, fs});
|
||||||
|
|
||||||
|
unif_bright = (GLuint) glGetUniformLocation(prog, "bright");
|
||||||
|
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
@@ -204,17 +214,11 @@ struct State {
|
|||||||
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
|
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
|
||||||
util::bufferData<ga::Mat>(GL_UNIFORM_BUFFER, {
|
util::bufferData<ga::Mat>(GL_UNIFORM_BUFFER, {
|
||||||
ga::Mat(
|
ga::Mat(
|
||||||
ga::Vec(1.f / 4 / ar, 0, 0, 0),
|
ga::Vec(1.f / view / ar, 0, 0, 0),
|
||||||
ga::Vec(0, 0, 1.f / 10, 0),
|
ga::Vec(0, 0, 1.f / 10, 0),
|
||||||
ga::Vec(0, 1.f / 4, 0, 0),
|
ga::Vec(0, 1.f / view, 0, 0),
|
||||||
ga::Vec(0, 0, 0, 1.f)),
|
ga::Vec(0, 0, 0, 1.f)),
|
||||||
|
rot
|
||||||
ga::Mat(
|
|
||||||
ga::Vec(c, 0, 0, s),
|
|
||||||
ga::Vec(0, c_, s_, 0),
|
|
||||||
ga::Vec(0, -s_, c_, 0),
|
|
||||||
ga::Vec(-s, 0, 0, c)
|
|
||||||
)
|
|
||||||
}, GL_STREAM_DRAW);
|
}, GL_STREAM_DRAW);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
}
|
}
|
||||||
@@ -226,12 +230,20 @@ struct State {
|
|||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
|
||||||
glUseProgram(prog);
|
glUseProgram(prog);
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glPointSize(5);
|
|
||||||
glLineWidth(5);
|
glLineWidth(10);
|
||||||
|
glUniform1f(unif_bright, 0);
|
||||||
glDrawArrays(GL_POINTS, 0, (unsigned) circles.size());
|
glDrawArrays(GL_POINTS, 0, (unsigned) circles.size());
|
||||||
|
|
||||||
|
glLineWidth(1);
|
||||||
|
glUniform1f(unif_bright, 1);
|
||||||
|
glDrawArrays(GL_POINTS, 0, (unsigned) circles.size());
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
@@ -239,10 +251,100 @@ struct State {
|
|||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void on_scroll(GLFWwindow *window, double xoffset, double yoffset) {
|
||||||
|
printf("scroll %.2f %.2f\n", xoffset, yoffset);
|
||||||
|
|
||||||
|
int xw = glfwGetKey(window, GLFW_KEY_Q);
|
||||||
|
int yw = glfwGetKey(window, GLFW_KEY_W);
|
||||||
|
int zw = glfwGetKey(window, GLFW_KEY_E);
|
||||||
|
int xy = glfwGetKey(window, GLFW_KEY_A);
|
||||||
|
int yz = glfwGetKey(window, GLFW_KEY_S);
|
||||||
|
int zx = glfwGetKey(window, GLFW_KEY_D);
|
||||||
|
|
||||||
|
int zoom = glfwGetKey(window, GLFW_KEY_LEFT_CONTROL);
|
||||||
|
|
||||||
|
float t = (float) yoffset * PI / 48;
|
||||||
|
float c = std::cos(t);
|
||||||
|
float s = std::sin(t);
|
||||||
|
|
||||||
|
if (xw) {
|
||||||
|
rot = ga::mul(rot, ga::Mat(
|
||||||
|
ga::Vec(c, 0, 0, s),
|
||||||
|
ga::Vec(0, 1, 0, 0),
|
||||||
|
ga::Vec(0, 0, 1, 0),
|
||||||
|
ga::Vec(-s, 0, 0, c)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yw) {
|
||||||
|
rot = ga::mul(rot, ga::Mat(
|
||||||
|
ga::Vec(1, 0, 0, 0),
|
||||||
|
ga::Vec(0, c, 0, s),
|
||||||
|
ga::Vec(0, 0, 1, 0),
|
||||||
|
ga::Vec(0, -s, 0, c)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zw) {
|
||||||
|
rot = ga::mul(rot, ga::Mat(
|
||||||
|
ga::Vec(1, 0, 0, 0),
|
||||||
|
ga::Vec(0, 1, 0, 0),
|
||||||
|
ga::Vec(0, 0, c, s),
|
||||||
|
ga::Vec(0, 0, -s, c)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xy) {
|
||||||
|
rot = ga::mul(rot, ga::Mat(
|
||||||
|
ga::Vec(c, s, 0, 0),
|
||||||
|
ga::Vec(-s, c, 0, 0),
|
||||||
|
ga::Vec(0, 0, 1, 0),
|
||||||
|
ga::Vec(0, 0, 0, 1)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yz) {
|
||||||
|
rot = ga::mul(rot, ga::Mat(
|
||||||
|
ga::Vec(1, 0, 0, 0),
|
||||||
|
ga::Vec(0, c, s, 0),
|
||||||
|
ga::Vec(0, -s, c, 0),
|
||||||
|
ga::Vec(0, 0, 0, 1)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zx) {
|
||||||
|
rot = ga::mul(rot, ga::Mat(
|
||||||
|
ga::Vec(c, 0, -s, 0),
|
||||||
|
ga::Vec(0, 1, 0, 0),
|
||||||
|
ga::Vec(s, 0, c, 0),
|
||||||
|
ga::Vec(0, 0, 0, 1)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zoom) {
|
||||||
|
view *= 1 - t / 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream matfile;
|
||||||
|
matfile.open("matrix.txt");
|
||||||
|
matfile << "vec((\n";
|
||||||
|
matfile << "vec((" << rot.x.x << ", " << rot.x.y << ", " << rot.x.z << ", " << rot.x.w << ")),\n";
|
||||||
|
matfile << "vec((" << rot.y.x << ", " << rot.y.y << ", " << rot.y.z << ", " << rot.y.w << ")),\n";
|
||||||
|
matfile << "vec((" << rot.z.x << ", " << rot.z.y << ", " << rot.z.z << ", " << rot.z.w << ")),\n";
|
||||||
|
matfile << "vec((" << rot.w.x << ", " << rot.w.y << ", " << rot.w.z << ", " << rot.w.w << ")),\n";
|
||||||
|
matfile << ")),";
|
||||||
|
matfile.close();
|
||||||
|
}
|
||||||
|
|
||||||
void deinit(GLFWwindow *window) {
|
void deinit(GLFWwindow *window) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
|
||||||
|
auto *state = (State *) glfwGetWindowUserPointer(window);
|
||||||
|
state->on_scroll(window, xoffset, yoffset);
|
||||||
|
}
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
|
||||||
@@ -259,6 +361,9 @@ void run() {
|
|||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
|
|
||||||
auto state = State(window);
|
auto state = State(window);
|
||||||
|
glfwSetWindowUserPointer(window, &state);
|
||||||
|
|
||||||
|
glfwSetScrollCallback(window, scroll_callback);
|
||||||
|
|
||||||
double time = glfwGetTime();
|
double time = glfwGetTime();
|
||||||
int frame = 0;
|
int frame = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user