|
|
@ -1,4 +1,5 @@ |
|
|
|
#include "Map.h" |
|
|
|
#include "algorithm" |
|
|
|
|
|
|
|
Map::Map(){ |
|
|
|
|
|
|
@ -6,6 +7,7 @@ Map::Map(){ |
|
|
|
|
|
|
|
void Map::Setup(){ |
|
|
|
ofDisableArbTex(); |
|
|
|
scale = 10000; |
|
|
|
isDebug = true; |
|
|
|
|
|
|
|
json_embeddings = ofLoadJson(jsonPath); |
|
|
@ -17,21 +19,107 @@ void Map::Setup(){ |
|
|
|
SetupTSNE(); |
|
|
|
} |
|
|
|
|
|
|
|
mapFbo.allocate(ofGetWindowWidth(), ofGetWindowHeight(), GL_RGBA); |
|
|
|
mapFbo.allocate(ofGetWindowWidth(), ofGetWindowHeight(), GL_RGB); |
|
|
|
|
|
|
|
fboImage.allocate(ofGetWindowWidth(), ofGetWindowHeight(), OF_IMAGE_COLOR); |
|
|
|
|
|
|
|
Setup3D(); |
|
|
|
|
|
|
|
SetupNodes(); |
|
|
|
} |
|
|
|
|
|
|
|
void Map::Update(){ |
|
|
|
|
|
|
|
time = ofGetElapsedTimef(); |
|
|
|
for(auto& n : nodes){ |
|
|
|
glm::vec2 offset = n.amplitude * sin(n.speed * time); |
|
|
|
n.offset = glm::vec3(offset.x, offset.y, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Map::Draw(){ |
|
|
|
|
|
|
|
mapFbo.begin(); |
|
|
|
|
|
|
|
cam.begin(); |
|
|
|
|
|
|
|
ofClear(0, 0, 0, 1); |
|
|
|
|
|
|
|
for (auto& n :nodes){ |
|
|
|
n.texture.getTexture().bind(); |
|
|
|
ofPushMatrix(); |
|
|
|
ofFill(); |
|
|
|
n.geom.setPosition(n.position + n.offset); |
|
|
|
n.geom.draw(); |
|
|
|
ofPopMatrix(); |
|
|
|
n.texture.getTexture().unbind(); |
|
|
|
} |
|
|
|
|
|
|
|
cam.end(); |
|
|
|
|
|
|
|
mapFbo.end(); |
|
|
|
|
|
|
|
mapFbo.readToPixels(fboPixels); |
|
|
|
fboImage.setFromPixels(fboPixels); |
|
|
|
|
|
|
|
//mapFbo.draw(0, 0);
|
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
Setup texture for each node |
|
|
|
*/ |
|
|
|
void Map::SetupNodes(){ |
|
|
|
std::cout << "Setting up nodes.." << std::endl; |
|
|
|
for (auto& node : nodes){ |
|
|
|
ofImage img; |
|
|
|
ofPlanePrimitive plane; |
|
|
|
|
|
|
|
img.load("data/" + node.image_path); |
|
|
|
int imageW = img.getWidth(); |
|
|
|
int imageH = img.getHeight(); |
|
|
|
int maxWidth = 100; |
|
|
|
int maxHeight = 100; |
|
|
|
float aspectRatio = (float)imageW / (float)imageH; |
|
|
|
|
|
|
|
// Determine plane dimensions based on aspect ratio and constraints
|
|
|
|
float planeW, planeH; |
|
|
|
if (aspectRatio > (float)maxWidth / maxHeight) { |
|
|
|
// Image is wider relative to the max constraints
|
|
|
|
planeW = maxWidth; |
|
|
|
planeH = maxWidth / aspectRatio; |
|
|
|
} else { |
|
|
|
// Image is taller relative to the max constraints
|
|
|
|
planeH = maxHeight; |
|
|
|
planeW = maxHeight * aspectRatio; |
|
|
|
} |
|
|
|
|
|
|
|
// Ensure that dimensions do not exceed constraints
|
|
|
|
if (planeH > maxHeight) { |
|
|
|
planeH = maxHeight; |
|
|
|
planeW = maxHeight * aspectRatio; |
|
|
|
} |
|
|
|
if (planeW > maxWidth) { |
|
|
|
planeW = maxWidth; |
|
|
|
planeH = maxWidth / aspectRatio; |
|
|
|
} |
|
|
|
|
|
|
|
plane.set(planeW, planeH); |
|
|
|
plane.setPosition(node.position); |
|
|
|
plane.setResolution(2, 2); |
|
|
|
plane.mapTexCoordsFromTexture(img.getTexture()); |
|
|
|
img.getTexture().setTextureWrap(GL_REPEAT, GL_REPEAT); |
|
|
|
plane.setScale(1); |
|
|
|
|
|
|
|
node.geom = plane; |
|
|
|
node.texture = img; |
|
|
|
node.speed = glm::vec2(ofRandom(0.1, 2), ofRandom(0.1, 2)); |
|
|
|
node.amplitude = glm::vec2(ofRandom(1, 5), ofRandom(1, 5)); |
|
|
|
node.phase = glm::vec2(ofRandom(0, TWO_PI), ofRandom(0, TWO_PI)); |
|
|
|
} |
|
|
|
std::cout << "Finished setting up nodes!" << std::endl; |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
Setup TSNE - reads JSON, converts to points, creates nodes & hashmap |
|
|
|
*/ |
|
|
|
void Map::SetupTSNE(){ |
|
|
|
for (const auto& entry: json_embeddings) { |
|
|
|
if (entry.contains("vector") && entry["vector"].is_array()) { |
|
|
@ -58,13 +146,47 @@ void Map::SetupTSNE(){ |
|
|
|
} |
|
|
|
|
|
|
|
std::cout << nodes.size() << std::endl; |
|
|
|
std::cout << embeddings.size() << std::endl; |
|
|
|
|
|
|
|
points = tsne.run(embeddings, dims, perplexity, theta, normalise, runManually); |
|
|
|
|
|
|
|
for (size_t i = 0; i < points.size(); i++){ |
|
|
|
const auto& vec = points[i]; |
|
|
|
auto& n = nodes[i]; |
|
|
|
n.position = glm::vec3(vec[0], vec[1], vec[2]); |
|
|
|
n.position = ( (glm::vec3(vec[0], vec[1], vec[2]) * scale) - (scale / 2) ); |
|
|
|
node_hash_map[n.image_path] = &n; |
|
|
|
} |
|
|
|
|
|
|
|
SortNodes(); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
Setup 3D environment |
|
|
|
*/ |
|
|
|
void Map::Setup3D(){ |
|
|
|
cam.setFov(20); |
|
|
|
cam.removeAllInteractions(); |
|
|
|
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY, OF_MOUSE_BUTTON_LEFT); |
|
|
|
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_MIDDLE); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
Query hashmap |
|
|
|
*/ |
|
|
|
void Map::SearchMap(){ |
|
|
|
std::string t = "dataset/20230601_webexclusi-irelandsey_cl11536538/segmented_images/000000000_0.png"; |
|
|
|
if(node_hash_map.find(t) != node_hash_map.end()){ |
|
|
|
Node* n = node_hash_map[t]; |
|
|
|
std::cout << n->foldername << std::endl; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
Sort nodes by z position, for draw calls (lowest -> highest) |
|
|
|
*/ |
|
|
|
void Map::SortNodes(){ |
|
|
|
std::cout << "Sorting Nodes.." << std::endl; |
|
|
|
std::sort(nodes.begin(), nodes.end(), [](const Node& a, const Node&b){ |
|
|
|
return a.position.z < b.position.z; |
|
|
|
}); |
|
|
|
std::cout << "Finished Sorting!" << std::endl; |
|
|
|
} |