Add rudimentary collision detection
This commit is contained in:
7
Makefile
7
Makefile
@@ -1,5 +1,5 @@
|
|||||||
snowland: glad.o snowland.o stb_image.o
|
snowland: glad.o snowland.o stb_image.o collisions.o
|
||||||
g++ -o snowland glad.o snowland.o stb_image.o -ldl -lglfw -std=c++17
|
g++ -o snowland glad.o snowland.o stb_image.o collisions.o -ldl -lglfw -std=c++17
|
||||||
|
|
||||||
glad.o: glad.c
|
glad.o: glad.c
|
||||||
g++ -c -o glad.o glad.c
|
g++ -c -o glad.o glad.c
|
||||||
@@ -10,5 +10,8 @@ snowland.o: snowland.cpp
|
|||||||
stb_image.o: stb_image.c
|
stb_image.o: stb_image.c
|
||||||
g++ -c -o stb_image.o stb_image.c -std=c++17
|
g++ -c -o stb_image.o stb_image.c -std=c++17
|
||||||
|
|
||||||
|
collisions.o: collisions.cpp
|
||||||
|
g++ -c -o collisions.o collisions.cpp -std=c++17
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o snowland
|
rm -f *.o snowland
|
||||||
|
|||||||
48
collisions.cpp
Normal file
48
collisions.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
float abs(float x) {
|
||||||
|
if (x < 0) {
|
||||||
|
return -x;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int signbit(float x) {
|
||||||
|
if (x < 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getIntersection(glm::vec3 vec_start, glm::vec3 vec_stop, glm::vec3 P1, glm::vec3 P2, glm::vec3 P3) {
|
||||||
|
|
||||||
|
glm::vec3 lba = vec_start - vec_stop;
|
||||||
|
glm::vec3 v01 = P2 - P1;
|
||||||
|
glm::vec3 v02 = P3 - P1;
|
||||||
|
glm::vec3 cross12 = glm::cross(v01, v02);
|
||||||
|
float det = glm::dot(lba, cross12);
|
||||||
|
if (abs(det) < 0.0000001) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 diff_start = vec_start - P1;
|
||||||
|
float tn = glm::dot(cross12, diff_start);
|
||||||
|
if (signbit(tn) != signbit(det) || abs(det) < abs(tn)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 coefU = glm::cross(v02, lba);
|
||||||
|
float un = glm::dot(coefU, diff_start);
|
||||||
|
if (signbit(un) != signbit(det) || abs(det) < abs(un)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 coefV = glm::cross(lba, v01);
|
||||||
|
float vn = glm::dot(coefV, diff_start);
|
||||||
|
if (signbit(vn) != signbit(det) || abs(det) < abs(vn)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
8
collisions.h
Normal file
8
collisions.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef COLLISIONS_H
|
||||||
|
#define COLLISIONS_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
int getIntersection(glm::vec3 vec_start, glm::vec3 vec_stop, glm::vec3 P1, glm::vec3 P2, glm::vec3 P3);
|
||||||
|
|
||||||
|
#endif
|
||||||
85
snowland.cpp
85
snowland.cpp
@@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "collisions.h"
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
||||||
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
|
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
|
||||||
@@ -47,6 +50,68 @@ const char *viewposC = "viewPos";
|
|||||||
const char *lightcolorC = "lightColor";
|
const char *lightcolorC = "lightColor";
|
||||||
const char *objectcolorC = "objectColor";
|
const char *objectcolorC = "objectColor";
|
||||||
|
|
||||||
|
int num_walls;
|
||||||
|
float *wall_vertices;
|
||||||
|
|
||||||
|
glm::vec3 getNormalFromIndex(int ix) {
|
||||||
|
return glm::vec3(
|
||||||
|
wall_vertices[ix * 6 * 6 + 3],
|
||||||
|
wall_vertices[ix * 6 * 6 + 4],
|
||||||
|
wall_vertices[ix * 6 * 6 + 5]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 getVec3FromIndices(int ix, int jx) {
|
||||||
|
return glm::vec3(
|
||||||
|
wall_vertices[ix * 6 * 6 + jx * 6],
|
||||||
|
wall_vertices[ix * 6 * 6 + jx * 6 + 1],
|
||||||
|
wall_vertices[ix * 6 * 6 + jx * 6 + 2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 checkIntersection(glm::vec3 movement) {
|
||||||
|
|
||||||
|
glm::vec3 vec_start, vec_stop, p1, p2, p3, res;
|
||||||
|
int gotX = 0, gotZ = 0;
|
||||||
|
vec_start = player_pos;
|
||||||
|
vec_stop = vec_start + movement * 10.0f;
|
||||||
|
res.x = movement.x;
|
||||||
|
res.y = movement.y;
|
||||||
|
res.z = movement.z;
|
||||||
|
|
||||||
|
for (int ix = 0; ix < num_walls; ix++) {
|
||||||
|
glm::vec3 norm = getNormalFromIndex(ix);
|
||||||
|
if (gotX && gotZ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!gotX) {
|
||||||
|
if ((movement.x > 0 && norm.x < 0) || (movement.x < 0 && norm.x > 0)) {
|
||||||
|
p1 = getVec3FromIndices(ix, 1);
|
||||||
|
p2 = getVec3FromIndices(ix, 0);
|
||||||
|
p3 = getVec3FromIndices(ix, 2);
|
||||||
|
if (getIntersection(vec_start, vec_stop, p1, p2, p3)) {
|
||||||
|
gotX = 1;
|
||||||
|
res.x = -movement.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!gotZ) {
|
||||||
|
if ((movement.z > 0 && norm.z < 0) || (movement.z < 0 && norm.z > 0)) {
|
||||||
|
p1 = getVec3FromIndices(ix, 1);
|
||||||
|
p2 = getVec3FromIndices(ix, 0);
|
||||||
|
p3 = getVec3FromIndices(ix, 2);
|
||||||
|
if (getIntersection(vec_start, vec_stop, p1, p2, p3)) {
|
||||||
|
gotZ = 1;
|
||||||
|
res.z = -movement.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
glfwInit();
|
glfwInit();
|
||||||
@@ -154,14 +219,13 @@ int main()
|
|||||||
|
|
||||||
fp = fopen("maze.txt", "r");
|
fp = fopen("maze.txt", "r");
|
||||||
fscanf(fp, "%f %f %f %f\n", &player_pos.x, &player_pos.y, &player_pos.z, &yaw);
|
fscanf(fp, "%f %f %f %f\n", &player_pos.x, &player_pos.y, &player_pos.z, &yaw);
|
||||||
int num_surfaces;
|
fscanf(fp, "%d\n", &num_walls);
|
||||||
fscanf(fp, "%d\n", &num_surfaces);
|
|
||||||
// num surfaces * 6 (vertices per point) * 6 (floats per point)
|
// num surfaces * 6 (vertices per point) * 6 (floats per point)
|
||||||
// add 1 for floor
|
// add 1 for floor
|
||||||
int num_walls = (num_surfaces) * 6 * 6;
|
int num_walls = (num_walls) * 6 * 6;
|
||||||
float *wall_vertices = (float *)calloc(sizeof(float), num_surfaces * 6 * 6);
|
wall_vertices = (float *)calloc(sizeof(float), num_walls * 6 * 6);
|
||||||
// read walls
|
// read walls
|
||||||
for (int i = 0; i < num_surfaces; i++) {
|
for (int i = 0; i < num_walls; i++) {
|
||||||
for (int j = 0; j < 6; j++) {
|
for (int j = 0; j < 6; j++) {
|
||||||
int vix = i*6*6 + j*6;
|
int vix = i*6*6 + j*6;
|
||||||
fscanf(
|
fscanf(
|
||||||
@@ -272,7 +336,7 @@ int main()
|
|||||||
glBindVertexArray(wallsVAO);
|
glBindVertexArray(wallsVAO);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, num_walls);
|
glDrawArrays(GL_TRIANGLES, 0, num_walls);
|
||||||
|
|
||||||
glm::vec3 floor_color = glm::vec3(0.1f, 0.1f, 0.1f);
|
glm::vec3 floor_color = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
glUniform3fv(glGetUniformLocation(program, objectcolorC), 1, &floor_color[0]);
|
glUniform3fv(glGetUniformLocation(program, objectcolorC), 1, &floor_color[0]);
|
||||||
|
|
||||||
glBindVertexArray(floorVAO);
|
glBindVertexArray(floorVAO);
|
||||||
@@ -301,19 +365,20 @@ void processInput(GLFWwindow *window)
|
|||||||
glm::vec3 movement;
|
glm::vec3 movement;
|
||||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
|
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
|
||||||
movement = glm::vec3(camera_front.x, 0.0, camera_front.z);
|
movement = glm::vec3(camera_front.x, 0.0, camera_front.z);
|
||||||
player_pos += glm::normalize(movement) * camera_speed_adjusted;
|
|
||||||
} else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
|
} else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
|
||||||
movement = glm::vec3(-camera_front.x, 0.0, -camera_front.z);
|
movement = glm::vec3(-camera_front.x, 0.0, -camera_front.z);
|
||||||
player_pos += glm::normalize(movement) * camera_speed_adjusted;
|
|
||||||
} else if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
|
} else if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
|
||||||
glm::vec3 right = glm::cross(camera_front, camera_up);
|
glm::vec3 right = glm::cross(camera_front, camera_up);
|
||||||
movement = glm::vec3(right.x, 0.0, right.z);
|
movement = glm::vec3(right.x, 0.0, right.z);
|
||||||
player_pos -= glm::normalize(movement) * camera_speed_adjusted;
|
|
||||||
} else if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
|
} else if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
|
||||||
glm::vec3 right = glm::cross(camera_front, camera_up);
|
glm::vec3 right = glm::cross(camera_front, camera_up);
|
||||||
movement = glm::vec3(right.x, 0.0, right.z);
|
movement = glm::vec3(right.x, 0.0, right.z);
|
||||||
player_pos += glm::normalize(movement) * camera_speed_adjusted;
|
} else {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
movement = glm::normalize(movement) * camera_speed_adjusted;
|
||||||
|
movement = checkIntersection(movement);
|
||||||
|
player_pos += movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
|
|||||||
Reference in New Issue
Block a user