-OBJS = main.o stb_image.o helpers.o tiny_obj_loader.o baseclass.o old_objects.o geometric_objects.o hud.o
+OBJS = main.o stb_image.o helpers.o tiny_obj_loader.o baseclass.o old_objects.o geometric_objects.o hud.o door.o
CXXFLAGS = -g -Wall
LDFLAGS = -lGL -lglfw -lGLEW -pthread -g
./a.out
${OBJS} : game.h
-main.o : projectiles.h activation_area.h turret.h tile_floor.h old_objects.h moving_platform.h geometric_objects.h hud.h
+main.o : projectiles.h activation_area.h turret.h tile_floor.h old_objects.h moving_platform.h geometric_objects.h hud.h door.h
--- /dev/null
+#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<glm::mat4> door::create_models() {
+ std::vector<glm::mat4> 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;
+}
+
--- /dev/null
+#pragma once
+class door : public loaded_object, public block_object {
+ public:
+ /* States for this door:
+ * closed: 0
+ * closing: 1
+ * opening: 2
+ * open: 3
+ */
+ std::vector<int> states;
+ std::vector<float> open_angles;
+ door(const char* of, const char* tf, glm::vec3 s) : loaded_object(of, tf, s) {
+ collision_check = true;
+ }
+ void open(size_t index);
+ void close(size_t index);
+ void activate(size_t index) override;
+ void move(int elapsed_time) override;
+ std::vector<glm::mat4> create_models() override;
+ ssize_t collision_index(glm::vec3 position, float distance);
+ void add_door(glm::vec3 location);
+ bool is_on_idx(glm::vec3 position, size_t index, float height);
+};
+
--- /dev/null
+# Blender v3.0.1 OBJ File: ''
+# www.blender.org
+mtllib cube.mtl
+o Cube
+v 5.000000 10.000000 -1.000000
+v 5.000000 -10.000000 -1.000000
+v 5.000000 10.000000 1.000000
+v 5.000000 -10.000000 1.000000
+v -5.000000 10.000000 -1.000000
+v -5.000000 -10.000000 -1.000000
+v -5.000000 10.000000 1.000000
+v -5.000000 -10.000000 1.000000
+vt 0.0 1.0
+vt 0.0 0.0
+vt 1.0 1.0
+vt 1.0 0.0
+vn 0.0000 1.0000 0.0000
+vn 0.0000 0.0000 1.0000
+vn -1.0000 0.0000 0.0000
+vn 0.0000 -1.0000 0.0000
+vn 1.0000 0.0000 0.0000
+vn 0.0000 0.0000 -1.0000
+usemtl Material
+s off
+f 1/2/1 5/1/1 7/3/1 3/4/1
+f 4/2/2 3/1/2 7/3/2 8/4/2
+f 8/2/3 7/1/3 5/3/3 6/4/3
+f 6/2/4 2/1/4 4/3/4 8/4/4
+f 2/2/5 1/1/5 3/3/5 4/4/5
+f 6/2/6 5/1/6 1/3/6 2/4/6
}
virtual bool collision_with_index(glm::vec3 position, size_t index, float distance = 0) { return false;}
virtual void hit_index(size_t index) {}
+ virtual void activate(size_t index) {}
};
class loaded_object : virtual public gameobject {
#include "turret.h"
#include "geometric_objects.h"
#include "hud.h"
+#include "door.h"
std::mutex grand_mutex;
else if(GLFW_KEY_S == key && 0 == action){
player_key_status.backward = 0;
}
+ if(GLFW_KEY_E == key && 1 == action){
+ // Spawn a block
+ glm::vec3 look_at_point = glm::vec3(player_position.x, player_position.y, player_position.z) ;
+ look_at_point.x += 6.0f * cosf(player_elevation) * sinf(player_heading);
+ look_at_point.y += 6.0f * sinf(player_elevation);
+ look_at_point.z += 6.0f * cosf(player_elevation) * cosf(player_heading);
+ for(gameobject* o : objects) {
+ ssize_t collide_index = o->collision_index(look_at_point, 4.0f);
+ if(collide_index != -1)
+ o->activate(collide_index);
+ }
+ }
if(GLFW_KEY_A == key)
player_key_status.left = action;
if(GLFW_KEY_D == key)
fpp.addpanel(glm::vec3(-30, 0, 500), glm::vec2(10, 10), glm::vec2(2.0, 2.0), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0));
objects.push_back(&fpp);
+ door d("door.obj", "cone.png", glm::vec3(10, 20, 2));
+ d.add_door(glm::vec3(0, 0, 300));
+ objects.push_back(&d);
+ bwb.locations.push_back(glm::vec3(15, 0, 293));
+ bwb.locations.push_back(glm::vec3(-15, 0, 293));
+
aimpoint main_aimpoint;
objects.push_back(&main_aimpoint);