#include "game.h" #include "door.h" void door::add_door(glm::vec3 location){ locations.push_back(location); states.push_back(0); open_angles.push_back(0.0f); } ssize_t door::collision_index(glm::vec3 position, float distance){ for(size_t i = 0; i < locations.size(); i++){ glm::vec3 l = locations[i]; // This'll get optimized out if(states[i] == 0){ if( size.x/2.0f + distance > abs(l.x-position.x) && size.y/2.0f + distance > abs(l.y-position.y) && size.z/2.0f + distance > abs(l.z-position.z)){ return i; } } else if(states[i] == 3){ if( size.z/2.0f + distance > abs(l.x-(position.x - (size.x / 2.0f))) && size.y/2.0f + distance > abs(l.y-position.y) && size.x/2.0f + distance > abs(l.z-position.z + (size.x / 2.0f))){ return i; } } } return -1; } bool door::is_on_idx(glm::vec3 position, size_t index, float height){ if(states[index] != 0) return false; return (0.0f < (position.y - locations[index].y) && 1.0f > (position.y - height) - (locations[index].y + size.y/2) && size.x/2 > fabs(position.x - locations[index].x) && size.z/2 > fabs(position.z - locations[index].z)); } void door::activate(size_t index){ if(states[index] == 3) close(index); if(states[index] == 0) open(index); } void door::open(size_t index){ states[index] = 2; } void door::close(size_t index) { states[index] = 1; } void door::move(int elapsed_time){ for(size_t i = 0; i < locations.size(); i++){ if(states[i] == 0 || states[i] == 3) // If all the way open or closed, do nothing return; if(states[i] == 1) { // closing if(open_angles[i] < 0.01f){ open_angles[i] = 0.0f; states[i] = 0; // closed } else open_angles[i] -= elapsed_time * (M_PI/2) / 2000000; } if(states[i] == 2) { // opening if(open_angles[i] > M_PI/2){ open_angles[i] = M_PI/2; states[i] = 3; // closed } else open_angles[i] += elapsed_time * (M_PI/2) / 2000000; } } } std::vector door::create_models() { std::vector models; data_mutex.lock(); models.reserve(locations.size()); for(size_t i = 0; i < locations.size(); i++){ auto l = locations[i]; glm::mat4 new_model = glm::mat4(1.0f); new_model = translate(new_model, l); // Rotation: Is it open or closed? // A problem: Hinges are usually on the edge of doors! // Minor caveat: doors can be hinged on either side, and only open one way new_model = glm::translate(new_model, glm::vec3(5, 0, 1)); new_model = glm::rotate(new_model, open_angles[i], glm::vec3(0, 1, 0)); new_model = glm::translate(new_model, glm::vec3(-5, 0, -1)); models.push_back(new_model); } data_mutex.unlock(); return models; }