diff --git a/core/include/core_app.h b/core/include/core_app.h index 635eb7c..957a48d 100644 --- a/core/include/core_app.h +++ b/core/include/core_app.h @@ -36,25 +36,25 @@ class CoreApp : public ofBaseApp { static void draw_green_frame(); void draw_fps_counter() const; - ofxAzureKinect::Device kinect_device; + ofxAzureKinect::Device _kinect_device; - IntroScene intro_scene; - TrackingScene tracking_scene; + IntroScene _intro_scene; + TrackingScene _tracking_scene; - Scene *current_scene; - Scene *inactive_scene; - Scene *keyboard_triggered_scene; + Scene *_current_scene; + Scene *_inactive_scene; + Scene *_keyboard_triggered_scene; - ofFbo current_app_fbo; - ofFbo inactive_app_fbo; - ofShader transition_shader; + ofFbo _current_app_fbo; + ofFbo _inactive_app_fbo; + ofShader _transition_shader; - const std::chrono::milliseconds transition_duration = 500ms; - std::chrono::steady_clock::time_point transition_start_time; + const std::chrono::milliseconds _transition_duration = 500ms; + std::chrono::steady_clock::time_point _transition_start_time; - ofSoundPlayer ambient_sound; - ofSoundPlayer transition_to_intro_sound; - ofSoundPlayer transition_to_tracking_sound; + ofSoundPlayer _ambient_sound; + ofSoundPlayer _transition_to_intro_sound; + ofSoundPlayer _transition_to_tracking_sound; - bool show_debug_info = false; + bool _show_debug_info; }; diff --git a/core/src/core_app.cpp b/core/src/core_app.cpp index e17aa04..b650eca 100644 --- a/core/src/core_app.cpp +++ b/core/src/core_app.cpp @@ -3,17 +3,16 @@ #include CoreApp::CoreApp() : - tracking_scene({&kinect_device}), current_scene(&intro_scene), inactive_scene(&tracking_scene), - keyboard_triggered_scene(nullptr) {} + _tracking_scene({&_kinect_device}), _current_scene(&_intro_scene), _inactive_scene(&_tracking_scene), + _keyboard_triggered_scene(nullptr), _show_debug_info(false) {} -//-------------------------------------------------------------- void CoreApp::setup() { ofSetFrameRate(60); ofSetVerticalSync(true); ofLogNotice(__FUNCTION__) << "Found " << ofxAzureKinect::Device::getInstalledCount() << " installed devices."; - if (kinect_device.open()) { + if (_kinect_device.open()) { auto device_settings = ofxAzureKinect::DeviceSettings(); device_settings.syncImages = true; device_settings.depthMode = K4A_DEPTH_MODE_NFOV_UNBINNED; @@ -22,87 +21,78 @@ void CoreApp::setup() { device_settings.colorResolution = K4A_COLOR_RESOLUTION_1080P; device_settings.updateWorld = true; device_settings.updateVbo = false; - kinect_device.startCameras(device_settings); + _kinect_device.startCameras(device_settings); auto body_tracker_settings = ofxAzureKinect::BodyTrackerSettings(); body_tracker_settings.sensorOrientation = K4ABT_SENSOR_ORIENTATION_DEFAULT; body_tracker_settings.processingMode = K4ABT_TRACKER_PROCESSING_MODE_GPU; body_tracker_settings.updateBodiesImage = true; - kinect_device.startBodyTracker(body_tracker_settings); + _kinect_device.startBodyTracker(body_tracker_settings); } - current_app_fbo.allocate(ofGetWidth(), ofGetHeight(), GL_RGBA); - inactive_app_fbo.allocate(ofGetWidth(), ofGetHeight(), GL_RGBA); - transition_shader.load("shaders/transition"); + _current_app_fbo.allocate(ofGetWidth(), ofGetHeight(), GL_RGBA); + _inactive_app_fbo.allocate(ofGetWidth(), ofGetHeight(), GL_RGBA); + _transition_shader.load("shaders/transition"); - ambient_sound.load("resources/audio/gruen_ambient.wav"); - ambient_sound.play(); - ambient_sound.setLoop(true); + _ambient_sound.load("resources/audio/gruen_ambient.wav"); + _ambient_sound.play(); + _ambient_sound.setLoop(true); - transition_to_intro_sound.load("resources/audio/transition_to_intro.wav"); - transition_to_intro_sound.setVolume(0.25f); + _transition_to_intro_sound.load("resources/audio/transition_to_intro.wav"); + _transition_to_intro_sound.setVolume(0.25f); - transition_to_tracking_sound.load("resources/audio/transition_to_tracking.wav"); - transition_to_tracking_sound.setVolume(0.25f); + _transition_to_tracking_sound.load("resources/audio/transition_to_tracking.wav"); + _transition_to_tracking_sound.setVolume(0.25f); } -//-------------------------------------------------------------- void CoreApp::exit() { - kinect_device.close(); + _kinect_device.close(); ofSoundStopAll(); } -//-------------------------------------------------------------- void CoreApp::update() { - if (keyboard_triggered_scene) { - keyboard_triggered_scene->update(); + if (_keyboard_triggered_scene) { + _keyboard_triggered_scene->update(); return; } - const auto &body_skeletons = kinect_device.getBodySkeletons(); + const auto &body_skeletons = _kinect_device.getBodySkeletons(); - if (current_scene == &intro_scene && !body_skeletons.empty()) { - transition_to_tracking_sound.play(); - transition_start_time = std::chrono::steady_clock::now(); - current_scene = &tracking_scene; - } else if (current_scene == &tracking_scene && body_skeletons.empty()) { - intro_scene.reset_particles(); + if (_current_scene == &_intro_scene && !body_skeletons.empty()) { + _transition_to_tracking_sound.play(); + _transition_start_time = std::chrono::steady_clock::now(); + _current_scene = &_tracking_scene; + } else if (_current_scene == &_tracking_scene && body_skeletons.empty()) { + _intro_scene.reset_particles(); - transition_to_intro_sound.play(); - transition_start_time = std::chrono::steady_clock::now(); - current_scene = &intro_scene; + _transition_to_intro_sound.play(); + _transition_start_time = std::chrono::steady_clock::now(); + _current_scene = &_intro_scene; } - current_scene->update(); + _current_scene->update(); } -//-------------------------------------------------------------- void CoreApp::draw() { - if (keyboard_triggered_scene) { - keyboard_triggered_scene->draw(); - draw_fps_counter(); - return; - } - - auto current_time = std::chrono::steady_clock::now(); - auto elapsed_time = std::chrono::duration_cast(current_time - transition_start_time); - auto progress = static_cast(elapsed_time.count()) / static_cast(transition_duration.count()); - - if (progress < 1.0f) { - current_scene->render(); - inactive_scene->render(); - - transition_shader.begin(); - { - transition_shader.setUniformTexture("transition_tex", inactive_scene->get_frame_buffer().getTexture(), 1); - transition_shader.setUniform1f("progress", progress); - transition_shader.setUniform1f("random_offset_one", ofRandomHeight()); - transition_shader.setUniform1f("random_offset_two", ofRandomHeight()); - current_scene->get_frame_buffer().draw(0, 0); - } - transition_shader.end(); + const auto time = std::chrono::steady_clock::now(); + const auto elapsed_time = std::chrono::duration_cast(time - _transition_start_time); + const auto progress = static_cast(elapsed_time.count()) / static_cast(_transition_duration.count()); + + if (_keyboard_triggered_scene) { + _keyboard_triggered_scene->draw(); + } else if (progress < 1.0f) { + _current_scene->render(); + _inactive_scene->render(); + + _transition_shader.begin(); + _transition_shader.setUniformTexture("transition_tex", _inactive_scene->get_frame_buffer().getTexture(), 1); + _transition_shader.setUniform1f("progress", progress); + _transition_shader.setUniform1f("random_offset_one", ofRandomHeight()); + _transition_shader.setUniform1f("random_offset_two", ofRandomHeight()); + _current_scene->get_frame_buffer().draw(0, 0); + _transition_shader.end(); } else { - current_scene->draw(); + _current_scene->draw(); } draw_fps_counter(); @@ -121,80 +111,71 @@ void CoreApp::draw_green_frame() { } void CoreApp::draw_fps_counter() const { - if (!show_debug_info) { + if (!_show_debug_info) { return; } - std::ostringstream oss; + auto oss = std::ostringstream(); oss << ofToString(ofGetFrameRate(), 2) + " FPS" << std::endl; ofDrawBitmapStringHighlight(oss.str(), 10, 20); } -//-------------------------------------------------------------- void CoreApp::keyPressed(int key) { switch (key) { case 'e': - tracking_scene.toggle_skeletons(); + _tracking_scene.toggle_skeletons(); break; case 'q': - tracking_scene.trigger_global_effect({ofGetWidth(), 0}); + _tracking_scene.trigger_global_effect({ofGetWidth(), 0}); break; case 'w': - tracking_scene.trigger_global_effect({0, 0}); + _tracking_scene.trigger_global_effect({0, 0}); break; case 'a': - tracking_scene.trigger_global_effect({ofGetWidth(), ofGetHeight()}); + _tracking_scene.trigger_global_effect({ofGetWidth(), ofGetHeight()}); break; case 's': - tracking_scene.trigger_global_effect({0, ofGetHeight()}); + _tracking_scene.trigger_global_effect({0, ofGetHeight()}); break; case 'r': - tracking_scene.reset_camera(); + _tracking_scene.reset_camera(); break; case 'f': - show_debug_info = !show_debug_info; + _show_debug_info = !_show_debug_info; break; case '1': - keyboard_triggered_scene = &intro_scene; + _keyboard_triggered_scene = &_intro_scene; break; case '2': - keyboard_triggered_scene = &tracking_scene; + _keyboard_triggered_scene = &_tracking_scene; break; case '3': - keyboard_triggered_scene = nullptr; + _keyboard_triggered_scene = nullptr; break; case 'p': - intro_scene.reset_particles(); + _intro_scene.reset_particles(); + break; + default: break; } } -//-------------------------------------------------------------- void CoreApp::keyReleased(int key) {} -//-------------------------------------------------------------- void CoreApp::mouseMoved(int x, int y) {} -//-------------------------------------------------------------- void CoreApp::mouseDragged(int x, int y, int button) {} -//-------------------------------------------------------------- void CoreApp::mousePressed(int x, int y, int button) {} -//-------------------------------------------------------------- void CoreApp::mouseReleased(int x, int y, int button) {} -//-------------------------------------------------------------- void CoreApp::mouseEntered(int x, int y) {} -//-------------------------------------------------------------- void CoreApp::mouseExited(int x, int y) {} -//-------------------------------------------------------------- void CoreApp::windowResized(int w, int h) {} -//-------------------------------------------------------------- void CoreApp::gotMessage(ofMessage msg) {} -//-------------------------------------------------------------- void CoreApp::dragEvent(ofDragInfo dragInfo) {} diff --git a/core/src/main.cpp b/core/src/main.cpp index 17cc43b..e82b363 100644 --- a/core/src/main.cpp +++ b/core/src/main.cpp @@ -9,7 +9,7 @@ int main() { auto settings = ofGLWindowSettings(); settings.setSize(1920, 1080); settings.setGLVersion(4, 6); - settings.windowMode = OF_FULLSCREEN; + settings.windowMode = OF_WINDOW; const auto window = ofCreateWindow(settings); ofRunApp(window, make_shared()); diff --git a/intro/include/intro_scene.h b/intro/include/intro_scene.h index 447e3c4..f931305 100644 --- a/intro/include/intro_scene.h +++ b/intro/include/intro_scene.h @@ -1,10 +1,11 @@ #pragma once -#include #include #include -#include +#include +#include +#include #include #include @@ -21,15 +22,15 @@ class IntroScene : public Scene { void reset_particles(); private: - const int screen_width = ofGetWidth(); - const int screen_height = ofGetHeight(); + void create_logo_vectors(); + void create_logo_in_outs_vectors(); // flow field std::vector flow_field; + int flow_field_resolution; + int flow_field_cols; + int flow_field_rows; float flow_field_offset; - const int flow_field_resolution = 20; - const int flow_field_cols = ofGetWidth() / flow_field_resolution; - const int flow_field_rows = ofGetHeight() / flow_field_resolution; // particles std::array particles; @@ -44,21 +45,18 @@ class IntroScene : public Scene { // logo ofxSVG logo_svg; ofxSVG logo_in_outs_svg; - const float logo_scale = 1.0; - std::vector> logo_vectors; - std::vector> logo_in_outs_vectors; + + std::vector> logo_vectors; + std::vector> logo_in_outs_vectors; std::vector> all_logo_vectors; ofxSVG logo_picture; ofFbo logo_fbo; ofVec2f logo_position; - float logo_width; - float logo_height; - int logo_left, logo_right, logo_top, logo_bottom; ofVec2f logo_center; float logo_radius; - int logo_margin = 30; + int logo_margin; ofFbo particle_draw_fbo; @@ -66,7 +64,4 @@ class IntroScene : public Scene { ofShader particle_pixel_shader; int line_position = 0; - - void create_logo_vectors(); - void create_logo_in_outs_vectors(); }; diff --git a/intro/src/intro_scene.cpp b/intro/src/intro_scene.cpp index 2bad6a3..87d186a 100644 --- a/intro/src/intro_scene.cpp +++ b/intro/src/intro_scene.cpp @@ -5,10 +5,15 @@ #include #include +#include IntroScene::IntroScene() { - flow_field.resize(flow_field_cols * flow_field_rows); // initialize vector field - flow_field_offset = 0.0; + flow_field_resolution = 20; + flow_field_cols = ofGetWidth() / flow_field_resolution; + flow_field_rows = ofGetHeight() / flow_field_resolution; + flow_field.resize(flow_field_cols * flow_field_rows); + + flow_field_offset = 0; logo_picture.load("resources/media_error_logo.svg"); logo_fbo.allocate(ofGetWidth(), ofGetHeight(), GL_RGB); @@ -36,13 +41,11 @@ IntroScene::IntroScene() { logo_svg.load("resources/media_error_logo_lines.svg"); logo_in_outs_svg.load("resources/logo_in_and_out_lines.svg"); logo_position = ofVec2f(ofGetWidth() / 2, ofGetHeight() / 2); - logo_width = logo_svg.getWidth() * logo_scale; - logo_height = logo_svg.getHeight() * logo_scale; - logo_left = screen_width / 2 - logo_svg.getWidth() / 2; - logo_right = screen_width / 2 + logo_svg.getWidth() / 2; - logo_top = screen_height / 2 - logo_svg.getHeight() / 2; - logo_bottom = screen_height / 2 + logo_svg.getHeight() / 2; + float logo_left = ofGetWidth() / 2.0f - logo_svg.getWidth() / 2.0f; + float logo_right = ofGetWidth() / 2.0f + logo_svg.getWidth() / 2.0f; + float logo_top = ofGetHeight() / 2.0f - logo_svg.getHeight() / 2.0f; + float logo_bottom = ofGetHeight() / 2.0f + logo_svg.getHeight() / 2.0f; create_logo_vectors(); create_logo_in_outs_vectors(); @@ -54,7 +57,7 @@ IntroScene::IntroScene() { ofRectangle boundingBoxLogo; for (int i = 0; i < logo_svg.getNumPath(); i++) { ofPath path = logo_svg.getPathAt(i); - vector outlines = path.getOutline(); + std::vector outlines = path.getOutline(); for (auto &outline: outlines) { boundingBoxLogo.growToInclude(outline.getBoundingBox()); } @@ -63,6 +66,7 @@ IntroScene::IntroScene() { // Mittelpunkt und Radius des Kreises berechnen logo_center = ofVec2f(boundingBoxLogo.getCenter().x + logo_left, boundingBoxLogo.getCenter().y + logo_top); logo_radius = (std::max(boundingBoxLogo.getWidth(), boundingBoxLogo.getHeight()) / 2.0f); + logo_margin = 30; } //-------------------------------------------------------------- @@ -186,9 +190,6 @@ void IntroScene::create_logo_vectors() { for (auto &outline: outlines) { outline = outline.getResampledBySpacing(4); // Resample für gleichmäßige Punkte - for (auto &point: outline) { - point *= logo_scale; - } bounding_box.growToInclude(outline.getBoundingBox()); } } @@ -207,8 +208,8 @@ void IntroScene::create_logo_vectors() { for (auto &outline: outlines) { outline = outline.getResampledBySpacing(4); // Optional: Punkte gleichmäßig verteilen for (int j = 0; j < outline.size() - 1; j++) { - ofVec2f start = ofVec2f(outline[j]) * logo_scale + offset; - ofVec2f end = ofVec2f(outline[j + 1]) * logo_scale + offset; + ofVec2f start = ofVec2f(outline[j]) + offset; + ofVec2f end = ofVec2f(outline[j + 1]) + offset; // Richtung berechnen entlang des Pfades ofVec2f direction = end - start; @@ -238,9 +239,6 @@ void IntroScene::create_logo_in_outs_vectors() { for (auto &outline: outlines) { outline = outline.getResampledBySpacing(4); // Resample für gleichmäßige Punkte - for (auto &point: outline) { - point *= logo_scale; - } bounding_box.growToInclude(outline.getBoundingBox()); } } @@ -259,8 +257,8 @@ void IntroScene::create_logo_in_outs_vectors() { for (auto &outline: outlines) { outline = outline.getResampledBySpacing(4); // Optional: Punkte gleichmäßig verteilen for (int j = 0; j < outline.size() - 1; j++) { - ofVec2f start = ofVec2f(outline[j]) * logo_scale + offset; - ofVec2f end = ofVec2f(outline[j + 1]) * logo_scale + offset; + ofVec2f start = ofVec2f(outline[j]) + offset; + ofVec2f end = ofVec2f(outline[j + 1]) + offset; // Richtung berechnen entlang des Pfades ofVec2f direction = end - start; diff --git a/shared/include/scene.h b/shared/include/scene.h index 4716ff6..b4d5812 100644 --- a/shared/include/scene.h +++ b/shared/include/scene.h @@ -1,6 +1,6 @@ #pragma once -#include +#include class Scene { public: diff --git a/tracking/include/collision_object.h b/tracking/include/collision_object.h index e81e54a..78f617d 100644 --- a/tracking/include/collision_object.h +++ b/tracking/include/collision_object.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -20,7 +21,7 @@ class CollisionObject { CollisionObject(glm::vec2 position, glm::vec2 velocity, const std::string &filename, std::shared_ptr effect_shader); - void update(std::vector &players, const std::vector &objects, const ofEasyCam &camera); + void update(std::vector &players, const std::vector &objects); void draw() const; std::pair global_effect_triggered(); @@ -33,11 +34,12 @@ class CollisionObject { glm::vec2 velocity() const; std::shared_ptr effect_shader() const; - protected: + private: void play_random_pluck(); void play_random_noise_hit(); - std::pair check_collision_with_bodies(std::vector &players, const ofEasyCam &camera); - std::pair check_collision_with_objects(const std::vector &objects); + + std::optional check_collision_with_bodies(std::vector &players) const; + std::optional check_collision_with_objects(const std::vector &objects) const; const float _min_speed = 5; const float _max_speed = 20; diff --git a/tracking/shaders/render/cloud.frag b/tracking/shaders/render/cloud.frag index 885a7ff..e990d09 100644 --- a/tracking/shaders/render/cloud.frag +++ b/tracking/shaders/render/cloud.frag @@ -1,13 +1,31 @@ #version 150 -in vec4 vColor; +in vec4 v_color; +in vec3 v_normal; +in vec3 v_frag_pos; -out vec4 fragColor; +out vec4 frag_color; void main() { - if (vColor.a == 0) { + if (v_color.a == 0) { discard; } - fragColor = vColor; + // hardcoded light properties + vec3 light_dir = normalize(vec3(0.5, 0.7, 1.0)); + vec3 light_color = vec3(1.0, 1.0, 0.9); + + // ambient component + float ambient_strength = 0.3; + vec3 ambient = ambient_strength * light_color; + + // diffuse component + vec3 normal = normalize(v_normal); + float diff = max(dot(normal, light_dir), 0.0); + vec3 diffuse = diff * light_color; + + // combine lighting with base color + vec3 result = (ambient + diffuse) * v_color.rgb; + + frag_color = vec4(result, v_color.a); } diff --git a/tracking/shaders/render/cloud.vert b/tracking/shaders/render/cloud.vert index e703350..a11d65d 100644 --- a/tracking/shaders/render/cloud.vert +++ b/tracking/shaders/render/cloud.vert @@ -15,7 +15,47 @@ uniform int player_id; uniform int time; -out vec4 vColor; +out vec4 v_color; +out vec3 v_normal; +out vec3 v_frag_pos; + +vec3 normal_vector(vec2 tex_coord, vec4 pos_world) { + vec3 normal = vec3(0.0, 0.0, 1.0); + if (tex_coord.x < frame_size.x - 1 && tex_coord.y < frame_size.y - 1) { + // get positions of adjacent pixels + vec2 right_coord = tex_coord + vec2(1.0, 0.0); + vec2 bottom_coord = tex_coord + vec2(0.0, 1.0); + + float right_depth = texture(depth_texture, right_coord).x; + float bottomDepth = texture(depth_texture, bottom_coord).x; + + vec4 right_ray = texture(world_texture, right_coord); + vec4 bottom_ray = texture(world_texture, bottom_coord); + + vec3 right_pos = vec3( + right_ray.x * right_depth * 65535.0, + right_ray.y * right_depth * 65535.0, + right_depth * 65535.0 + ); + + vec3 bottom_pos = vec3( + bottom_ray.x * bottomDepth * 65535.0, + bottom_ray.y * bottomDepth * 65535.0, + bottomDepth * 65535.0 + ); + + vec3 currentPos = vec3(pos_world.x, pos_world.y, pos_world.z); + + // calculate normal from adjacent positions + if (right_depth > 0.0 && bottomDepth > 0.0) { + vec3 right_vec = right_pos - currentPos; + vec3 bottom_vec = bottom_pos - currentPos; + normal = normalize(cross(right_vec, bottom_vec)); + } + } + + return normal; +} void main() { vec2 tex_coord = vec2(gl_InstanceID % frame_size.x, gl_InstanceID / frame_size.x); @@ -24,16 +64,10 @@ void main() { int body_index = int(texture(body_index_texture, tex_coord).x * 255); vec4 ray = texture(world_texture, tex_coord); - if (body_ids[body_index] == player_id && depth != 0 && ray.x != 0 && ray.y != 0) { - vColor = vec4(0, 1, 0, 1); - } else { - vColor = vec4(0); - } - - vec4 posWorld = vec4(1); - posWorld.z = depth * 65535.0; - posWorld.x = ray.x * posWorld.z; - posWorld.y = ray.y * posWorld.z; + vec4 pos_world = vec4(1); + pos_world.z = depth * 65535.0; + pos_world.x = ray.x * pos_world.z; + pos_world.y = ray.y * pos_world.z; float min_grid_size = 15; float max_grid_size = 20; @@ -43,9 +77,18 @@ void main() { float offset = (max_grid_size + min_grid_size) / 2.0; float grid_size = amplitude * sin(time * speed) + offset; - posWorld.x = floor(posWorld.x / grid_size) * grid_size; - posWorld.y = floor(posWorld.y / grid_size) * grid_size; - posWorld.z = floor(posWorld.z / grid_size) * grid_size; + pos_world.x = floor(pos_world.x / grid_size) * grid_size; + pos_world.y = floor(pos_world.y / grid_size) * grid_size; + pos_world.z = floor(pos_world.z / grid_size) * grid_size; + + v_normal = normal_vector(tex_coord, pos_world); + v_frag_pos = vec3(pos_world.xyz); - gl_Position = modelViewProjectionMatrix * posWorld; + if (body_ids[body_index] == player_id && depth != 0 && ray.x != 0 && ray.y != 0) { + v_color = vec4(0.0, 1.0, 0.0, 1.0); + } else { + v_color = vec4(0.0); + } + + gl_Position = modelViewProjectionMatrix * pos_world; } diff --git a/tracking/shaders/render/default.frag b/tracking/shaders/render/default.frag index a4a1312..e990d09 100644 --- a/tracking/shaders/render/default.frag +++ b/tracking/shaders/render/default.frag @@ -1,13 +1,31 @@ #version 150 -in vec4 vColor; +in vec4 v_color; +in vec3 v_normal; +in vec3 v_frag_pos; -out vec4 fragColor; +out vec4 frag_color; void main() { - if (vColor.a == 0) { + if (v_color.a == 0) { discard; } - fragColor = vColor; -} \ No newline at end of file + // hardcoded light properties + vec3 light_dir = normalize(vec3(0.5, 0.7, 1.0)); + vec3 light_color = vec3(1.0, 1.0, 0.9); + + // ambient component + float ambient_strength = 0.3; + vec3 ambient = ambient_strength * light_color; + + // diffuse component + vec3 normal = normalize(v_normal); + float diff = max(dot(normal, light_dir), 0.0); + vec3 diffuse = diff * light_color; + + // combine lighting with base color + vec3 result = (ambient + diffuse) * v_color.rgb; + + frag_color = vec4(result, v_color.a); +} diff --git a/tracking/shaders/render/default.vert b/tracking/shaders/render/default.vert index 991dc2a..aca77eb 100644 --- a/tracking/shaders/render/default.vert +++ b/tracking/shaders/render/default.vert @@ -15,7 +15,47 @@ uniform int player_id; uniform int time; -out vec4 vColor; +out vec4 v_color; +out vec3 v_normal; +out vec3 v_frag_pos; + +vec3 normal_vector(vec2 tex_coord, vec4 pos_world) { + vec3 normal = vec3(0.0, 0.0, 1.0); + if (tex_coord.x < frame_size.x - 1 && tex_coord.y < frame_size.y - 1) { + // get positions of adjacent pixels + vec2 right_coord = tex_coord + vec2(1.0, 0.0); + vec2 bottom_coord = tex_coord + vec2(0.0, 1.0); + + float right_depth = texture(depth_texture, right_coord).x; + float bottomDepth = texture(depth_texture, bottom_coord).x; + + vec4 right_ray = texture(world_texture, right_coord); + vec4 bottom_ray = texture(world_texture, bottom_coord); + + vec3 right_pos = vec3( + right_ray.x * right_depth * 65535.0, + right_ray.y * right_depth * 65535.0, + right_depth * 65535.0 + ); + + vec3 bottom_pos = vec3( + bottom_ray.x * bottomDepth * 65535.0, + bottom_ray.y * bottomDepth * 65535.0, + bottomDepth * 65535.0 + ); + + vec3 currentPos = vec3(pos_world.x, pos_world.y, pos_world.z); + + // calculate normal from adjacent positions + if (right_depth > 0.0 && bottomDepth > 0.0) { + vec3 right_vec = right_pos - currentPos; + vec3 bottom_vec = bottom_pos - currentPos; + normal = normalize(cross(right_vec, bottom_vec)); + } + } + + return normal; +} void main() { vec2 tex_coord = vec2(gl_InstanceID % frame_size.x, gl_InstanceID / frame_size.x); @@ -24,16 +64,19 @@ void main() { int body_index = int(texture(body_index_texture, tex_coord).x * 255); vec4 ray = texture(world_texture, tex_coord); + vec4 pos_world = vec4(1); + pos_world.z = depth * 65535.0; + pos_world.x = ray.x * pos_world.z; + pos_world.y = ray.y * pos_world.z; + + v_normal = normal_vector(tex_coord, pos_world); + v_frag_pos = vec3(pos_world.xyz); + if (body_ids[body_index] == player_id && depth != 0 && ray.x != 0 && ray.y != 0) { - vColor = vec4(0.0, 1.0, 0, 1.0); + v_color = vec4(0.0, 1.0, 0.0, 1.0); } else { - vColor = vec4(0.0); + v_color = vec4(0.0); } - - vec4 posWorld = vec4(1); - posWorld.z = depth * 65535.0; - posWorld.x = ray.x * posWorld.z; - posWorld.y = ray.y * posWorld.z; - - gl_Position = modelViewProjectionMatrix * posWorld; + + gl_Position = modelViewProjectionMatrix * pos_world; } diff --git a/tracking/shaders/render/matrix.frag b/tracking/shaders/render/matrix.frag index a4a1312..e990d09 100644 --- a/tracking/shaders/render/matrix.frag +++ b/tracking/shaders/render/matrix.frag @@ -1,13 +1,31 @@ #version 150 -in vec4 vColor; +in vec4 v_color; +in vec3 v_normal; +in vec3 v_frag_pos; -out vec4 fragColor; +out vec4 frag_color; void main() { - if (vColor.a == 0) { + if (v_color.a == 0) { discard; } - fragColor = vColor; -} \ No newline at end of file + // hardcoded light properties + vec3 light_dir = normalize(vec3(0.5, 0.7, 1.0)); + vec3 light_color = vec3(1.0, 1.0, 0.9); + + // ambient component + float ambient_strength = 0.3; + vec3 ambient = ambient_strength * light_color; + + // diffuse component + vec3 normal = normalize(v_normal); + float diff = max(dot(normal, light_dir), 0.0); + vec3 diffuse = diff * light_color; + + // combine lighting with base color + vec3 result = (ambient + diffuse) * v_color.rgb; + + frag_color = vec4(result, v_color.a); +} diff --git a/tracking/shaders/render/matrix.vert b/tracking/shaders/render/matrix.vert index 5944207..6946b43 100644 --- a/tracking/shaders/render/matrix.vert +++ b/tracking/shaders/render/matrix.vert @@ -8,19 +8,58 @@ uniform sampler2DRect depth_texture; uniform sampler2DRect body_index_texture; uniform sampler2DRect world_texture; -// Matrix effect texture is a Rect texture uniform sampler2DRect matrix_texture; uniform ivec2 frame_size; uniform int[6] body_ids; + uniform int player_id; + uniform int time; -out vec4 vColor; +out vec4 v_color; +out vec3 v_normal; +out vec3 v_frag_pos; -void main() { - vec2 matrix_texture_size = textureSize(matrix_texture); +vec3 normal_vector(vec2 tex_coord, vec4 pos_world) { + vec3 normal = vec3(0.0, 0.0, 1.0); + if (tex_coord.x < frame_size.x - 1 && tex_coord.y < frame_size.y - 1) { + // get positions of adjacent pixels + vec2 right_coord = tex_coord + vec2(1.0, 0.0); + vec2 bottom_coord = tex_coord + vec2(0.0, 1.0); + + float right_depth = texture(depth_texture, right_coord).x; + float bottomDepth = texture(depth_texture, bottom_coord).x; + + vec4 right_ray = texture(world_texture, right_coord); + vec4 bottom_ray = texture(world_texture, bottom_coord); + + vec3 right_pos = vec3( + right_ray.x * right_depth * 65535.0, + right_ray.y * right_depth * 65535.0, + right_depth * 65535.0 + ); + + vec3 bottom_pos = vec3( + bottom_ray.x * bottomDepth * 65535.0, + bottom_ray.y * bottomDepth * 65535.0, + bottomDepth * 65535.0 + ); + + vec3 currentPos = vec3(pos_world.x, pos_world.y, pos_world.z); + + // calculate normal from adjacent positions + if (right_depth > 0.0 && bottomDepth > 0.0) { + vec3 right_vec = right_pos - currentPos; + vec3 bottom_vec = bottom_pos - currentPos; + normal = normalize(cross(right_vec, bottom_vec)); + } + } + + return normal; +} +void main() { vec2 tex_coord = vec2(gl_InstanceID % frame_size.x, gl_InstanceID / frame_size.x); float depth = texture(depth_texture, tex_coord).x; @@ -31,20 +70,23 @@ void main() { pos_world.z = depth * 65535.0; pos_world.x = ray.x * pos_world.z; pos_world.y = ray.y * pos_world.z; - pos_world.w = 1.0; - gl_Position = modelViewProjectionMatrix * pos_world; + v_normal = normal_vector(tex_coord, pos_world); + v_frag_pos = vec3(pos_world.xyz); + vec2 matrix_texture_size = textureSize(matrix_texture); if (body_ids[body_index] == player_id && depth != 0 && ray.x != 0 && ray.y != 0) { const float scale = 0.4; const float speed = 0.1; vec2 matrix_texcoord; matrix_texcoord.x = mod(pos_world.x * scale, matrix_texture_size.x); - matrix_texcoord.y = mod(pos_world.y * scale + time * speed, matrix_texture_size.y); + matrix_texcoord.y = mod(pos_world.y * scale - time * speed, matrix_texture_size.y); - vColor = texture(matrix_texture, matrix_texcoord); + v_color = texture(matrix_texture, matrix_texcoord); } else { - vColor = vec4(0.0); + v_color = vec4(0.0); } -} \ No newline at end of file + + gl_Position = modelViewProjectionMatrix * pos_world; +} diff --git a/tracking/shaders/render/warp.frag b/tracking/shaders/render/warp.frag index 885a7ff..e990d09 100644 --- a/tracking/shaders/render/warp.frag +++ b/tracking/shaders/render/warp.frag @@ -1,13 +1,31 @@ #version 150 -in vec4 vColor; +in vec4 v_color; +in vec3 v_normal; +in vec3 v_frag_pos; -out vec4 fragColor; +out vec4 frag_color; void main() { - if (vColor.a == 0) { + if (v_color.a == 0) { discard; } - fragColor = vColor; + // hardcoded light properties + vec3 light_dir = normalize(vec3(0.5, 0.7, 1.0)); + vec3 light_color = vec3(1.0, 1.0, 0.9); + + // ambient component + float ambient_strength = 0.3; + vec3 ambient = ambient_strength * light_color; + + // diffuse component + vec3 normal = normalize(v_normal); + float diff = max(dot(normal, light_dir), 0.0); + vec3 diffuse = diff * light_color; + + // combine lighting with base color + vec3 result = (ambient + diffuse) * v_color.rgb; + + frag_color = vec4(result, v_color.a); } diff --git a/tracking/shaders/render/warp.vert b/tracking/shaders/render/warp.vert index d675383..25342f8 100644 --- a/tracking/shaders/render/warp.vert +++ b/tracking/shaders/render/warp.vert @@ -15,7 +15,47 @@ uniform int player_id; uniform int time; -out vec4 vColor; +out vec4 v_color; +out vec3 v_normal; +out vec3 v_frag_pos; + +vec3 normal_vector(vec2 tex_coord, vec4 pos_world) { + vec3 normal = vec3(0.0, 0.0, 1.0); + if (tex_coord.x < frame_size.x - 1 && tex_coord.y < frame_size.y - 1) { + // get positions of adjacent pixels + vec2 right_coord = tex_coord + vec2(1.0, 0.0); + vec2 bottom_coord = tex_coord + vec2(0.0, 1.0); + + float right_depth = texture(depth_texture, right_coord).x; + float bottomDepth = texture(depth_texture, bottom_coord).x; + + vec4 right_ray = texture(world_texture, right_coord); + vec4 bottom_ray = texture(world_texture, bottom_coord); + + vec3 right_pos = vec3( + right_ray.x * right_depth * 65535.0, + right_ray.y * right_depth * 65535.0, + right_depth * 65535.0 + ); + + vec3 bottom_pos = vec3( + bottom_ray.x * bottomDepth * 65535.0, + bottom_ray.y * bottomDepth * 65535.0, + bottomDepth * 65535.0 + ); + + vec3 currentPos = vec3(pos_world.x, pos_world.y, pos_world.z); + + // calculate normal from adjacent positions + if (right_depth > 0.0 && bottomDepth > 0.0) { + vec3 right_vec = right_pos - currentPos; + vec3 bottom_vec = bottom_pos - currentPos; + normal = normalize(cross(right_vec, bottom_vec)); + } + } + + return normal; +} void main() { vec2 tex_coord = vec2(gl_InstanceID % frame_size.x, gl_InstanceID / frame_size.x); @@ -24,19 +64,22 @@ void main() { int body_index = int(texture(body_index_texture, tex_coord).x * 255); vec4 ray = texture(world_texture, tex_coord); + vec4 pos_world = vec4(1); + pos_world.z = depth * 65535.0; + pos_world.x = ray.x * pos_world.z; + pos_world.y = ray.y * pos_world.z; + + v_normal = normal_vector(tex_coord, pos_world); + v_frag_pos = vec3(pos_world.xyz); + + const float amplitude = 20.0; + pos_world.x += sin(pos_world.y * 0.05 + time / 100.0) * amplitude; + if (body_ids[body_index] == player_id && depth != 0 && ray.x != 0 && ray.y != 0) { - vColor = vec4(0, 1, 0, 1); + v_color = vec4(0.0, 1.0, 0.0, 1.0); } else { - vColor = vec4(0); + v_color = vec4(0.0); } - - vec4 posWorld = vec4(1); - posWorld.z = depth * 65535.0; - posWorld.x = ray.x * posWorld.z; - posWorld.y = ray.y * posWorld.z; - - float amplitude = 20.0; - posWorld.x += sin(posWorld.y * 0.05 + time / 100.0) * amplitude; - - gl_Position = modelViewProjectionMatrix * posWorld; + + gl_Position = modelViewProjectionMatrix * pos_world; } diff --git a/tracking/src/collision_object.cpp b/tracking/src/collision_object.cpp index 9051441..5cd060e 100644 --- a/tracking/src/collision_object.cpp +++ b/tracking/src/collision_object.cpp @@ -50,8 +50,7 @@ CollisionObject::CollisionObject(glm::vec2 position, glm::vec2 velocity, const s } } -void CollisionObject::update(std::vector &players, const std::vector &objects, - const ofEasyCam &camera) { +void CollisionObject::update(std::vector &players, const std::vector &objects) { if (_position.x <= 0 || _position.x + width() >= ofGetWidth()) { play_random_pluck(); _velocity.x *= -1; @@ -62,26 +61,26 @@ void CollisionObject::update(std::vector &players, const std::vector CollisionObject::check_collision_with_bodies(std::vector &players, - const ofEasyCam &camera) { +std::optional CollisionObject::check_collision_with_bodies(std::vector &players) const { for (auto &player: players) { - // Zugriff auf die Skeleton-Vertices des Spielers const auto &lines = player.get_skeleton_lines(); const auto &velocities = player.get_skeleton_velocities(); @@ -159,18 +156,19 @@ std::pair CollisionObject::check_collision_with_bodies(std::vec if (bounding_box.intersects(line[0], line[1])) { player.set_shader(_effect_shader); - auto new_velocity = -_velocity; + auto new_velocity = -(_velocity); new_velocity += line_velocity[0]; - return {true, new_velocity}; + return new_velocity; } } } - return {false, {0, 0}}; + return std::nullopt; } -std::pair CollisionObject::check_collision_with_objects(const std::vector &objects) { +std::optional +CollisionObject::check_collision_with_objects(const std::vector &objects) const { auto this_bounds = ofRectangle(position().x, position().y, width(), height()); for (const auto &object: objects) { if (this == &object) { @@ -198,11 +196,11 @@ std::pair CollisionObject::check_collision_with_objects(const s new_velocity.y = -(new_velocity.y); // bounce vertically } - return {true, new_velocity}; + return new_velocity; } } - return {false, _velocity}; + return std::nullopt; } float CollisionObject::width() const { return _image.getWidth(); } diff --git a/tracking/src/tracking_scene.cpp b/tracking/src/tracking_scene.cpp index 12d9744..f1ec398 100644 --- a/tracking/src/tracking_scene.cpp +++ b/tracking/src/tracking_scene.cpp @@ -81,7 +81,7 @@ void TrackingScene::update() { } for (auto &collision_object: _collision_objects) { - collision_object.update(_players, _collision_objects, _camera); + collision_object.update(_players, _collision_objects); if (ofGetSystemTimeMillis() - _global_effect_trigger_time > _global_effect_duration) { auto [triggered, position] = collision_object.global_effect_triggered(); diff --git a/tracking/tracking.vcxproj.filters b/tracking/tracking.vcxproj.filters index 3e9238f..4ad575a 100644 --- a/tracking/tracking.vcxproj.filters +++ b/tracking/tracking.vcxproj.filters @@ -1810,5 +1810,11 @@ resources\audio + + shaders\render + + + shaders\render + \ No newline at end of file