diff --git a/ghost.cpp b/ghost.cpp index c8131b8..985cb27 100644 --- a/ghost.cpp +++ b/ghost.cpp @@ -4,7 +4,9 @@ #include "ghost.h" +float pi = glm::pi(); int counter = 0; +float direction_persist_factor = 0.02; Ghost::Ghost(float xmin, float xmax, float zmin, float zmax) { @@ -20,65 +22,82 @@ Ghost::Ghost(float xmin, float xmax, float zmin, float zmax) { pos.y = 2.5; pos.z = rand_float(zmin, zmax); - y_offset = rand_float(0.0, 3.14); - yawr = rand_float(0.0, 6.28); + y_offset = rand_float(0.0, pi); + yawr = rand_float(0.0, pi*2.0f); first_frame = false; + direction_persist = 0.0f; + } -void Ghost::apply_movement() { +void Ghost::apply_movement(float curr_time, float timed) { - float curr_time = static_cast(glfwGetTime()); + // vertical movement + pos.y = 2.5 + sin(curr_time + y_offset); - if (!first_frame) { - first_frame = true; - prev_move_time = curr_time; - return; - } + moved.x = -sin(yawr) + cos(yawr); + moved.z = cos(yawr) + sin(yawr); - float diff_time = curr_time - prev_move_time; - prev_move_time = curr_time; - - glm::vec3 moved; - moved.x = pos.x + (-sin(yawr) + cos(yawr)) * diff_time; - moved.y = 2.5 + sin(curr_time + y_offset); - moved.z = pos.z + (cos(yawr) + sin(yawr)) * diff_time; + pos += moved * timed; bool reset_yaw = false; - if (moved.x < xmin) { + if (pos.x < xmin) { reset_yaw = true; - moved.x = xmin; - } else if (moved.x > xmax) { + pos.x = xmin; + } else if (pos.x > xmax) { reset_yaw = true; - moved.x = xmax; + pos.x = xmax; } - if (moved.z < zmin) { + if (pos.z < zmin) { reset_yaw = true; - moved.z = zmin; - } else if (moved.z > zmax) { + pos.z = zmin; + } else if (pos.z > zmax) { reset_yaw = true; - moved.z = zmax; + pos.z = zmax; } + // TODO make this face origin if (reset_yaw) { - yawr = rand_float(0.0, 6.28); + yawr = rand_float(0.0, pi * 2.0); } else { - yawr += rand_float(-0.3, 0.3); + yawr += rand_float(-0.05, 0.05); } - pos = moved; - } glm::mat4 Ghost::get_model(glm::vec3 &camera_pos) { + // initialize to identity matrix glm::mat4 ghost_model = glm::mat4(1.0f); + // apply location ghost_model = glm::translate(ghost_model, pos); - glm::vec3 ghost_direction = pos - camera_pos; - ghost_model = glm::rotate(ghost_model, atan2f(ghost_direction.x, ghost_direction.z), glm::vec3(0.0f, 1.0f, 0.0f)); + // apply direction + // the cross product helps us determine which direction it's going relative to player + glm::vec3 ghost_to_player = pos - camera_pos; + glm::vec3 crossed = glm::cross(ghost_to_player, moved); + //float dist2 = ghost_to_player.x * ghost_to_player.x + ghost_to_player.z * ghost_to_player.z; + float theta = atan2f(ghost_to_player.x, ghost_to_player.z); + if (crossed.y < 0.0) { + direction_persist = (1.0 - direction_persist_factor) * direction_persist - direction_persist_factor; + } else { + direction_persist = (1.0 - direction_persist_factor) * direction_persist + direction_persist_factor; + } + if (direction_persist < 0.0) { + theta += pi; + } + ghost_model = glm::rotate(ghost_model, theta, glm::vec3(0.0f, 1.0f, 0.0f)); + /* + if (dist2 > 256) { + yawr = theta; + } + if (ghost_id == 0) { + printf("(%f, %f, %f)\n", pos.x, pos.y, pos.z); + printf("%f %f %f %f\n", xmin, xmax, zmin, zmax); + } + */ return ghost_model; } diff --git a/ghost.h b/ghost.h index fd1e4c0..05873a2 100644 --- a/ghost.h +++ b/ghost.h @@ -6,12 +6,13 @@ class Ghost { public: Ghost(float xmin, float xmax, float zmin, float zmax); - void apply_movement(); + void apply_movement(float curr_time, float timed); glm::mat4 get_model(glm::vec3 &camera_pos); private: int ghost_id; bool first_frame; + glm::vec3 moved; glm::vec3 pos; float yawr; float xmin; @@ -20,6 +21,7 @@ class Ghost { float zmax; float y_offset; float prev_move_time; + float direction_persist; }; float rand_float(float rmin, float rmax); diff --git a/ghostland.cpp b/ghostland.cpp index e8bc8ed..49ba48d 100644 --- a/ghostland.cpp +++ b/ghostland.cpp @@ -27,20 +27,11 @@ void set_light_front(int xoffset, int yoffset); Player *player; // settings -const unsigned int WINDOWWIDTH = 1600; -const unsigned int WINDOWHEIGHT = 900; +unsigned int WINDOWWIDTH = 1600; +unsigned int WINDOWHEIGHT = 900; // camera -bool mousemove = false; -float xpersist = 0.0f; -float ypersist = 0.0f; - -bool first_mouse = true; -float yaw = 0.0f; -float pitch = 0.0f; -float lastX = WINDOWWIDTH / 2.0; -float lastY = WINDOWHEIGHT / 2.0; - +bool first_frame = false; float timed = 0.0f; float last_frame = 0.0f; @@ -88,7 +79,11 @@ int main(int argc, char *argv[]) // num surfaces * 6 (vertices per point) * 6 (floats per point) int num_wall_vertices = num_walls * 6 * 6; wall_vertices = (float *)calloc(sizeof(float), num_wall_vertices); - int xmin_wall, xmax_wall, zmin_wall, zmax_wall; + float xmin_wall, xmax_wall, zmin_wall, zmax_wall; + xmin_wall = 9999.9; + xmax_wall = -9999.9; + zmin_wall = 9999.9; + zmax_wall = -9999.9; // read walls for (int i = 0; i < num_walls; i++) { for (int j = 0; j < 6; j++) { @@ -149,7 +144,13 @@ int main(int argc, char *argv[]) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - GLFWwindow* window = glfwCreateWindow(WINDOWWIDTH, WINDOWHEIGHT, "Ghostland!", NULL, NULL); + GLFWmonitor *monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode *monitor_mode = glfwGetVideoMode(monitor); + + WINDOWWIDTH = monitor_mode->width; + WINDOWHEIGHT = monitor_mode->height; + + GLFWwindow* window = glfwCreateWindow(WINDOWWIDTH, WINDOWHEIGHT, "Ghostland!", monitor, NULL); if (window == NULL) { printf("Failed to create GLFW window.\n"); @@ -166,6 +167,7 @@ int main(int argc, char *argv[]) if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { printf("Failed to initialize GLAD.\n"); + glfwTerminate(); return -1; } @@ -270,12 +272,12 @@ int main(int argc, char *argv[]) } // ghost vertices float ghost_vertices[] = { - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, }; unsigned int ghostVBO, ghostVAO; glGenVertexArrays(1, &ghostVAO); @@ -327,7 +329,7 @@ int main(int argc, char *argv[]) float smallcutoff = glm::cos(glm::radians(7.5f)); std::vector ghosts; - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 800; i++) { ghosts.push_back(new Ghost(xmin_wall, xmax_wall, zmin_wall, zmax_wall)); } @@ -359,8 +361,10 @@ int main(int argc, char *argv[]) } timed = current_frame - last_frame; last_frame = current_frame; - - mousemove = false; + if (!first_frame) { + first_frame = true; + continue; + } player->process_input(window); @@ -451,13 +455,13 @@ int main(int argc, char *argv[]) set_uniform(ghost_program, viewC, view); for (int i = 0; i < ghosts.size(); i++) { glm::mat4 ghost_model = ghosts[i]->get_model(camera_pos); - ghosts[i]->apply_movement(); + ghosts[i]->apply_movement(current_frame, timed); set_uniform(ghost_program, modelC, ghost_model); glBindVertexArray(ghostVAO); glDrawArrays(GL_TRIANGLES, 0, (3 + 3 + 2) * 6); } - player->apply_movement(); + player->apply_movement(timed); glfwSwapBuffers(window); glfwPollEvents(); diff --git a/player.cpp b/player.cpp index 6fcfa6f..26736e1 100644 --- a/player.cpp +++ b/player.cpp @@ -6,9 +6,9 @@ Player::Player(glm::vec3 startpos, float startyaw) { position = startpos; - yaw = startyaw; + yaw = 45.0f + startyaw; - pitch = 0.0f; + pitch = 45.0f; first_mouse = false; first_frame = false; light_xpersist = 0.0f; @@ -203,18 +203,7 @@ void Player::set_light_offset(float xoffset, float yoffset) { } -void Player::apply_movement() { - - float curr_time = static_cast(glfwGetTime()); - - if (!first_frame) { - prev_move_time = curr_time; - first_frame = true; - return; - } - - float diff_time = curr_time - prev_move_time; - prev_move_time = curr_time; +void Player::apply_movement(float timed) { // mouse movement glm::vec3 front; @@ -230,7 +219,7 @@ void Player::apply_movement() { // positional movement glm::vec3 movement = velocity; - movement *= diff_time; + movement *= timed; glm::vec3 intersected = check_intersection(movement); if (is_in_air()) { if (intersected.x == 0.0) { @@ -253,7 +242,7 @@ void Player::apply_movement() { position.y = 0.0f; velocity.y = 0.0f; } else { - velocity.y += diff_time * vacceleration; + velocity.y += timed * vacceleration; } position.x += intersected.x; diff --git a/player.h b/player.h index 2386e1a..5a7b9d5 100644 --- a/player.h +++ b/player.h @@ -38,7 +38,7 @@ class Player { void process_input(GLFWwindow *window); void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); bool is_in_air(); - void apply_movement(); + void apply_movement(float timed); private: float yaw;