adding in the axes for all the camera poses. failing to read the file properly though

This commit is contained in:
2025-08-21 23:54:05 -05:00
parent 8b816f8296
commit 19f786ee7c
10 changed files with 177 additions and 69 deletions

View File

@@ -140,6 +140,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\body.cpp" />
<ClCompile Include="src\camera_poses.cpp" />
<ClCompile Include="src\glad.c" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\shaders.cpp" />

View File

@@ -30,5 +30,8 @@
<ClCompile Include="src\body.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\camera_poses.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -4,17 +4,17 @@
#include <glm/glm.hpp>
#include "util.hpp"
struct body {
struct Body {
glm::mat4 pose;
float scale;
uint ebo;
uint vao;
uint vbo;
uint shader;
array<float> verts;
array<int> faces;
Array<float> verts;
Array<int> faces;
glm::vec4 color;
};
bool load_body(body* out_body, const char* obj_filepath);
void draw_body(const body& b);
bool load_body(Body* out_body, const char* obj_filepath);
void draw_body(const Body& b);

6
inc/camera_poses.hpp Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include "util.hpp"
#include "body.hpp"
bool parse_poses(Array<Body> *bodies_out, const char* filepath);

View File

@@ -1,6 +1,9 @@
#pragma once
#include <cstdlib>
#include <glm/ext/matrix_float4x4.hpp>
#include <glm/ext/quaternion_float.hpp>
#include <glm/ext/vector_float4.hpp>
#include <stdio.h>
#define min(a, b) ((a < b) ? a : b)
@@ -8,17 +11,19 @@
typedef unsigned int uint;
template<class T> struct array {
template<class T> struct Array {
T* data;
size_t len;
size_t cap;
inline T& operator[](int i) { return data[i]; }
};
template<class T> void append(array<T>& a, T el);
template<class T> T pop(array<T>& a);
template<class T> void resize(array<T>& a, size_t new_cap);
template<class T> void clear(array<T>& a);
bool read_file(array<char>* out, const char* filepath);
array<char*> split_str(const char *s, char delimiter);
array<char*> split_str(const char *s);
template<class T> void append(Array<T>& a, T el);
template<class T> T pop(Array<T>& a);
template<class T> void resize(Array<T>& a, size_t new_cap);
template<class T> void clear(Array<T>& a);
bool read_file(Array<char>* out, const char* filepath);
Array<char*> split_str(const char* s, char delimiter);
Array<char*> split_str(const char* s);
glm::mat4 quat_to_mat4(glm::quat q);

View File

@@ -11,8 +11,8 @@ enum class ParserState {
FACE_SKIP,
};
bool load_body(body* out_body, const char* obj_filepath) {
array<char> source;
bool load_body(Body* out_body, const char* obj_filepath) {
Array<char> source;
if (!read_file(&source, obj_filepath)) {
return false;
}
@@ -27,8 +27,8 @@ bool load_body(body* out_body, const char* obj_filepath) {
}
}
array<float> verts = { (float*)malloc(sizeof(float) * num_verts * 3), num_verts * 3 };
array<int> faces = { (int*)malloc(sizeof(int) * num_faces * 3), num_faces*3 };
Array<float> verts = { (float*)malloc(sizeof(float) * num_verts * 3), num_verts * 3 };
Array<int> faces = { (int*)malloc(sizeof(int) * num_faces * 3), num_faces*3 };
// Get ready for the parsing loop
ParserState state = ParserState::PREFIX;
@@ -114,9 +114,9 @@ bool load_body(body* out_body, const char* obj_filepath) {
return true;
}
void draw_body(const body& b) {
void draw_body(const Body& b) {
use_shader(b.shader);
set_uniform(b.shader, "global_t", b.pose);
set_uniform(b.shader, "global_t", b.scale*b.pose);
set_uniform(b.shader, "color", b.color);
glBindVertexArray(b.vao);
glDrawElements(GL_TRIANGLES, b.faces.len, GL_UNSIGNED_INT, 0);

71
src/camera_poses.cpp Normal file
View File

@@ -0,0 +1,71 @@
#include <body.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <glm/glm.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/vector_float3.hpp>
#include <glm/matrix.hpp>
#include <util.hpp>
#include "camera_poses.hpp"
#define LINE_BUF_SIZE 128
#define NUM_SPHERES_PER_AXE 25
#define SPACE_PER_SPHERE 10.0f
glm::vec4 red_color = glm::vec4(1, 0, 0, 1);
glm::vec4 green_color = glm::vec4(0, 1, 0, 1);
glm::vec4 blue_color = glm::vec4(0, 0, 1, 1);
bool parse_poses(Array<Body>* bodies_out, const char* filepath) {
FILE* fp;
if (!fopen_s(&fp, filepath, "rb")) {
printf("Error parsing poses csv: %s\n", filepath);
return false;
}
char delim = ',';
char line[LINE_BUF_SIZE];
// read in header
fgets(line, LINE_BUF_SIZE, fp);
while (!feof(fp)) {
fgets(line, LINE_BUF_SIZE, fp);
Array<char*> words = split_str(line, delim);
float x = atof(words[0]);
float y = atof(words[1]);
float z = atof(words[2]);
float w = atof(words[3]);
float i = atof(words[4]);
float j = atof(words[5]);
float k = atof(words[6]);
glm::mat4 pose = glm::translate(quat_to_mat4(glm::quat(w, i, j, k)), glm::vec3(x, y, z));
// because clang refuses to cooperate with my append implementation and generate the function code...
*bodies_out
= { (Body*)malloc(sizeof(Body) * 3 * NUM_SPHERES_PER_AXE * 14), 3 * NUM_SPHERES_PER_AXE * 14 };
// Generate axis spheres
for (int i = 0; i < 3; i++) {
for (int j = 0; j < NUM_SPHERES_PER_AXE; j++) {
Body b;
if (!load_body(&b, "Icosphere.obj")) {
return false;
}
// How far along the axis is this ball
glm::vec3 trans = glm::vec3(0, 0, 0);
trans[i] = (float)j * SPACE_PER_SPHERE;
// Now move the translated pose via the camera's pose
b.pose = pose * glm::translate(b.pose, trans);
bodies_out->data[i*j + j] = b;
}
}
}
}

View File

@@ -15,6 +15,7 @@
#include "util.hpp"
#include "shaders.hpp"
#include "body.hpp"
#include "camera_poses.hpp"
static GLFWwindow* window;
static float width, height;
@@ -31,7 +32,7 @@ void process_input() {
}
static uint shader;
void create_new_sphere(body* b, float scale=1) {
void create_new_sphere(Body* b, float scale = 1) {
assert(load_body(b, "Icosphere.obj"));
b->shader = shader;
b->scale = scale;
@@ -40,14 +41,16 @@ void create_new_sphere(body* b, float scale=1) {
static bool stop = false;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
const float max_hp = 10; // Number of scans (without a particular barcode) for which the sphere will still be visible
static std::vector<std::tuple<char*, body*, float>> camera_bodies; // I would use my array here, but was getting a linking error
const float max_hp
= 10; // Number of scans (without a particular barcode) for which the sphere will still be visible
static std::vector<std::tuple<char*, Body*, float>>
camera_bodies; // I would use my array here, but was getting a linking error
void* process_cin(void* args) {
std::string line;
while (true) {
std::getline(std::cin, line);
array<char*> words = split_str(line.c_str());
Array<char*> words = split_str(line.c_str());
assert(words.len == 4);
printf("Received: %s, %s, %s, %s\n", words[0], words[1], words[2], words[3]); // echo for debugging
float x = atof(words[1]);
@@ -62,17 +65,19 @@ void *process_cin(void* args) {
transl = 0.9f * transl + 0.1f * glm::vec4(new_loc, 1); // filter
int color_i = i + 1;
std::get<1>(camera_bodies[i])->color = glm::vec4(color_i&0x4, color_i&0x2, color_i&0x1, 1);
std::get<1>(camera_bodies[i])->color
= glm::vec4(color_i & 0x4, color_i & 0x2, color_i & 0x1, 1);
std::get<2>(camera_bodies[i]) = max_hp;
found_match = true;
} else if (std::get<1>(camera_bodies[i])) {
float& cur_hp = std::get<2>(camera_bodies[i]);
if (cur_hp > 0) cur_hp -= 1;
if (cur_hp > 0)
cur_hp -= 1;
std::get<1>(camera_bodies[i])->color = glm::vec4(i & 0x4, i & 0x2, i & 0x1, cur_hp / max_hp);
}
}
if (!found_match) {
auto t = std::make_tuple(words[0], (body*)NULL, max_hp);
auto t = std::make_tuple(words[0], (Body*)NULL, max_hp);
camera_bodies.push_back(t);
}
pthread_mutex_unlock(&lock);
@@ -91,7 +96,6 @@ static glm::vec3 camera_loc = glm::vec3(0, 0, -1);
static glm::vec3 up = glm::vec3(0, 1, 0);
static glm::mat4 world_to_camera = glm::lookAt(camera_loc, focal_point, up);
static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) {
float dx = (xpos - prev_cursor_x);
float dy = (ypos - prev_cursor_y);
@@ -185,15 +189,9 @@ int main() {
glfwSwapBuffers(window); // front buffer is now back
glClear(GL_COLOR_BUFFER_BIT); // Write to back buffer again (former front buf)
body b;
assert(load_body(&b, "Icosphere.obj"));
b.shader = shader;
b.pose = glm::translate(b.pose, glm::vec3(5, 5, 5));
b.color = glm::vec4(1, 0, 0, 1);
body b2;
/*Body b2;
create_new_sphere(&b2);
b2.color = glm::vec4(0, 0.5, 0, 1);
b2.color = glm::vec4(0, 0.5, 0, 1);*/
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// set_uniform(shader, "color", glm::vec4 { sin(time), sin(time + glm::radians(45.0f)), sin(time +
@@ -208,28 +206,33 @@ int main() {
pthread_t thread_id;
pthread_create(&thread_id, NULL, process_cin, NULL);
Array<Body> camera_pose_axes;
if (!parse_poses(&camera_pose_axes, "poses.csv")) {
return -1;
}
while (!glfwWindowShouldClose(window)) {
process_input();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
set_uniform(shader, "camera_t", world_to_camera);
set_uniform(shader, "projection_t", projection_t);
draw_body(b);
draw_body(b2);
pthread_mutex_lock(&lock);
for (int i = 0; i < camera_pose_axes.len; i++) {
draw_body(camera_pose_axes[i]);
}
if (pthread_mutex_trylock(&lock)) {
for (int i = 0; i < camera_bodies.size(); i++) {
if (!std::get<1>(camera_bodies[i])) {
body* b = (body*)malloc(sizeof(body));
Body* b = (Body*)malloc(sizeof(Body));
create_new_sphere(b);
b->color = glm::vec4(i & 0x4, i & 0x2, i & 0x1, max_hp);
std::get<1>(camera_bodies[i]) = b;
}
draw_body(*std::get<1>(camera_bodies[i]));
}
pthread_mutex_unlock(&lock);
}
glfwSwapBuffers(window);
glfwPollEvents();

View File

@@ -68,7 +68,7 @@ void set_uniform(uint id, const char* name, uniform_variant value) {
}
bool _compile_shader(uint *out_id, const char* filepath, int shader_type) {
array<char> source;
Array<char> source;
if (!read_file(&source, filepath))
return false;

View File

@@ -3,12 +3,14 @@
#include <cstring>
#include <cwctype>
#include <stdlib.h>
#include <glm/ext/quaternion_float.hpp>
#include <glm/mat4x4.hpp>
#include "util.hpp"
array<char*> _split_str_inner(const char* s, char delim, bool just_check_ws);
Array<char*> _split_str_inner(const char* s, char delim, bool just_check_ws);
template<class T> void append(array<T>& a, T el) {
template<class T> void append(Array<T>& a, T el) {
if (a.len == a.cap) {
resize(a, max(8, a.cap * 2));
}
@@ -16,13 +18,13 @@ template<class T> void append(array<T>& a, T el) {
a.len++;
}
template<class T> T pop(array<T>& a) {
template<class T> T pop(Array<T>& a) {
assert(a.len >= 1);
a.len--;
return a.data[a.len + 1];
}
template<class T> void resize(array<T>& a, size_t new_cap) {
template<class T> void resize(Array<T>& a, size_t new_cap) {
T* new_data = (T*)malloc(sizeof(T) * new_cap);
if (a.len > 0) {
memcpy(new_data, a.data, min(a.len, new_cap));
@@ -33,11 +35,11 @@ template<class T> void resize(array<T>& a, size_t new_cap) {
a.cap = new_cap;
}
template<class T> void clear(array<T>& a) {
template<class T> void clear(Array<T>& a) {
a.len = 0;
}
bool read_file(array<char>* out, const char* filepath) {
bool read_file(Array<char>* out, const char* filepath) {
FILE* fp = NULL;
if (fopen_s(&fp, filepath, "rb") != 0) {
printf("ERROR Failed to open file %s\n", filepath);
@@ -56,16 +58,16 @@ bool read_file(array<char>* out, const char* filepath) {
return true;
}
array<char*> split_str(const char* s, char delimiter) { return _split_str_inner(s, delimiter, false); }
Array<char*> split_str(const char* s, char delimiter) { return _split_str_inner(s, delimiter, false); }
array<char*> split_str(const char* s) { return _split_str_inner(s, ' ', true); }
Array<char*> split_str(const char* s) { return _split_str_inner(s, ' ', true); }
array<char*> _split_str_inner(const char* s, char delim, bool just_check_ws) {
array<char*> res = { NULL, 0, 0 };
Array<char*> _split_str_inner(const char* s, char delim, bool just_check_ws) {
Array<char*> res = { NULL, 0, 0 };
char c;
int i = 0;
array<char> cur_word = { NULL, 0, 0 };
Array<char> cur_word = { NULL, 0, 0 };
while (true) {
c = s[i++];
bool is_delim = just_check_ws ? iswspace(c) : c == delim;
@@ -89,3 +91,20 @@ array<char*> _split_str_inner(const char* s, char delim, bool just_check_ws) {
}
return res;
}
// https://songho.ca/opengl/gl_quaternion.html
glm::mat4 quat_to_mat4(glm::quat q) {
glm::vec4 col0 = glm::vec4(
1 - 2 * q.y * q.y - 2 * q.z * q.z, 2 * q.x * q.y + 2 * q.w * q.z, 2 * q.x * q.z - 2 * q.w * q.y, 0);
glm::vec4 col1 = glm::vec4(
2 * q.x * q.y - 2 * q.w * q.z, 1 - 2 * q.x * q.x - 2 * q.z * q.z, 2 * q.y * q.z + 2 * q.w * q.x, 0);
glm::vec4 col2 = glm::vec4(
2 * q.x * q.z + 2 * q.w * q.y, 2 * q.y * q.z - 2 * q.w * q.x, 1 - 2 * q.x * q.x - 2 * q.y * q.y, 0);
glm::vec4 col3 = glm::vec4(0, 0, 0, 1);
return glm::mat4(col0, col1, col2, col3);
}