adding in the axes for all the camera poses. failing to read the file properly though
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
10
inc/body.hpp
10
inc/body.hpp
@@ -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
6
inc/camera_poses.hpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "util.hpp"
|
||||
#include "body.hpp"
|
||||
|
||||
bool parse_poses(Array<Body> *bodies_out, const char* filepath);
|
||||
21
inc/util.hpp
21
inc/util.hpp
@@ -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);
|
||||
|
||||
12
src/body.cpp
12
src/body.cpp
@@ -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
71
src/camera_poses.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/main.cpp
47
src/main.cpp
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
41
src/util.cpp
41
src/util.cpp
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user