realtime rotations

This commit is contained in:
2019-02-07 23:38:05 -05:00
parent e5092e9c6b
commit 2298a4fef9
4 changed files with 184 additions and 32 deletions

View File

@@ -10,7 +10,6 @@ namespace ga {
Vec(float x, float y, float z, float w) :
x(x), y(y), z(z), w(w) {}
};
struct Bivec {
@@ -29,11 +28,11 @@ namespace ga {
namespace unit {
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); }
@@ -46,6 +45,8 @@ namespace ga {
Bivec xz() { return Bivec(0, 0, 0, 0, 1, 0); }
Bivec yw() { return Bivec(0, 0, 0, 0, 0, 1); }
Mat identity() { return Mat(x(), y(), z(), w()); }
}
float length2(Vec v) {
@@ -93,6 +94,28 @@ namespace ga {
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) {
return mul(1 / length(v), v);
}
@@ -101,21 +124,42 @@ namespace ga {
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) {
// c as a transformation
// scale by c
return Mat(Vec(c, 0, 0, 0), Vec(0, c, 0, 0), Vec(0, 0, c, 0), Vec(0, 0, 0, c));
auto m = unit::identity();
m.x = tform(c, m.x);
m.y = tform(c, m.y);
m.z = tform(c, m.z);
m.w = tform(c, m.w);
return m;
}
Mat matrix(Vec v) {
// v as a transformation
// reflect along v
return matrix(1); // todo reflection
auto m = unit::identity();
m.x = tform(v, m.x);
m.y = tform(v, m.y);
m.z = tform(v, m.z);
m.w = tform(v, m.w);
return m;
}
Mat rotor(Bivec v) {
// v as a transformation
// rotate along v
return matrix(1);
Mat matrix(Bivec v) {
auto m = unit::identity();
m.x = tform(v, m.x);
m.y = tform(v, m.y);
m.z = tform(v, m.z);
m.w = tform(v, m.w);
return m;
}
}

View File

@@ -2,6 +2,8 @@
#define PI 3.14159
uniform float bright;
in vec4 pos;
in vec4 pos4;
in vec4 pos3;
@@ -11,7 +13,8 @@ out vec4 color;
void main() {
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);
}

View File

@@ -1,6 +1,6 @@
#version 440
#define CIRCLE_RES 64
#define CIRCLE_RES 128
#define PI 3.14159
layout(points) in;

View File

@@ -121,13 +121,17 @@ struct HopfCircle {
struct State {
GLuint vao{};
GLuint vbo{}, ubo{};
GLuint unif_bright{};
GLuint ubo_bp = 1;
GLuint prog{};
std::vector<HopfCircle> circles{};
ga::Mat rot = ga::unit::identity();
float view = 4.f;
float t = 0;
float dt = 0;
void regen() {
circles.clear();
@@ -136,10 +140,10 @@ struct State {
const int M = 4;
const float PAD = 0.0125;
for (int k = 0; k <= N; ++k) {
for (int j = 0; j <= M; ++j) {
float xi = 2 * PI * k / N;
float eta = (PI / 2 - 2 * PAD) * j / M + PAD;
for (int x = 0; x <= N; ++x) {
for (int e = 1; e < M; ++e) {
float xi = 2 * PI * x / N;
float eta = (PI / 2 - 2 * PAD) * e / M + PAD;
circles.emplace_back(xi, eta);
}
}
@@ -152,6 +156,10 @@ struct State {
explicit State(GLFWwindow *window) {
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, &ubo);
glGenVertexArrays(1, &vao);
@@ -165,6 +173,8 @@ struct State {
GLuint fs = util::buildShader(GL_FRAGMENT_SHADER, "fs", {"shaders/main.frag"});
prog = util::buildProgram(false, "prog", {vs, gs, fs});
unif_bright = (GLuint) glGetUniformLocation(prog, "bright");
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
@@ -204,17 +214,11 @@ struct State {
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
util::bufferData<ga::Mat>(GL_UNIFORM_BUFFER, {
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, 1.f / 4, 0, 0),
ga::Vec(0, 1.f / view, 0, 0),
ga::Vec(0, 0, 0, 1.f)),
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)
)
rot
}, GL_STREAM_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
@@ -226,12 +230,20 @@ struct State {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_LEQUAL);
glUseProgram(prog);
glBindVertexArray(vao);
glEnable(GL_DEPTH_TEST);
glPointSize(5);
glLineWidth(5);
glLineWidth(10);
glUniform1f(unif_bright, 0);
glDrawArrays(GL_POINTS, 0, (unsigned) circles.size());
glLineWidth(1);
glUniform1f(unif_bright, 1);
glDrawArrays(GL_POINTS, 0, (unsigned) circles.size());
glBindVertexArray(0);
glUseProgram(0);
@@ -239,10 +251,100 @@ struct State {
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 scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
auto *state = (State *) glfwGetWindowUserPointer(window);
state->on_scroll(window, xoffset, yoffset);
}
void run() {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
@@ -259,6 +361,9 @@ void run() {
glfwSwapInterval(0);
auto state = State(window);
glfwSetWindowUserPointer(window, &state);
glfwSetScrollCallback(window, scroll_callback);
double time = glfwGetTime();
int frame = 0;