diff --git a/src/collision/collision_handler.cpp b/src/collision/collision_handler.cpp index 4a82a7f..61d7c0e 100644 --- a/src/collision/collision_handler.cpp +++ b/src/collision/collision_handler.cpp @@ -3,7 +3,7 @@ namespace collision { - void CheckCollisions(std::vector> entities) + void CheckCollisions(std::deque>& entities) { if (entities.size() < 2) { return; } if (entities.size() == 2) @@ -15,7 +15,7 @@ namespace collision entities[1]->OnCollide(c); } } - + for (int i = 0; i < entities.size() - 2; i++) { std::shared_ptr entity = entities[i]; diff --git a/src/collision/collision_handler.h b/src/collision/collision_handler.h index ea1a67d..8887dd8 100644 --- a/src/collision/collision_handler.h +++ b/src/collision/collision_handler.h @@ -4,6 +4,7 @@ #include #include "../entities/collision_entity.h" #include "collision.h" +#include namespace collision { @@ -13,5 +14,5 @@ namespace collision * * @param entities: A list with all the collision entities. */ - void CheckCollisions(std::vector> entities); + void CheckCollisions(std::deque>& entities); } \ No newline at end of file diff --git a/src/computervision/OpenPoseVideo.cpp b/src/computervision/OpenPoseVideo.cpp deleted file mode 100644 index 33527a1..0000000 --- a/src/computervision/OpenPoseVideo.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "OpenPoseVideo.h" - -using namespace std; -using namespace cv; -using namespace cv::dnn; - -namespace computervision -{ -#define MPI - -#ifdef MPI - const int POSE_PAIRS[7][2] = - { - {0,1}, {1,2}, {2,3}, - {3,4}, {1,5}, {5,6}, - {6,7} - }; - - string protoFile = "res/pose/mpi/pose_deploy_linevec_faster_4_stages.prototxt"; - string weightsFile = "res/pose/mpi/pose_iter_160000.caffemodel"; - - int nPoints = 8; -#endif - -#ifdef COCO - const int POSE_PAIRS[17][2] = - { - {1,2}, {1,5}, {2,3}, - {3,4}, {5,6}, {6,7}, - {1,8}, {8,9}, {9,10}, - {1,11}, {11,12}, {12,13}, - {1,0}, {0,14}, - {14,16}, {0,15}, {15,17} - }; - - string protoFile = "pose/coco/pose_deploy_linevec.prototxt"; - string weightsFile = "pose/coco/pose_iter_440000.caffemodel"; - - int nPoints = 18; -#endif - Net net; - - void OpenPoseVideo::setup() { - net = readNetFromCaffe(protoFile, weightsFile); - - net.setPreferableBackend(DNN_TARGET_CPU); - } - - void OpenPoseVideo::movementSkeleton(Mat& inputImage, std::function&, cv::Mat& poinst_on_image)> f) { - std::cout << "movement skeleton start" << std::endl; - - int inWidth = 368; - int inHeight = 368; - float thresh = 0.01; - - Mat frame; - int frameWidth = inputImage.size().width; - int frameHeight = inputImage.size().height; - - double t = (double)cv::getTickCount(); - std::cout << "reading input image and blob" << std::endl; - - frame = inputImage; - Mat inpBlob = blobFromImage(frame, 1.0 / 255, Size(inWidth, inHeight), Scalar(0, 0, 0), false, false); - - std::cout << "done reading image and blob" << std::endl; - - net.setInput(inpBlob); - - std::cout << "done setting input to net" << std::endl; - Mat output = net.forward(); - std::cout << "time took to set input and forward: " << t << std::endl; - - int H = output.size[2]; - int W = output.size[3]; - - std::cout << "about to find position of boxy parts" << std::endl; - // find the position of the body parts - vector points(nPoints); - for (int n = 0; n < nPoints; n++) - { - // Probability map of corresponding body's part. - Mat probMap(H, W, CV_32F, output.ptr(0, n)); - - Point2f p(-1, -1); - Point maxLoc; - double prob; - minMaxLoc(probMap, 0, &prob, 0, &maxLoc); - if (prob > thresh) - { - p = maxLoc; - p.x *= (float)frameWidth / W; - p.y *= (float)frameHeight / H; - - circle(frame, cv::Point((int)p.x, (int)p.y), 8, Scalar(0, 255, 255), -1); - cv::putText(frame, cv::format("%d", n), cv::Point((int)p.x, (int)p.y), cv::FONT_HERSHEY_COMPLEX, 1.1, cv::Scalar(0, 0, 255), 2); - } - points[n] = p; - } - - cv::putText(frame, cv::format("time taken = %.2f sec", t), cv::Point(50, 50), cv::FONT_HERSHEY_COMPLEX, .8, cv::Scalar(255, 50, 0), 2); - std::cout << "time taken: " << t << std::endl; - //imshow("Output-Keypoints", frame); - //imshow("Output-Skeleton", frame); - std::cout << "about to call points receiving method" << std::endl; - f(points,frame); - } -} \ No newline at end of file diff --git a/src/computervision/OpenPoseVideo.h b/src/computervision/OpenPoseVideo.h deleted file mode 100644 index e05737d..0000000 --- a/src/computervision/OpenPoseVideo.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -using namespace cv; - -namespace computervision -{ - class OpenPoseVideo{ - private: - - public: - void movementSkeleton(Mat& inputImage, std::function&, cv::Mat& poinst_on_image)> f); - void setup(); - }; -} diff --git a/src/computervision/async/async_arm_detection.cpp b/src/computervision/async/async_arm_detection.cpp deleted file mode 100644 index a43b7dc..0000000 --- a/src/computervision/async/async_arm_detection.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include "async_arm_detection.h" -#include "../OpenPoseVideo.h" -#include -#include "StaticCameraInstance.h" - - -namespace computervision -{ - AsyncArmDetection::AsyncArmDetection() - { - - } - - void AsyncArmDetection::run_arm_detection(std::function, cv::Mat poinst_on_image)> points_ready_func, OpenPoseVideo op) - { - VideoCapture cap = static_camera::getCap(); - - std::cout << "STARTING THREAD LAMBDA" << std::endl; - /*cv::VideoCapture cap = static_camera::GetCap();*/ - - if (!cap.isOpened()) - { - std::cout << "capture was closed, opening..." << std::endl; - cap.open(0); - } - - while (true) - { - Mat img; - cap.read(img); - op.movementSkeleton(img, points_ready_func); - } - } - - void AsyncArmDetection::start(std::function, cv::Mat poinst_on_image)> points_ready_func, OpenPoseVideo op) - { - - std::cout << "starting function" << std::endl; - - - std::thread async_arm_detect_thread(&AsyncArmDetection::run_arm_detection,this, points_ready_func, op); - - async_arm_detect_thread.detach(); // makes sure the thread is detached from the variable. - } -} diff --git a/src/computervision/async/async_arm_detection.h b/src/computervision/async/async_arm_detection.h deleted file mode 100644 index 98fd163..0000000 --- a/src/computervision/async/async_arm_detection.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include "../OpenPoseVideo.h" -#include "StaticCameraInstance.h" - - -namespace computervision -{ - class AsyncArmDetection - { - public: - AsyncArmDetection(void); - - - void start(std::function, cv::Mat poinst_on_image)>, computervision::OpenPoseVideo op); - private: - void run_arm_detection(std::function, cv::Mat poinst_on_image)> points_ready_func, OpenPoseVideo op); - }; - -} diff --git a/src/computervision/BackgroundRemover.cpp b/src/computervision/background_remover.cpp similarity index 97% rename from src/computervision/BackgroundRemover.cpp rename to src/computervision/background_remover.cpp index ebae572..e9a19e1 100644 --- a/src/computervision/BackgroundRemover.cpp +++ b/src/computervision/background_remover.cpp @@ -1,4 +1,4 @@ -#include "BackgroundRemover.h" +#include "background_remover.h" /* Author: Pierfrancesco Soffritti https://github.com/PierfrancescoSoffritti diff --git a/src/computervision/BackgroundRemover.h b/src/computervision/background_remover.h similarity index 100% rename from src/computervision/BackgroundRemover.h rename to src/computervision/background_remover.h diff --git a/src/computervision/FingerCount.cpp b/src/computervision/finger_count.cpp similarity index 99% rename from src/computervision/FingerCount.cpp rename to src/computervision/finger_count.cpp index bdd1938..0bc4409 100644 --- a/src/computervision/FingerCount.cpp +++ b/src/computervision/finger_count.cpp @@ -1,4 +1,4 @@ -#include "FingerCount.h" +#include "finger_count.h" #include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" diff --git a/src/computervision/FingerCount.h b/src/computervision/finger_count.h similarity index 100% rename from src/computervision/FingerCount.h rename to src/computervision/finger_count.h diff --git a/src/computervision/HandDetectRegion.cpp b/src/computervision/hand_detect_region.cpp similarity index 66% rename from src/computervision/HandDetectRegion.cpp rename to src/computervision/hand_detect_region.cpp index 87f3538..c354d45 100644 --- a/src/computervision/HandDetectRegion.cpp +++ b/src/computervision/hand_detect_region.cpp @@ -1,6 +1,6 @@ -#include "HandDetectRegion.h" - +#include "hand_detect_region.h" +#define TIME_DURATION 1.0f namespace computervision { @@ -20,10 +20,20 @@ namespace computervision Mat input_frame = GenerateHandMaskSquare(camera_frame); frame_out = input_frame.clone(); + if (!background_calibrated || !skin_calibrated) + if (time >= TIME_DURATION) + { + //std::cout << "timer finised, seconds left: " << seconds_left << std::endl; + seconds_left--; + time = 0; + } + + // detect skin color skin_detector.drawSkinColorSampler(camera_frame,start_x_pos,start_y_pos,region_width,region_height); // remove background from image + foreground = background_remover.getForeground(input_frame); // detect the hand contours @@ -32,10 +42,33 @@ namespace computervision // draw the hand rectangle on the camera input, and draw text showing if the hand is open or closed. DrawHandMask(&camera_frame); + if (seconds_left <= 0) + { + if (!background_calibrated) + { + background_remover.calibrate(input_frame); + background_calibrated = true; + hand_calibrator.SetBackGroundCalibrated(background_calibrated); + seconds_left = 5; + time = 0; + } + else + { + + if (!skin_calibrated) + { + if (is_main_skin_detection_region) + skin_timer_callback(); + } + } + + } + + // uncomment these lines to show debug hand information //imshow("output" + region_id, frame_out); //imshow("foreground" + region_id, foreground); //imshow("handMask" + region_id, handMask); - /*imshow("handDetection", fingerCountDebug);*/ + //imshow("handDetection", fingerCountDebug); hand_present = hand_calibrator.CheckIfHandPresent(handMask,handcalibration::HandDetectionType::GAME); //std::string text = (hand_present ? "hand" : "no"); @@ -47,7 +80,17 @@ namespace computervision hand_calibrator.DrawBackgroundSkinCalibrated(camera_frame); - + std::string calibration_text = (!background_calibrated ? "calibrating background in " : (!skin_calibrated ? "calibrating skin in " : "")); + calibration_text += std::to_string(seconds_left); + if (!background_calibrated || !skin_calibrated) + { + cv::rectangle(camera_frame, cv::Rect(0, camera_frame.rows - 130, 600, 60), cv::Scalar(0, 0, 0), -1); + cv:putText(camera_frame, calibration_text, cv::Point(5, 400), cv::FONT_HERSHEY_COMPLEX, 1.0, cv::Scalar(255, 0, 255), 2); + } + if (background_calibrated && !skin_calibrated) + { + cv::putText(camera_frame, "put your hand in the left square", cv::Point(5, camera_frame.rows - 105), cv::FONT_HERSHEY_COMPLEX, 1.0, cv::Scalar(255, 0, 255), 2); + } } @@ -92,6 +135,8 @@ namespace computervision { std::cout << "calibrating skin " << region_id << std::endl; hand_calibrator.SetSkinCalibration(true); + skin_calibrated = true; + time = 0; return skin_detector.calibrateAndReturn(frame_out); } @@ -100,6 +145,13 @@ namespace computervision std::cout << "setting skin " << region_id << std::endl; skin_detector.setTresholds(tresholds); hand_calibrator.SetSkinCalibration(true); + skin_calibrated = true; + time = 0; + } + + void HandDetectRegion::UpdateTime(float delta_time) + { + time += delta_time; } } diff --git a/src/computervision/HandDetectRegion.h b/src/computervision/hand_detect_region.h similarity index 70% rename from src/computervision/HandDetectRegion.h rename to src/computervision/hand_detect_region.h index 7cc1a9a..17ec562 100644 --- a/src/computervision/HandDetectRegion.h +++ b/src/computervision/hand_detect_region.h @@ -2,11 +2,13 @@ #include #include +#include + #include "async/StaticCameraInstance.h" #include "calibration/HandCalibrator.h" -#include "BackgroundRemover.h" -#include "SkinDetector.h" -#include "FingerCount.h" +#include "background_remover.h" +#include "skin_detector.h" +#include "finger_count.h" namespace computervision { class HandDetectRegion @@ -36,8 +38,12 @@ namespace computervision std::vector CalculateSkinTresholds(); void setSkinTresholds(std::vector& tresholds); + void UpdateTime(float delta_time); + void SetMainSkinDetecRegion(bool val) { is_main_skin_detection_region = val; }; + void SetSkinTimerCallback(std::function fun) { skin_timer_callback = fun; }; private: + int start_x_pos; int start_y_pos; int region_height; @@ -51,6 +57,17 @@ namespace computervision std::string region_id; bool DrawHandMask(cv::Mat* input); + + float time = 0; + int seconds_left = 5; // calibration countdown + + bool background_calibrated = false; + bool skin_calibrated = false; + bool is_main_skin_detection_region = false; + std::function skin_timer_callback; + + + }; } diff --git a/src/computervision/ObjectDetection.cpp b/src/computervision/object_detection.cpp similarity index 60% rename from src/computervision/ObjectDetection.cpp rename to src/computervision/object_detection.cpp index 155512e..ea3c13f 100644 --- a/src/computervision/ObjectDetection.cpp +++ b/src/computervision/object_detection.cpp @@ -1,14 +1,7 @@ -#include -#include -#include +#include "object_detection.h" -#include "ObjectDetection.h" -#include "BackgroundRemover.h" -#include "SkinDetector.h" -#include "FingerCount.h" -#include "async/StaticCameraInstance.h" -#include "calibration/HandCalibrator.h" +#define TIME_DURATION 1.0f namespace computervision { @@ -25,6 +18,11 @@ namespace computervision handcalibration::HandCalibrator hand_calibrator; cv::VideoCapture cap = static_camera::getCap(); + float time = 0; + int seconds_left = 5; // calibration countdown + + bool background_calibrated = false; + bool skin_calibrated = false; ObjectDetection::ObjectDetection() { @@ -42,6 +40,20 @@ namespace computervision bool ObjectDetection::DetectHand(Mat camera_frame, bool& hand_present) { + //calculate deltatime + if (!background_calibrated || !skin_calibrated) + { + UpdateTime(); + + if (time >= TIME_DURATION) + { + std::cout << "timer finised, seconds left: " << seconds_left << std::endl; + seconds_left--; + time = 0; + } + } + + Mat input_frame = GenerateHandMaskSquare(camera_frame); frame_out = input_frame.clone(); @@ -62,38 +74,59 @@ namespace computervision // draw the hand rectangle on the camera input, and draw text showing if the hand is open or closed. DrawHandMask(&camera_frame); - + + if (seconds_left <= 0) + { + if (!background_calibrated) + { + background_remover.calibrate(input_frame); + background_calibrated = true; + hand_calibrator.SetBackGroundCalibrated(background_calibrated); + seconds_left = 5; + time = 0; + } + else + { + + if (!skin_calibrated) + { + skin_detector.calibrate(input_frame); + skin_calibrated = true; + hand_calibrator.SetSkinCalibration(skin_calibrated); + time = 0; + } + } + + } hand_calibrator.SetAmountOfFingers(fingers_amount); finger_count.DrawHandContours(camera_frame); hand_calibrator.DrawHandCalibrationText(camera_frame); + + std::string calibration_text = (!background_calibrated ? "calibrating background in " : (!skin_calibrated ? "calibrating skin in " : "")); + calibration_text += std::to_string(seconds_left); + if (!background_calibrated || !skin_calibrated) + { + cv::rectangle(camera_frame, cv::Rect(0, camera_frame.rows - 120, 500, 50), cv::Scalar(0, 0, 0), -1); + cv::putText(camera_frame, calibration_text, cv::Point(5, camera_frame.rows-80), cv::FONT_HERSHEY_COMPLEX, 1.0, cv::Scalar(255, 0, 255), 2); + } + + if (background_calibrated && !skin_calibrated) + { + cv::putText(camera_frame, "put your hand in the square", cv::Point(5, camera_frame.rows - 100), cv::FONT_HERSHEY_COMPLEX, 1.0, cv::Scalar(255, 0, 255), 2); + } imshow("camera", camera_frame); + // uncomment these lines to show debug hand information /*imshow("output", frame_out); imshow("foreground", foreground); imshow("handMask", handMask); imshow("handDetection", fingerCountDebug);*/ - hand_present = hand_calibrator.CheckIfHandPresent(handMask,handcalibration::HandDetectionType::MENU); + hand_present = hand_calibrator.CheckIfHandPresent(handMask, handcalibration::HandDetectionType::MENU); hand_calibrator.SetHandPresent(hand_present); - - int key = waitKey(1); - - if (key == 98) // b, calibrate the background - { - background_remover.calibrate(input_frame); - hand_calibrator.SetBackGroundCalibrated(true); - } - else if (key == 115) // s, calibrate the skin color - { - skin_detector.calibrate(input_frame); - hand_calibrator.SetSkinCalibration(true); - - } - - return fingers_amount > 0; } @@ -144,5 +177,15 @@ namespace computervision imshow("Webcam image", img); } + void ObjectDetection::UpdateTime() + { + double current_time = glfwGetTime(); + static double last_frame_time = current_time; + double delt_time = current_time - last_frame_time; + last_frame_time = current_time; + + time += delt_time; + } + } \ No newline at end of file diff --git a/src/computervision/ObjectDetection.h b/src/computervision/object_detection.h similarity index 89% rename from src/computervision/ObjectDetection.h rename to src/computervision/object_detection.h index 92fc335..4cf76d6 100644 --- a/src/computervision/ObjectDetection.h +++ b/src/computervision/object_detection.h @@ -8,6 +8,14 @@ #include #include #include +#include +#include + +#include "background_remover.h" +#include "skin_detector.h" +#include "finger_count.h" +#include "async/StaticCameraInstance.h" +#include "calibration/HandCalibrator.h" namespace computervision @@ -86,6 +94,7 @@ namespace computervision private: bool is_hand_open; bool is_hand_present; + void UpdateTime(); }; diff --git a/src/computervision/SkinDetector.cpp b/src/computervision/skin_detector.cpp similarity index 99% rename from src/computervision/SkinDetector.cpp rename to src/computervision/skin_detector.cpp index 100f25f..64c21bc 100644 --- a/src/computervision/SkinDetector.cpp +++ b/src/computervision/skin_detector.cpp @@ -1,4 +1,4 @@ -#include "SkinDetector.h" +#include "skin_detector.h" #include /* diff --git a/src/computervision/SkinDetector.h b/src/computervision/skin_detector.h similarity index 100% rename from src/computervision/SkinDetector.h rename to src/computervision/skin_detector.h diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index f74432d..585f463 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -23,5 +23,7 @@ namespace entities this->rotation.y += rotation.y; this->rotation.z += rotation.z; } + + } diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 3fd3c2b..6a041bc 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -40,7 +40,7 @@ namespace entities inline glm::vec3 GetPosition() const { return position; } inline void SetPosition(const ::glm::vec3& position) { this->position = position; } inline glm::vec3 GetRotation() const { return rotation; } - inline void SetRotation(const ::glm::vec3& rotation) { this->rotation = rotation; } + void SetRotation(const ::glm::vec3& rotation) { this->rotation = rotation; } inline float GetScale() const { return scale; } inline void SetScale(const float scale) { this->scale = scale; } }; diff --git a/src/entities/collision_entity.cpp b/src/entities/collision_entity.cpp index 304ffb7..57e7b9e 100644 --- a/src/entities/collision_entity.cpp +++ b/src/entities/collision_entity.cpp @@ -40,7 +40,10 @@ namespace entities const glm::vec3 size = bounding_box.size; - min_xyz = bounding_box.center_pos; - max_xyz = glm::vec3(min_xyz.x + size.x, min_xyz.y + size.y, min_xyz.z + size.z); + min_xyz = { bounding_box.center_pos.x - (0.5 * size.x), bounding_box.center_pos.y, bounding_box.center_pos.z + (0.5 * size.z) }; + max_xyz = { bounding_box.center_pos.x + (0.5 * size.x), bounding_box.center_pos.y + size.y, bounding_box.center_pos.z - (0.5 * size.z) }; + + // min_xyz = bounding_box.center_pos; + // max_xyz = { bounding_box.center_pos.x + size.x, bounding_box.center_pos.y + size.y, bounding_box.center_pos.z + size.z }; } } diff --git a/src/entities/collision_entity.h b/src/entities/collision_entity.h index a1269d1..1eb8ee4 100644 --- a/src/entities/collision_entity.h +++ b/src/entities/collision_entity.h @@ -58,7 +58,7 @@ namespace entities void SetCollisionBehaviour(std::function function) { if (function != nullptr) { on_collide = function; } } - protected: + public: /* * @brief: This method moves the collision to the center of the entity diff --git a/src/entities/house_generator.cpp b/src/entities/house_generator.cpp index f316bed..04f52a5 100644 --- a/src/entities/house_generator.cpp +++ b/src/entities/house_generator.cpp @@ -33,6 +33,7 @@ namespace entities } } + } void HouseGenerator::GetFurniturePiece(singleton::FurnitureType type, singleton::FurniturePiece* furniture_piece) @@ -127,5 +128,4 @@ namespace entities return furniture_list.at(modelNumber); } - } diff --git a/src/entities/house_generator.h b/src/entities/house_generator.h index b552b4c..10e8149 100644 --- a/src/entities/house_generator.h +++ b/src/entities/house_generator.h @@ -8,6 +8,7 @@ #include "../models/Model.h" #include "../collision/collision.h" #include "../model_Storage.h" +#include "collision_entity.h" namespace entities { diff --git a/src/entities/main_character.cpp b/src/entities/main_character.cpp index cdf53c7..5c48903 100644 --- a/src/entities/main_character.cpp +++ b/src/entities/main_character.cpp @@ -7,11 +7,10 @@ #include"../renderEngine/loader.h" namespace entities { - float movement_speed; - float down_speed; - float side_speed; + int movement_speed, down_speed, side_speed; bool is_playing; + MainCharacter::MainCharacter(const models::TexturedModel& model, const glm::vec3& position, const glm::vec3& rotation, float scale, const collision::Box& bounding_box) : CollisionEntity(model, position, rotation, scale, bounding_box) @@ -19,63 +18,58 @@ namespace entities is_playing = true; } - void MainCharacter::Move(GLFWwindow* window) + void MainCharacter::Move(std::vector regions) { - if (is_playing) { - movement_speed = -0.5f; //Forward speed adjustment, bee is moving at a standard speedrate - down_speed = -1.0f; //Down speed adjustment, downspeed is difference between down_speed and UP_SPEED - side_speed = 0; //Side speed adjustment + computervision::HandDetectRegion* reg_left = regions.at(0); + computervision::HandDetectRegion* reg_up = regions.at(1); + computervision::HandDetectRegion* reg_right = regions.at(2); + double delta_time = UpdateDelta(); + + if (is_playing) { + movement_speed = -15; //Forward speed adjustment, bee is moving at a standard speedrate + down_speed = -50; //Down speed adjustment, downspeed is difference between down_speed and UP_SPEED + side_speed = 0; //Side speed adjustment //For gameplay with use of keyboard keys: W, A, S, D //W: Go forward //A: Go left //S: Go backwards //D: Go right //TODO Implement CV actions - SetRotation(glm::vec3(0, 90, 0)); - if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) - { - movement_speed -= SIDE_SPEED; - } - - if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) - { - movement_speed += SIDE_SPEED; - } //top right - if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) + SetRotation(glm::vec3(0, 90, 0)); + if (reg_up->IsHandPresent() && reg_left->IsHandPresent()) { side_speed += SIDE_SPEED; - down_speed += UP_SPEED; + down_speed += UP_SPEED/2; + SetRotation(glm::vec3(10, 90, 0)); } //right - if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) + if (reg_left->IsHandPresent()) { side_speed += SIDE_SPEED; } //top left - if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) + if (reg_up->IsHandPresent() && reg_right->IsHandPresent()) { - down_speed += UP_SPEED; + down_speed += UP_SPEED/2; side_speed -= SIDE_SPEED; + SetRotation(glm::vec3(10, 90, 0)); } //left - if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) + if (reg_right->IsHandPresent()) { side_speed -= SIDE_SPEED; } - if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) + if (reg_up->IsHandPresent()) { down_speed += UP_SPEED; SetRotation(glm::vec3(10, 90, 0)); } - if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) - { - down_speed -= UP_SPEED; - } } - IncreasePosition(glm::vec3(side_speed, down_speed, movement_speed)); + IncreasePosition(glm::vec3(side_speed*delta_time, down_speed*delta_time, movement_speed*delta_time)); + std::cout << "delta time char: "<< delta_time << std::endl; //Use only for binding bee to house, such that it doesn't go outside of the room. //TODO delete when boundingbox is implemented! @@ -85,7 +79,7 @@ namespace entities else if (position.y < -40) position.y = -40; //Move player bounding box according to the position on screen MoveCollisionBox(); - if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) + if (reg_right->IsHandPresent() && reg_left->IsHandPresent()) { is_playing = true; } @@ -97,4 +91,13 @@ namespace entities is_playing = false; std::cout << "collision" << std::endl; } + + double MainCharacter::UpdateDelta() + { + double current_time = glfwGetTime(); + static double last_frame_time = current_time; + double delt_time = current_time - last_frame_time; + last_frame_time = current_time; + return delt_time; + } } \ No newline at end of file diff --git a/src/entities/main_character.h b/src/entities/main_character.h index d1029a2..589536a 100644 --- a/src/entities/main_character.h +++ b/src/entities/main_character.h @@ -2,6 +2,7 @@ #include "collision_entity.h" #include "../shaders/entity_shader.h" +#include "../computervision/HandDetectRegion.h" namespace entities { @@ -9,8 +10,8 @@ namespace entities * This class contains the information about the player model */ class MainCharacter : public CollisionEntity { - const float SIDE_SPEED = 0.8f; //Standard movement speed for left/right movement - const float UP_SPEED = 2.0f; //Standard movement speed for up movement + const int SIDE_SPEED = 40; //Standard movement speed for left/right movement + const int UP_SPEED = 100; //Standard movement speed for up movement public: /* * @brief: Constructor for the main character model @@ -31,8 +32,10 @@ namespace entities * * @return: Vector with the adjusted side_speed, down_speed, and movement_speed */ - void Move(GLFWwindow* window); + void Move(std::vector regions); void OnCollide(const collision::Collision& collision) override; + + double UpdateDelta(); }; } diff --git a/src/main.cpp b/src/main.cpp index 2cc5640..40645f7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,15 +31,15 @@ #include "model_Storage.h" #include "computervision/ObjectDetection.h" -//#include "computervision/OpenPoseImage.h" -#include "computervision/OpenPoseVideo.h" - -#include "computervision/async/async_arm_detection.h" +#include "scenes/game_Over_Scene.h" +#include "entities/collision_entity.h" +#include "computervision/object_detection.h" #pragma comment(lib, "glfw3.lib") #pragma comment(lib, "glew32s.lib") #pragma comment(lib, "opengl32.lib") +int score; static double UpdateDelta(); static GLFWwindow* window; @@ -49,15 +49,6 @@ scene::Scene* current_scene; bool points_img_available = false; cv::Mat points_img; -void retrieve_points(std::vector arm_points, cv::Mat points_on_image) -{ - - std::cout << "got points!!" << std::endl; - std::cout << "points: " << arm_points << std::endl; - points_img = points_on_image; - points_img_available = true; -} - int main(void) { #pragma region OPENGL_SETTINGS @@ -73,9 +64,10 @@ int main(void) glewInit(); glGetError(); #pragma endregion - //current_scene = new scene::Startup_Scene(); current_scene = new scene::Loading_Scene(); + score = 0; + glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) { @@ -89,8 +81,6 @@ int main(void) bool window_open = true; - - // Main game loop while (!glfwWindowShouldClose(window) && window_open) { @@ -115,9 +105,13 @@ int main(void) case scene::Scenes::INGAME: - current_scene = new scene::In_Game_Scene(); + current_scene = new scene::In_Game_Scene(&score); break; + case scene::Scenes::GAMEOVER: + current_scene = new scene::Game_Over_Scene(score); + break; + default: std::cout << "Wrong return value!!! ->" << std::endl; break; @@ -144,4 +138,4 @@ static double UpdateDelta() double delt_time = current_time - last_frame_time; last_frame_time = current_time; return delt_time; -} +} \ No newline at end of file diff --git a/src/renderEngine/Renderer.cpp b/src/renderEngine/Renderer.cpp index f135200..70f2259 100644 --- a/src/renderEngine/Renderer.cpp +++ b/src/renderEngine/Renderer.cpp @@ -121,5 +121,87 @@ namespace render_engine shader.Stop(); } + + void Render(std::vector>& guis, shaders::GuiShader& shader) + { + shader.Start(); + + // Enable the VAO and the positions VBO + glBindVertexArray(quad.vao_id); + glEnableVertexAttribArray(0); + + // Enable alpha blending (for transparency in the texture) + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Disable depth testing to textures with transparency can overlap + glDisable(GL_DEPTH_TEST); + + // Render each gui to the screen + for (std::shared_ptr gui : guis) + { + // Bind the texture of the gui to the shader + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gui->texture); + + glm::mat4 matrix = toolbox::CreateModelMatrix(gui->position, gui->scale); + shader.LoadModelMatrix(matrix); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, quad.vertex_count); + + std::cout << "in render method, gui x value: " << gui.get()->scale.x << std::endl; + } + + // Enable depth test again + glEnable(GL_DEPTH_TEST); + + // Disable alpha blending + glDisable(GL_BLEND); + + // Disable the VBO and VAO + glDisableVertexAttribArray(0); + glBindVertexArray(0); + + shader.Stop(); + } + + void Render(std::shared_ptr& gui, shaders::GuiShader& shader) + { + shader.Start(); + + // Enable the VAO and the positions VBO + glBindVertexArray(quad.vao_id); + glEnableVertexAttribArray(0); + + // Enable alpha blending (for transparency in the texture) + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Disable depth testing to textures with transparency can overlap + glDisable(GL_DEPTH_TEST); + + // Render each gui to the screen + // Bind the texture of the gui to the shader + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gui->texture); + + glm::mat4 matrix = toolbox::CreateModelMatrix(gui->position, gui->scale); + shader.LoadModelMatrix(matrix); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, quad.vertex_count); + + + // Enable depth test again + glEnable(GL_DEPTH_TEST); + + // Disable alpha blending + glDisable(GL_BLEND); + + // Disable the VBO and VAO + glDisableVertexAttribArray(0); + glBindVertexArray(0); + + shader.Stop(); + } } } diff --git a/src/renderEngine/Renderer.h b/src/renderEngine/Renderer.h index 8a7a473..2e90e3c 100644 --- a/src/renderEngine/Renderer.h +++ b/src/renderEngine/Renderer.h @@ -40,5 +40,22 @@ namespace render_engine @param shade: The shader the GUI textures need to be rendered with */ void Render(std::vector& guis, shaders::GuiShader& shader); + + /* + * @brief: renders guis elements from a shared pointer vector + * + * @param guis: List with GUI textures to render + * @param sahde: The shader to use + */ + void Render(std::vector>& guis, shaders::GuiShader& shader); + + + /* + * @brief renders 1 gui element. + * + * @param gui: the texture to render + * @param shader: the shader to use + */ + void Render(std::shared_ptr& gui, shaders::GuiShader& shader); } } \ No newline at end of file diff --git a/src/scenes/game_Over_Scene.cpp b/src/scenes/game_Over_Scene.cpp new file mode 100644 index 0000000..a04ac48 --- /dev/null +++ b/src/scenes/game_Over_Scene.cpp @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include "game_Over_Scene.h" +#include +#include + +#include "../models/model.h" +#include "../renderEngine/loader.h" +#include "../renderEngine/obj_loader.h" +#include "../renderEngine/renderer.h" +#include "../shaders/entity_shader.h" +#include "../gui/gui_interactable.h" +#include "../toolbox/toolbox.h" +#include "../computervision/MenuTest.h" +#include "../computervision/ObjectDetection.h" +#include "../computervision/HandDetectRegion.h" + +namespace scene +{ + shaders::GuiShader* gui_shader_gameOver; + std::vector guis_gameOver; + computervision::ObjectDetection objDetect_gameOver; + std::vector> score_textures_gameOver; + + float item_number_gameOver = 0; + bool hand_mode_gameOver = false; + + Game_Over_Scene::Game_Over_Scene(int score) + { + shaders::EntityShader shader; + shader.Init(); + render_engine::renderer::Init(shader); + shader.CleanUp(); + + gui_shader_gameOver = new shaders::GuiShader(); + gui_shader_gameOver->Init(); + + for (int i = 0; i <= 9; i++) + { + std::shared_ptr score_pointer; + + std::string texture_path = "res/"; + texture_path += std::to_string(i); + texture_path += ".png"; + + score_pointer = std::make_unique(render_engine::loader::LoadTexture(texture_path), glm::vec2(0.0f, 0.2f), glm::vec2(0.07, 0.15)); + + score_textures_gameOver.push_back(score_pointer); + } + + game_over_texture = std::make_unique(render_engine::loader::LoadTexture("res/game_over.png"), glm::vec2(0.0f, 0.6f), glm::vec2(0.50f, 0.50f)); + end_score = score; + } + + gui::Button* ConvertGuiTextureToButtonGameOver(gui::GuiTexture* texture) { + gui::Button* button; + if (texture != NULL) + { + if (texture->GetType() == gui::GuiType::BUTTON) { + + button = (gui::Button*)texture; + return button; + } + else { + button = nullptr; + return button; + } + } + else { + button = nullptr; + return button; + } + } + + gui::GuiTexture* GetMenuItemGameOver(bool hand_state) { + if (hand_state) + item_number_gameOver += 0.20f; + + int temp_item_number = item_number_gameOver; + + //If temp_item_number is equal to the size of the array, set item_number bac to zero to loop through the array again + if (temp_item_number == guis_gameOver.size()) { + item_number_gameOver = 0; + temp_item_number = 0; + } + std::cout << guis_gameOver[temp_item_number]->texture << std::endl; + return guis_gameOver[temp_item_number]; + } + + scene::Scenes scene::Game_Over_Scene::start(GLFWwindow* window) { + gui::Button button_start_scene(render_engine::loader::LoadTexture("res/Birb1.jpg"), glm::vec2(0.0f, -0.5f), glm::vec2(0.25f, 0.25f)); + button_start_scene.SetHoverTexture(render_engine::loader::LoadTexture("res/Birb2.jpg")); + button_start_scene.SetClickedTexture(render_engine::loader::LoadTexture("res/Birb3.jpg")); + button_start_scene.SetOnClickAction([]() + { + std::cout << "Back to start screen!!" << std::endl; + + }); + guis_gameOver.push_back(&button_start_scene); + + computervision::ObjectDetection objDetect; + cv::Mat cameraFrame; + gui::GuiTexture* chosen_item_gameOver = NULL; //This is the selected menu_item + bool hand_closed = false; //Flag to prevent multiple button presses + + while (return_value == scene::Scenes:: GAMEOVER) + { + render(); + update(window); + + if (hand_mode_gameOver) + { + cameraFrame = objDetect_gameOver.ReadCamera(); + + bool detect = false; + bool hand_detection = objDetect_gameOver.DetectHand(cameraFrame, detect); + + if (hand_detection) + { + hand_closed = false; + std::cout << "hand is opened" << std::endl; + + //Loop through menu items + chosen_item_gameOver = GetMenuItemGameOver(true); + + gui::Button* new_button = ConvertGuiTextureToButtonGameOver(chosen_item_gameOver); + if (new_button != NULL) { + const float x_pos = (chosen_item_gameOver->position.x + 1.0) * WINDOW_WIDTH / 2; + const float y_pos = (1.0 - chosen_item_gameOver->position.y) * WINDOW_HEIGHT / 2; + + //Set cursor to location of selected menu_item + glfwSetCursorPos(window, x_pos, y_pos); + } + } + else if (!hand_detection) + { + std::cout << "hand is closed" << std::endl; + + //Gets selected menu_item + chosen_item_gameOver = GetMenuItemGameOver(false); + gui::Button* new_button = ConvertGuiTextureToButtonGameOver(chosen_item_gameOver); + + if (new_button != NULL && !hand_closed) { + //Run function click + new_button->ForceClick(GLFW_MOUSE_BUTTON_LEFT); + hand_closed = true; + } + } + } + glfwSwapBuffers(window); + glfwPollEvents(); + } + + gui_shader_gameOver->CleanUp(); + render_engine::loader::CleanUp(); + return return_value; + } + + /** + * renders the models in the start-up scene + */ + void scene::Game_Over_Scene::render() + { + render_engine::renderer::Prepare(); + + // Render GUI items + render_engine::renderer::Render(guis_gameOver, *gui_shader_gameOver); + } + + /** + * updates the variables for the start-up scene + */ + void scene::Game_Over_Scene::update(GLFWwindow* window) + { + for (gui::GuiTexture* button : guis_gameOver) { + gui::Button* new_button = ConvertGuiTextureToButtonGameOver(button); + if (new_button != NULL) + new_button->Update(window); + } + bool hand_present; + objDetect_gameOver.DetectHand(objDetect_gameOver.ReadCamera(), hand_present); + + render_engine::renderer::Render(game_over_texture, *gui_shader_gameOver); + DrawScore(end_score); + } + + /** + * manages the key input in the start-up scene + */ + void scene::Game_Over_Scene::onKey(GLFWwindow* window, int key, int scancode, int action, int mods) + { + if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) + { + //return_value = scene::Scenes::STARTUP; + cv::destroyWindow("camera"); + } + else if (glfwGetKey(window, GLFW_KEY_BACKSPACE) == GLFW_PRESS) { + hand_mode_gameOver = !hand_mode_gameOver; + } + } + + void Game_Over_Scene::DrawScore(int score) + { + std::vector digits; + score_guis_gameOver.clear(); + + toolbox::GetDigitsFromNumber(score, digits); + + for (int i = digits.size() - 1; i >= 0; i--) + { + score_textures_gameOver[digits[i]].get()->position.x = (0.15 * i - 0.05); + render_engine::renderer::Render(score_textures_gameOver[digits[i]], *gui_shader_gameOver); + } + } +} \ No newline at end of file diff --git a/src/scenes/game_Over_Scene.h b/src/scenes/game_Over_Scene.h new file mode 100644 index 0000000..5fd7203 --- /dev/null +++ b/src/scenes/game_Over_Scene.h @@ -0,0 +1,35 @@ +#pragma once +#include "scene.h" +#include "../gui/gui_element.h" + +namespace scene +{ + extern GLFWwindow* window; + + class Game_Over_Scene : public scene::Scene + { + private: + + int end_score; + scene::Scenes return_value = scene::Scenes::GAMEOVER; + std::vector> score_guis_gameOver; + std::shared_ptr game_over_texture; + + + public: + Game_Over_Scene(int score); + + Scenes start(GLFWwindow* window) override; + + void render() override; + + void update(GLFWwindow* window) override; + + void onKey(GLFWwindow* window, int key, int scancode, int action, int mods) override; + /** + * @brief: This method renders the score points onto the game window + * @param score: Score to show + */ + void DrawScore(int score); + }; +} \ No newline at end of file diff --git a/src/scenes/in_Game_Scene.cpp b/src/scenes/in_Game_Scene.cpp index f8aa2e1..c28dde0 100644 --- a/src/scenes/in_Game_Scene.cpp +++ b/src/scenes/in_Game_Scene.cpp @@ -1,36 +1,16 @@ -#include -#include -#include -#include #include "in_Game_Scene.h" -#include "startup_Scene.h" -#include "../entities/main_character.h" -#include "../collision/collision_handler.h" -#include "../gui/gui_interactable.h" -#include "../models/model.h" -#include "../renderEngine/loader.h" -#include "../renderEngine/obj_loader.h" -#include "../renderEngine/renderer.h" -#include "../shaders/entity_shader.h" -#include "../toolbox/toolbox.h" -#include "../entities/house_generator.h" -#include -#include -#include -#include -#include -#include "../computervision/HandDetectRegion.h" -#include "../computervision/ObjectDetection.h" #define MAX_MODEL_DEQUE_SIZE 6 // max amount of models to load at the same time #define UPCOMING_MODEL_AMOUNT 4 // how much models should be loaded in front of us - namespace scene { std::shared_ptrmain_character; - std::vector> collision_entities; + std::deque> collision_entities; + + //std::deque> furniture_collision; + entities::HouseGenerator* house_generator; std::deque> house_models; @@ -39,9 +19,13 @@ namespace scene shaders::EntityShader* shader; shaders::GuiShader* gui_shader; std::vector guis; + std::vector> score_textures; int furniture_count_old; int score; + int* ptr; + + float delta_time = 0; std::vector regions; computervision::HandDetectRegion reg_left("left", 0, 0, 150, 150), reg_right("right", 0, 0, 150, 150), reg_up("up", 0, 0, 150, 150); @@ -49,8 +33,9 @@ namespace scene /** * sets up the first things when the objects has been made */ - In_Game_Scene::In_Game_Scene() + In_Game_Scene::In_Game_Scene(int *score_ptr) { + ptr = score_ptr; camera = std::make_unique(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0)); shader = new shaders::EntityShader; @@ -60,9 +45,22 @@ namespace scene gui_shader = new shaders::GuiShader(); gui_shader->Init(); score = 0; + + for (int i = 0; i <= 9; i++) + { + std::shared_ptr score_pointer; + + std::string texture_path = "res/"; + texture_path += std::to_string(i); + texture_path += ".png"; + + score_pointer = std::make_unique(render_engine::loader::LoadTexture(texture_path), glm::vec2(-0.9f, 0.8f), glm::vec2(0.07, 0.15)); + score_textures.push_back(score_pointer); + } } + /** - * temporary!!!! + * temporary? * just to make some bounding boxes */ collision::Box create_bounding_box(glm::vec3 size, glm::vec3 pos, int scale) { @@ -83,32 +81,38 @@ namespace scene delete house_generator; } - - /** - * @brief loads a new chunk in front of the camera, and deletes the chunk behind the camera. - * - * @param model_pos the amount of models the camera has passed already. This is the rounded result of (z position of camera) / (size of model) - * - */ - void load_chunk(int model_pos) + + void In_Game_Scene::SetupHandDetection() { - static unsigned int furniture_count = 0; - // set up squares according to size of camera input cv::Mat camera_frame; static_camera::getCap().read(camera_frame); // get camera frame to know the width and heigth + + reg_left.SetMainSkinDetecRegion(true); + reg_right.SetMainSkinDetecRegion(false); + reg_right.SetMainSkinDetecRegion(false); + std::function callback = [this]() {OnSkinCalibrationCallback(); }; + reg_left.SetSkinTimerCallback(callback); + reg_left.SetXPos(10); reg_left.SetYPos(camera_frame.rows / 2 - reg_left.GetHeight() / 2); reg_right.SetXPos(camera_frame.cols - 10 - reg_right.GetWidth()); reg_right.SetYPos(camera_frame.rows / 2 - reg_right.GetHeight() / 2); reg_up.SetXPos(camera_frame.cols / 2 - reg_up.GetWidth() / 2); reg_up.SetYPos(10); + } + + + void In_Game_Scene::LoadChunk(int model_pos) + { + static unsigned int furniture_count = 0; std::cout << "loading model chunk" << std::endl; if (house_models.size() >= MAX_MODEL_DEQUE_SIZE * furniture_count) { for (int i = 0; i < furniture_count; i++) { house_models.pop_front(); + collision_entities.erase(collision_entities.begin() + 1); } } int z_offset = model_pos * (house_generator->GetHouseDepth()); // how much "in the distance" we should load the model @@ -116,10 +120,12 @@ namespace scene std::deque> furniture; house_generator->GenerateHouse(&furniture, glm::vec3(0, -75, -50 - z_offset), 90); furniture_count = furniture.size(); - + house_models.insert(house_models.end(), furniture.begin(), furniture.end()); + collision_entities.insert(collision_entities.end(), furniture.begin(), furniture.end()); std::cout << "funriture_count in load chunk (house included): " << furniture_count << std::endl; furniture_count_old = furniture_count - 1; + } /** @@ -135,13 +141,17 @@ namespace scene raw_model_char = render_engine::LoadObjModel("res/beeTwo.obj"); models::TexturedModel model_char = { raw_model_char, texture }; collision::Box char_box = create_bounding_box(raw_model_char.model_size, glm::vec3(0, 0, 0), 1); - main_character = std::make_shared(model_char, glm::vec3(0, -50, -100), glm::vec3(0, 90, 0), 5, char_box); - collision_entities.push_back(main_character); + main_character = std::make_shared(model_char, glm::vec3(0, 50, -100), glm::vec3(0, 90, 0), 5, char_box); + + //collision_entities.push_back(main_character); house_generator = new entities::HouseGenerator(); + + SetupHandDetection(); + // load the first few house models for (int i = 0; i <= UPCOMING_MODEL_AMOUNT; i++) { - load_chunk(i); + LoadChunk(i); } lights.push_back(entities::Light(glm::vec3(0, 1000, 7000), glm::vec3(5, 5, 5))); // sun @@ -181,6 +191,9 @@ namespace scene }); pause_guis.push_back(&pause_button_quit); + regions.push_back(®_left); + regions.push_back(®_up); + regions.push_back(®_right); //the scene loop, this while loop represent the scene while (return_value == scene::Scenes::INGAME) @@ -242,16 +255,24 @@ namespace scene // Stop rendering the entities shader->Stop(); + + DrawScore(score); } //updates certain variables void scene::In_Game_Scene::update(GLFWwindow* window) { + UpdateDeltaTime(); //camera.Move(window); + update_hand_detection(); + main_character->Move(regions); + if (!main_character.get()->GetOnCollide()) + { + *ptr = score; + std::cout << "Score: " << score << std::endl; + return_value = scene::Scenes::GAMEOVER; + } - main_character->Move(window); - - //std::cout << "x get: " << movement.x << "\ny get: " << movement.y << "\nz get: " << movement.z << "\n"; camera->Follow(main_character->GetPosition()); // calculate where the next house model should be loaded @@ -261,15 +282,19 @@ namespace scene // if we have passed a model, load a new one and delete the one behind us if (last_model_pos != model_pos) { - load_chunk(model_pos + UPCOMING_MODEL_AMOUNT); + LoadChunk(model_pos + UPCOMING_MODEL_AMOUNT); score += furniture_count_old; std::cout << "Score: " << score << std::endl; - std::cout << "Funriture_count_old in model (house excluded): " << furniture_count_old << std::endl; + std::cout << "Furniture_count_old in model (house excluded): " << furniture_count_old << std::endl; + } // remember the position at which the new model was added last_model_pos = model_pos; + collision_entities.push_front(main_character); collision::CheckCollisions(collision_entities); + collision_entities.pop_front(); + update_hand_detection(); } @@ -289,24 +314,14 @@ namespace scene { game_state = scene::Game_State::RUNNING; } - - if (glfwGetKey(window, GLFW_KEY_B) == GLFW_PRESS) - { - reg_left.CalibrateBackground(); - reg_right.CalibrateBackground(); - reg_up.CalibrateBackground(); - } - - if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) - { - std::vector tresholds = reg_left.CalculateSkinTresholds(); - reg_right.setSkinTresholds(tresholds); - reg_up.setSkinTresholds(tresholds); - } } void scene::In_Game_Scene::update_hand_detection() { + reg_left.UpdateTime(delta_time); + reg_right.UpdateTime(delta_time); + reg_up.UpdateTime(delta_time); + cv::Mat camera_frame; static_camera::getCap().read(camera_frame); reg_left.DetectHand(camera_frame); @@ -316,9 +331,41 @@ namespace scene cv::imshow("camera", camera_frame); } + void scene::In_Game_Scene::OnSkinCalibrationCallback() + { + std::cout << "on skin calibration callback" << std::endl; + std::vector tresholds = reg_left.CalculateSkinTresholds(); + reg_right.setSkinTresholds(tresholds); + reg_up.setSkinTresholds(tresholds); + } + //renders the models for the pause menu void In_Game_Scene::render_pause_menu() { render_engine::renderer::Render(pause_guis, *gui_shader); } + + void In_Game_Scene::DrawScore(int score) + { + std::vector digits; + score_guis.clear(); + + toolbox::GetDigitsFromNumber(score, digits); + + + for (int i = digits.size() - 1; i >= 0; i--) + { + score_textures[digits[i]].get()->position.x = 0.15 * i - 0.9; // place the number at the top left. the numbers are just fine tuned to get the position just right + render_engine::renderer::Render(score_textures[digits[i]], *gui_shader); + } + } + + void In_Game_Scene::UpdateDeltaTime() + { + double current_time = glfwGetTime(); + static double last_frame_time = current_time; + delta_time = current_time - last_frame_time; + last_frame_time = current_time; + + } } diff --git a/src/scenes/in_Game_Scene.h b/src/scenes/in_Game_Scene.h index dfffaec..df8c149 100644 --- a/src/scenes/in_Game_Scene.h +++ b/src/scenes/in_Game_Scene.h @@ -3,6 +3,18 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "startup_Scene.h" #include "scene.h" #include "../gui/gui_interactable.h" #include "../models/model.h" @@ -11,6 +23,12 @@ #include "../renderEngine/renderer.h" #include "../shaders/entity_shader.h" #include "../toolbox/toolbox.h" +#include "../entities/main_character.h" +#include "../collision/collision_handler.h" +#include "../entities/house_generator.h" +#include "../computervision/hand_detect_region.h" +#include "../computervision/object_detection.h" + namespace scene @@ -27,7 +45,6 @@ namespace scene PAUSED }; - class In_Game_Scene : public scene::Scene { private: @@ -53,6 +70,10 @@ namespace scene std::vector guis; //pause_guis is a list of components that will be rendered when the game is paused. std::vector pause_guis; + // list of gui texture that holds the textures for the score + std::vector> score_guis; + + void UpdateDeltaTime(); /** * @brief renders the objects/gui models @@ -60,10 +81,42 @@ namespace scene * @return void */ void render_pause_menu(); + + /** + * @brief updates the hand detection with the deltatime and checks the hand detection for each region. als updates the camera display + * + */ void update_hand_detection(); + + /** + * @brief sets up the hand detection regions and sets the callbacks for the skin calibration. + * + */ + void SetupHandDetection(); + + /** + * @brief callback that gets called when the left skin detect region timout has been reached. sets the other regions with the skin data from the first region + * + */ + void OnSkinCalibrationCallback(); + + /** + * @brief draws the score on the screen with the digit resources. + * + * @param score the score to display. + */ + void DrawScore(int score); + + /** + * @brief loads a new chunk in front of the camera, and deletes the chunk behind the camera. + * + * @param model_pos the amount of models the camera has passed already. This is the rounded result of (z position of camera) / (size of model) + * + */ + void LoadChunk(int model_pos); public: - In_Game_Scene(); + In_Game_Scene(int *score_ptr); ~In_Game_Scene(); /** @@ -97,6 +150,13 @@ namespace scene * @return void */ void onKey(GLFWwindow* window, int key, int scancode, int action, int mods) override; + + /** + * @brief: This method renders the score points onto the game window + * @param score: Score to show + */ + void DrawScore(int score); + }; } diff --git a/src/scenes/scene.h b/src/scenes/scene.h index 396a6f5..5d3be79 100644 --- a/src/scenes/scene.h +++ b/src/scenes/scene.h @@ -20,10 +20,10 @@ namespace scene { }; class Scene - { + { public: virtual ~Scene() = 0; - + /** * @brief the method start is the start of a scene where a while loop runs, this runs the scene. * @param window the main window of the application @@ -55,7 +55,6 @@ namespace scene { * @return void */ virtual void onKey(GLFWwindow* window, int key, int scancode, int action, int mods) {}; + }; } - - diff --git a/src/scenes/startup_Scene.cpp b/src/scenes/startup_Scene.cpp index 7e814e5..6e6c88f 100644 --- a/src/scenes/startup_Scene.cpp +++ b/src/scenes/startup_Scene.cpp @@ -14,8 +14,8 @@ #include "../gui/gui_interactable.h" #include "../toolbox/toolbox.h" #include "../computervision/MenuTest.h" -#include "../computervision/ObjectDetection.h" -#include "../computervision/HandDetectRegion.h" +#include "../computervision/object_detection.h" +#include "../computervision/hand_detect_region.h" diff --git a/src/toolbox/Timer.h b/src/toolbox/Timer.h index 80fd164..46b2a67 100644 --- a/src/toolbox/Timer.h +++ b/src/toolbox/Timer.h @@ -42,5 +42,7 @@ namespace toolbox * @return: True if the timer has finished */ bool HasFinished() const { return has_finished; } + + void Reset() { current_time = 0; } }; } \ No newline at end of file diff --git a/src/toolbox/toolbox.cpp b/src/toolbox/toolbox.cpp index a12cdc5..461405c 100644 --- a/src/toolbox/toolbox.cpp +++ b/src/toolbox/toolbox.cpp @@ -1,6 +1,6 @@ #include #include "toolbox.h" - +#include namespace toolbox { glm::mat4 CreateModelMatrix(glm::vec2 translation, glm::vec2 scale) @@ -56,4 +56,12 @@ namespace toolbox } return min + rand() % ((max + 1) - min); } + + void GetDigitsFromNumber(int number, std::vector& result_vector) + { + if (number >= 10) + GetDigitsFromNumber(number / 10, result_vector); + + result_vector.push_back(number % 10); + } } diff --git a/src/toolbox/toolbox.h b/src/toolbox/toolbox.h index cc5d5b9..143004c 100644 --- a/src/toolbox/toolbox.h +++ b/src/toolbox/toolbox.h @@ -2,6 +2,7 @@ #include "../entities/camera.h" #include +#include namespace toolbox { @@ -78,4 +79,13 @@ namespace toolbox * @return: The random number */ int Random(const int min, const int max); + + + /** + * @brief gets the separate digits from the number. + * + * @param number the number to get the digits from + * @param result_vector the vector to hold the individual digits. + */ + void GetDigitsFromNumber(int number, std::vector& result_vector); } diff --git a/wk2_fps.vcxproj b/wk2_fps.vcxproj index 2250702..8132452 100644 --- a/wk2_fps.vcxproj +++ b/wk2_fps.vcxproj @@ -24,15 +24,16 @@ - + + - + - - - + + + @@ -57,18 +58,18 @@ - + + - - - + + - - + + diff --git a/wk2_fps.vcxproj.filters b/wk2_fps.vcxproj.filters index 1d4f859..79510d5 100644 --- a/wk2_fps.vcxproj.filters +++ b/wk2_fps.vcxproj.filters @@ -4,11 +4,11 @@ - + - - - + + + @@ -23,13 +23,14 @@ - + + @@ -95,11 +96,9 @@ - - @@ -120,7 +119,7 @@ - + @@ -128,11 +127,11 @@ - - + + - - + + @@ -152,6 +151,7 @@ +