From 72139509e302f7340ef37012d2ae3ff1a69ea34d Mon Sep 17 00:00:00 2001 From: cailean Date: Thu, 22 Aug 2024 15:05:41 +0100 Subject: [PATCH] interpolation movement --- .vscode/c_cpp_properties.json | 4 +- Demo.code-workspace | 89 ++++++++++++++++++++++++++++++++++- src/Player.cpp | 6 ++- src/Player.h | 1 + src/Request.h | 1 + src/TSNEMap.cpp | 84 ++++++++++++++++++++++++++++++--- src/TSNEMap.h | 17 ++++++- src/ofApp.cpp | 2 +- 8 files changed, 192 insertions(+), 12 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 7e2796a..008e0d8 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -106,7 +106,9 @@ "/usr/include/gstreamer-1.0", "/usr/include/glib-2.0", "${workspaceRoot}", - "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxTSNE/src" + "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxTSNE/src", + "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxGui/src", + "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxTSNE/src/bhtsne" ], "browse": { "limitSymbolsToIncludedHeaders": true, diff --git a/Demo.code-workspace b/Demo.code-workspace index 7c78bf5..0005300 100644 --- a/Demo.code-workspace +++ b/Demo.code-workspace @@ -10,5 +10,92 @@ "path": "${workspaceRoot}/../../../../addons" } ], - "settings": {} + "settings": { + "files.associations": { + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "strstream": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdint": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "expected": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "source_location": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp", + "format": "cpp", + "stdfloat": "cpp", + "__nullptr": "cpp" + } + } } \ No newline at end of file diff --git a/src/Player.cpp b/src/Player.cpp index 51e5ad6..0c5e965 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -3,7 +3,7 @@ Player::Player(){ hasVideo = false; playerVideoIndex = 0; - req.setup("192.168.0.54", 2000, "search"); + req.setup("192.168.0.53", 2000, "search"); resp.folder = "fingers.mp4"; resp.video = "movies/fingers.mp4"; @@ -93,6 +93,10 @@ string Player::getFrameName(){ return imagePath; } +int Player::getFrameIndex(){ + return resp.index; +} + void Player::setupGUI(){ gui.setup("Embeddings"); diff --git a/src/Player.h b/src/Player.h index dd158a4..d0b6420 100644 --- a/src/Player.h +++ b/src/Player.h @@ -20,6 +20,7 @@ class Player { void updateVector(); void checkNewFrame(); string getFrameName(); + int getFrameIndex(); ofVideoPlayer videoPlayer; diff --git a/src/Request.h b/src/Request.h index 4ab691d..e607f6a 100644 --- a/src/Request.h +++ b/src/Request.h @@ -32,6 +32,7 @@ struct VPQuery{ std::string video; std::string image; int frame; + int index; }; class Request { diff --git a/src/TSNEMap.cpp b/src/TSNEMap.cpp index bb33c62..a2f4131 100644 --- a/src/TSNEMap.cpp +++ b/src/TSNEMap.cpp @@ -1,8 +1,13 @@ #include "TSNEMap.h" +#include "Request.h" + + TSNEMap::TSNEMap(){ image.load("images/happy.jpeg"); - zoomLevel = 1.0; + zoomLevel = 1; + velocity = glm::vec3(0.0f,0.0f,0.0f); + acceleration = glm::vec3(0.0f,0.0f,0.0f); } void TSNEMap::setup(){ @@ -15,6 +20,8 @@ void TSNEMap::setup(){ // Setup top-down orthographic camera cam.setNearClip(-1000000); cam.setFarClip(1000000); + cam.setPosition(0, 0, 0); + cam.setScale(zoomLevel, zoomLevel, zoomLevel); } void TSNEMap::setupTSNE(std::string jsonPath){ @@ -32,6 +39,10 @@ void TSNEMap::setupTSNE(std::string jsonPath){ // Check if the entry has a "vector" field if (entry.contains("vector") && entry["vector"].is_array()) { std::vector vec; + std::string imagePath; + ImageHM imageEntry; + + imagePath = entry["image"]; // Loop through each value in the "vector" field for (const auto& value : entry["vector"]) { @@ -45,6 +56,11 @@ void TSNEMap::setupTSNE(std::string jsonPath){ // Add the extracted vector to the list embeddings.push_back(vec); + + imageEntry.imagePath = imagePath; + imageEntry.vec = vec; + imageMap.push_back(imageEntry); + } else { ofLogError() << "Entry does not contain a valid 'vector' field"; } @@ -54,12 +70,14 @@ void TSNEMap::setupTSNE(std::string jsonPath){ tsnePoints = tsne.run(embeddings, dims, perplexity, theta, normalise, runManually); // Output the vectors to the console (for debugging) - for (const auto& vec : tsnePoints) { - for (float value : vec) { - std::cout << value << " "; - } - std::cout << std::endl; + for (size_t i = 0; i < tsnePoints.size(); ++i){ + const auto& vec = tsnePoints[i]; + auto& imgHM = imageMap[i]; + imgHM.position = glm::vec2(vec[0], vec[1]); + + imageHashmap[imgHM.imagePath] = imgHM.position; } + } void TSNEMap::setupNodes(){ @@ -127,7 +145,11 @@ void TSNEMap::setupNodes(){ } -void TSNEMap::update(){ +void TSNEMap::update(std::string imagePath){ + + bool imageCheck = false; + + if (!image.isAllocated()){ ofLogError() << "Image not found"; } @@ -142,6 +164,15 @@ void TSNEMap::update(){ object.plane.setPosition(object.plane.getPosition().x + offsetX, object.plane.getPosition().y + offsetY, 0); } + + if (imageHashmap.find(imagePath) != imageHashmap.end()){ + glm::vec2 position = imageHashmap[imagePath]; + + // Move camera to image + MoveCameraToPosition(position); + } else { + ofLogError() << "Image not found in HashMap"; + } } void TSNEMap::draw(){ @@ -176,6 +207,45 @@ void TSNEMap::draw(){ fbo.draw(0, 0, ofGetWindowWidth() / 3, ofGetWindowHeight() / 3 * 2); } +void TSNEMap::MoveCameraToPosition(glm::vec2 position){ + + glm::vec3 currentPosition(cam.getPosition().x, cam.getPosition().y, 0); + glm::vec3 targetPosition((position.x * 5000) - 2500, (position.y * 5000) - 2500, 0); + glm::vec3 direction = targetPosition - currentPosition; + float distance = glm::length(direction); + + direction = glm::normalize(direction); + + // Define acceleration based on direction + acceleration = direction * 0.002f; // Adjust as needed + + // Add acceleration to velocity + velocity += acceleration; + + // Define minimum and maximum velocities based on distance + const float minVelocity = 0.01f; // Minimum velocity when close to the target + const float maxVelocityDistance = 1000.0f; // Distance at which max velocity is applied + const float maxVelocity = 5.0f; // Maximum velocity + + // Scale max velocity based on distance + float dynamicMaxVelocity = glm::clamp(distance / maxVelocityDistance * maxVelocity, minVelocity, maxVelocity); + + // Clamp the velocity to the range [-dynamicMaxVelocity, dynamicMaxVelocity] + float velocityLength = glm::length(velocity); + if (velocityLength > dynamicMaxVelocity) { + velocity = glm::normalize(velocity) * dynamicMaxVelocity; + } + + // Update position + glm::vec3 newPosition = currentPosition + velocity; + cam.setPosition(newPosition); + + // Optionally, log the details + std::cout << "velocity " << velocity << std::endl; + std::cout << "target " << targetPosition << std::endl; + std::cout << "new position " << cam.getPosition() << std::endl; +} + void TSNEMap::setTexture(std::string imagePath){ image.load("images/rte-archive-football/" + imagePath); } diff --git a/src/TSNEMap.h b/src/TSNEMap.h index dfbe63c..b036ef9 100644 --- a/src/TSNEMap.h +++ b/src/TSNEMap.h @@ -16,18 +16,25 @@ struct ImageObject { ofImage texture; }; +typedef struct { + std::string imagePath; + std::vector vec; + glm::vec2 position; +} ImageHM; + class TSNEMap{ public: void setup(); void draw(); - void update(); + void update(std::string imagePath); void setTexture(std::string imagePath); void updateCameraProjection(); void keyPressed(int key); void setupTSNE(std::string jsonPath); void setupNodes(); + void MoveCameraToPosition(glm::vec2 position); ofFbo fbo; vector planes; @@ -48,6 +55,14 @@ class TSNEMap{ bool normalise = true; bool runManually = false; + std::unordered_map imageHashmap; + vector imageMap; + + std::string lastImagePath; + + glm::vec3 velocity; + glm::vec3 acceleration; + TSNEMap(); }; diff --git a/src/ofApp.cpp b/src/ofApp.cpp index 093e943..a0e4f37 100644 --- a/src/ofApp.cpp +++ b/src/ofApp.cpp @@ -18,7 +18,7 @@ void ofApp::update(){ player.update(); std::string imagePath = player.getFrameName(); imageViewer.update(imagePath); - map.update(); + map.update(imagePath); } //--------------------------------------------------------------