|  |  | @ -32,6 +32,8 @@ void ofApp::setup(){ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     alpha_demo.allocate(portrait_pre_fbo_alpha.getWidth(), portrait_pre_fbo_alpha.getHeight(), OF_IMAGE_COLOR_ALPHA); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     text_display.allocate(ofGetWindowWidth(), map_h, GL_RGBA); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     /* black pi mapper bg */ | 
			
		
	
		
			
				
					|  |  |  |     mapper_black.allocate(300, 1080, GL_RGB); | 
			
		
	
		
			
				
					|  |  |  |     mapper_black.begin(); | 
			
		
	
	
		
			
				
					|  |  | @ -63,6 +65,9 @@ void ofApp::setup(){ | 
			
		
	
		
			
				
					|  |  |  |     p_depth.load("shaders/p_depth"); | 
			
		
	
		
			
				
					|  |  |  |     map_depth.load("shaders/map_depth"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     font.load("MaziusDisplay-Bold.otf", 180); | 
			
		
	
		
			
				
					|  |  |  |     ofLog() << font.getLineHeight(); | 
			
		
	
		
			
				
					|  |  |  |     | 
			
		
	
		
			
				
					|  |  |  |     ORTCHAR_T* modelPath = "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/apps/myApps/image-to-mesh/bin/data/models/depth_anything_v2_vits.onnx"; | 
			
		
	
		
			
				
					|  |  |  |     ORTCHAR_T* modelPath_Small = "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/apps/myApps/image-to-mesh/bin/data/models/depth_anything_v2_vitb.onnx"; | 
			
		
	
		
			
				
					|  |  |  |     ORTCHAR_T* modelPath_Yolo = "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/apps/myApps/image-to-mesh/bin/data/models/yolov5s-face.onnx"; | 
			
		
	
	
		
			
				
					|  |  | @ -119,8 +124,6 @@ void ofApp::setup(){ | 
			
		
	
		
			
				
					|  |  |  |     portrait_camera.setOrientation(current_cp.rotation); | 
			
		
	
		
			
				
					|  |  |  |     portrait_camera.setScale(current_cp.scale); | 
			
		
	
		
			
				
					|  |  |  |     updateCurrentCameraMode(); | 
			
		
	
		
			
				
					|  |  |  |     // portrait_camera.removeAllInteractions();
 | 
			
		
	
		
			
				
					|  |  |  |     // portrait_camera.disableMouseInput();
 | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     createNodes("data/json/sv_embeddings.json"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -140,13 +143,12 @@ void ofApp::setup(){ | 
			
		
	
		
			
				
					|  |  |  | //--------------------------------------------------------------
 | 
			
		
	
		
			
				
					|  |  |  | void ofApp::update(){ | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     float current_time = ofGetElapsedTimef(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     Node n = server->getChosenNode(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     // Check if node has changed
 | 
			
		
	
		
			
				
					|  |  |  |     if(n.tsne_position != last_chosen_node.tsne_position) { | 
			
		
	
		
			
				
					|  |  |  |     if(n.id != last_chosen_node.id) { | 
			
		
	
		
			
				
					|  |  |  |         portrait_needs_update = true; | 
			
		
	
		
			
				
					|  |  |  |         last_chosen_node = n; | 
			
		
	
		
			
				
					|  |  |  |         current_cp = cam_positions[ofRandom(cam_positions.size())]; | 
			
		
	
	
		
			
				
					|  |  | @ -201,21 +203,18 @@ void ofApp::update(){ | 
			
		
	
		
			
				
					|  |  |  |     mapper.update(); | 
			
		
	
		
			
				
					|  |  |  |     bullet.update(server->is_active, n, nn_nodes); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     // if(tsne_update_complete) {
 | 
			
		
	
		
			
				
					|  |  |  |     //     tsne_update_complete = false;  // Reset flag
 | 
			
		
	
		
			
				
					|  |  |  |     //     onTSNEUpdateComplete();  // Call your main thread function
 | 
			
		
	
		
			
				
					|  |  |  |     // }
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     // if(ofGetElapsedTimef() > tsne_start_time + TNSE_DURATION){
 | 
			
		
	
		
			
				
					|  |  |  |     //     tsne_iter_idx = (tsne_iter_idx + 1) % 3;
 | 
			
		
	
		
			
				
					|  |  |  |     //     updateTSNEPositions(nodes);
 | 
			
		
	
		
			
				
					|  |  |  |     // }
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     updateCurrentCameraMode(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if(bullet.getRandomWalkTime() > 60){ | 
			
		
	
		
			
				
					|  |  |  |         display_text = true; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | //--------------------------------------------------------------
 | 
			
		
	
		
			
				
					|  |  |  | void ofApp::draw(){ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     //drawText();
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     ofPushStyle(); | 
			
		
	
		
			
				
					|  |  |  |     map_fbo_alpha.begin(); | 
			
		
	
		
			
				
					|  |  |  |     ofClear(0); | 
			
		
	
	
		
			
				
					|  |  | @ -267,7 +266,8 @@ void ofApp::draw(){ | 
			
		
	
		
			
				
					|  |  |  |     shaders.setUniform1f("time", ofGetElapsedTimef()); | 
			
		
	
		
			
				
					|  |  |  |     shaders.setUniform1i("frame", ofGetFrameNum()); | 
			
		
	
		
			
				
					|  |  |  |     map_fbo_post.draw(0, 0); | 
			
		
	
		
			
				
					|  |  |  |     map_fbo_alpha.draw(0,0); | 
			
		
	
		
			
				
					|  |  |  |     map_fbo_alpha.draw(0, 0); | 
			
		
	
		
			
				
					|  |  |  |     //text_display.draw(0, 0);
 | 
			
		
	
		
			
				
					|  |  |  |     shaders.end(); | 
			
		
	
		
			
				
					|  |  |  |     comp_fbo.end(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -277,6 +277,7 @@ void ofApp::draw(){ | 
			
		
	
		
			
				
					|  |  |  |     comp_fbo.draw(0, 0); | 
			
		
	
		
			
				
					|  |  |  |     mapper.draw(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if(bullet.print_debug) | 
			
		
	
		
			
				
					|  |  |  |         server->print(); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
	
		
			
				
					|  |  | @ -549,12 +550,12 @@ void ofApp::createNodes(std::string json_path){ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     /* setup nodes */ | 
			
		
	
		
			
				
					|  |  |  |     bool addNode = true;  // Toggle flag to track every second node
 | 
			
		
	
		
			
				
					|  |  |  |     int _id = 0; | 
			
		
	
		
			
				
					|  |  |  |     int id = 0; | 
			
		
	
		
			
				
					|  |  |  |     for(const auto& j : json) { | 
			
		
	
		
			
				
					|  |  |  |         if(j.contains("vector") && j["vector"].is_array() && j["error"] == 0) { | 
			
		
	
		
			
				
					|  |  |  |             if(addNode) {  // Only process when flag is true
 | 
			
		
	
		
			
				
					|  |  |  |                 Node n; | 
			
		
	
		
			
				
					|  |  |  |                 n.id = _id; | 
			
		
	
		
			
				
					|  |  |  |                 n.id = id; | 
			
		
	
		
			
				
					|  |  |  |                 n.img.load(j["image"]); | 
			
		
	
		
			
				
					|  |  |  |                 n.img_path = (j["image"]); | 
			
		
	
		
			
				
					|  |  |  |                 n.tex = n.img.getTexture(); | 
			
		
	
	
		
			
				
					|  |  | @ -571,7 +572,7 @@ void ofApp::createNodes(std::string json_path){ | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 n.raw_embedding = t_embedding; | 
			
		
	
		
			
				
					|  |  |  |                 nodes.push_back(n); | 
			
		
	
		
			
				
					|  |  |  |                 _id++; | 
			
		
	
		
			
				
					|  |  |  |                 id++; | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             addNode = !addNode;  // Toggle the flag after each valid node
 | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
	
		
			
				
					|  |  | @ -601,40 +602,13 @@ void ofApp::createNodes(std::string json_path){ | 
			
		
	
		
			
				
					|  |  |  |         point_iterations.push_back(tsne_points); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     for(size_t i = 0; i < tsne_points.size(); i++){ | 
			
		
	
		
			
				
					|  |  |  |         const auto& vec = point_iterations[1][i]; | 
			
		
	
		
			
				
					|  |  |  |         auto& n = nodes[i]; | 
			
		
	
		
			
				
					|  |  |  |         n.tsne_position = (glm::vec3(((vec[0] * 2) - 1) * tsne_scale, ((vec[1] * 2) - 1) * tsne_scale, -5.0f)); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | void ofApp::updateTSNEPositions(vector<Node>& _nodes){ | 
			
		
	
		
			
				
					|  |  |  |     if(tsne_updating) { | 
			
		
	
		
			
				
					|  |  |  |         ofLog() << "TSNE update already in progress"; | 
			
		
	
		
			
				
					|  |  |  |         return; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     tsne_updating = true; | 
			
		
	
		
			
				
					|  |  |  |     tsne_update_complete = false;  // Reset flag
 | 
			
		
	
		
			
				
					|  |  |  |     tsne_thread = std::thread(&ofApp::updateTSNEPositionsThreaded, this, std::ref(_nodes)); | 
			
		
	
		
			
				
					|  |  |  |     tsne_thread.detach(); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | void ofApp::updateTSNEPositionsThreaded(vector<Node>& _nodes){ | 
			
		
	
		
			
				
					|  |  |  |     ofLog() << "Starting TSNE update in thread"; | 
			
		
	
		
			
				
					|  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |         std::lock_guard<std::mutex> lock(nodes_mutex); | 
			
		
	
		
			
				
					|  |  |  |         for(size_t i = 0; i < point_iterations[tsne_iter_idx].size(); i++) { | 
			
		
	
		
			
				
					|  |  |  |             const auto& vec = point_iterations[tsne_iter_idx][i]; | 
			
		
	
		
			
				
					|  |  |  |             nodes[i].tsne_position = glm::vec3( | 
			
		
	
		
			
				
					|  |  |  |                 ((vec[0] * 2) - 1) * tsne_scale, | 
			
		
	
		
			
				
					|  |  |  |                 ((vec[1] * 2) - 1) * tsne_scale, | 
			
		
	
		
			
				
					|  |  |  |                 -5.0f | 
			
		
	
		
			
				
					|  |  |  |             ); | 
			
		
	
		
			
				
					|  |  |  |     for(size_t x = 0; x < point_iterations.size(); x++){ | 
			
		
	
		
			
				
					|  |  |  |         for(size_t y = 0; y < tsne_points.size(); y++){ | 
			
		
	
		
			
				
					|  |  |  |             const auto& vec = point_iterations[x][y]; | 
			
		
	
		
			
				
					|  |  |  |             auto& n = nodes[y]; | 
			
		
	
		
			
				
					|  |  |  |             n.tsne_list[x] = (glm::vec3(((vec[0] * 2) - 1) * tsne_scale, ((vec[1] * 2) - 1) * tsne_scale, -5.0f)); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     tsne_updating = false; | 
			
		
	
		
			
				
					|  |  |  |     tsne_update_complete = true;  // Set completion flag
 | 
			
		
	
		
			
				
					|  |  |  |     ofLog() << "TSNE update complete"; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | std::vector<std::vector<double>> ofApp::createDoubleVectorFromNodes(const std::vector<Node>& nodes) { | 
			
		
	
	
		
			
				
					|  |  | @ -732,15 +706,6 @@ void ofApp::keyPressed(int key) { | 
			
		
	
		
			
				
					|  |  |  |     mapper.keyPressed(key); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | // Your main thread function:
 | 
			
		
	
		
			
				
					|  |  |  | void ofApp::onTSNEUpdateComplete() { | 
			
		
	
		
			
				
					|  |  |  |     // Do whatever you need to do after TSNE update
 | 
			
		
	
		
			
				
					|  |  |  |     // This will run on the main thread
 | 
			
		
	
		
			
				
					|  |  |  |     bullet.updateTSNEPosition(nodes); | 
			
		
	
		
			
				
					|  |  |  |     tsne_start_time = ofGetElapsedTimef(); | 
			
		
	
		
			
				
					|  |  |  |     ofLog() << "Handling TSNE update completion on main thread"; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | void ofApp::keyReleased(int key){ | 
			
		
	
		
			
				
					|  |  |  |     mapper.keyReleased(key); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
	
		
			
				
					|  |  | @ -835,3 +800,76 @@ ofMesh ofApp::createCustomPlane(float width, float height, int numX, int numY) { | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     return mesh; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | void ofApp::drawText(){ | 
			
		
	
		
			
				
					|  |  |  |    text_display.begin(); | 
			
		
	
		
			
				
					|  |  |  |     ofPushStyle(); | 
			
		
	
		
			
				
					|  |  |  |     ofClear(0, 0, 0, 0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |    float random_walk_time = bullet.getRandomWalkTime(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     if (random_walk_time > 10) { | 
			
		
	
		
			
				
					|  |  |  |         // Fade in and oscillate
 | 
			
		
	
		
			
				
					|  |  |  |         fade_time += ofGetLastFrameTime(); | 
			
		
	
		
			
				
					|  |  |  |         if (!is_oscillating) { | 
			
		
	
		
			
				
					|  |  |  |             // Linear fade in
 | 
			
		
	
		
			
				
					|  |  |  |             t_alpha = ofClamp(fade_time, 0, 1); | 
			
		
	
		
			
				
					|  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |             if (fade_time >= 1) { | 
			
		
	
		
			
				
					|  |  |  |                 is_oscillating = true; | 
			
		
	
		
			
				
					|  |  |  |                 oscillate_time = 0; | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |             // Oscillating fade
 | 
			
		
	
		
			
				
					|  |  |  |             oscillate_time += ofGetLastFrameTime(); | 
			
		
	
		
			
				
					|  |  |  |             t_alpha = 1 - (glm::sin(oscillate_time) + 1) / 2; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |         // Fade out
 | 
			
		
	
		
			
				
					|  |  |  |         fade_time -= ofGetLastFrameTime(); | 
			
		
	
		
			
				
					|  |  |  |         t_alpha = ofClamp(fade_time, 0, 1); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         if (fade_time <= 0) { | 
			
		
	
		
			
				
					|  |  |  |             is_oscillating = false; | 
			
		
	
		
			
				
					|  |  |  |             is_fading_in = true; | 
			
		
	
		
			
				
					|  |  |  |             fade_time = 0; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     ofSetColor(ofColor::black, t_alpha * 255); | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     vector<std::string> sentence{ | 
			
		
	
		
			
				
					|  |  |  |         "HOW ARE", | 
			
		
	
		
			
				
					|  |  |  |         "YOU", | 
			
		
	
		
			
				
					|  |  |  |         "FEELING?" | 
			
		
	
		
			
				
					|  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     // Calculate total text height
 | 
			
		
	
		
			
				
					|  |  |  |     float line_height = font.getLineHeight(); | 
			
		
	
		
			
				
					|  |  |  |     int num_lines = sentence.size(); | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     // Calculate vertical center of the screen
 | 
			
		
	
		
			
				
					|  |  |  |     float screen_center = text_display.getHeight() / 2; | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     // Calculate total text block height
 | 
			
		
	
		
			
				
					|  |  |  |     float total_text_height = line_height * num_lines; | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     // Add ascender height to adjust baseline
 | 
			
		
	
		
			
				
					|  |  |  |     float ascender_height = font.getAscenderHeight(); | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     // Starting Y position to center the text block
 | 
			
		
	
		
			
				
					|  |  |  |     float start_y = screen_center - (total_text_height / 2) + ascender_height; | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     for(size_t idx = 0; idx < sentence.size(); ++idx){ | 
			
		
	
		
			
				
					|  |  |  |         const auto& t = sentence[idx]; | 
			
		
	
		
			
				
					|  |  |  |         float text_width = font.stringWidth(t); | 
			
		
	
		
			
				
					|  |  |  |         float text_x = text_display.getWidth()/2 - text_width/2; | 
			
		
	
		
			
				
					|  |  |  |         float text_y = start_y + (idx * line_height); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         font.drawString(t, text_x, text_y); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     ofPopStyle(); | 
			
		
	
		
			
				
					|  |  |  |     text_display.end(); | 
			
		
	
		
			
				
					|  |  |  | } |