@@ -3,13 +3,13 @@
|
||||
|
||||
#include "FlatLayerVisualisation.hpp"
|
||||
#include "Range.hpp"
|
||||
#include "RenderingState.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace fmri;
|
||||
|
||||
static inline void computeColor(float intensity, float limit, float *destination)
|
||||
{
|
||||
const float saturation = min(-log(abs(intensity) / limit) / 10.0f, 1.0f);
|
||||
const float saturation = std::min(-std::log(std::abs(intensity) / limit) / 10.0f, 1.0f);
|
||||
if (intensity > 0) {
|
||||
destination[0] = saturation;
|
||||
destination[1] = saturation;
|
||||
@@ -24,27 +24,26 @@ static inline void computeColor(float intensity, float limit, float *destination
|
||||
FlatLayerVisualisation::FlatLayerVisualisation(const LayerData &layer, Ordering ordering) :
|
||||
LayerVisualisation(layer.numEntries()),
|
||||
ordering(ordering),
|
||||
faceCount(layer.numEntries() * NODE_FACES.size() / 3),
|
||||
vertexBuffer(new float[faceCount * 3]),
|
||||
colorBuffer(new float[faceCount * 3]),
|
||||
indexBuffer(new int[faceCount * 3])
|
||||
vertexBuffer(layer.numEntries() * NODE_FACES.size()),
|
||||
colorBuffer(layer.numEntries() * NODE_FACES.size()),
|
||||
indexBuffer(layer.numEntries() * NODE_FACES.size())
|
||||
{
|
||||
auto &shape = layer.shape();
|
||||
CHECK_EQ(shape.size(), 2) << "layer should be flat!" << endl;
|
||||
CHECK_EQ(shape[0], 1) << "Only single images supported." << endl;
|
||||
CHECK_EQ(shape.size(), 2) << "layer should be flat!\n";
|
||||
CHECK_EQ(shape[0], 1) << "Only single images supported.\n";
|
||||
|
||||
initializeNodePositions();
|
||||
initializeNodePositions(layer.numEntries());
|
||||
|
||||
const auto limit = (int) layer.numEntries();
|
||||
auto data = layer.data();
|
||||
const auto
|
||||
[minElem, maxElem] = minmax_element(data, data + limit);
|
||||
[minElem, maxElem] = std::minmax_element(data, data + limit);
|
||||
|
||||
auto scalingMax = max(abs(*minElem), abs(*maxElem));
|
||||
auto scalingMax = std::max(abs(*minElem), abs(*maxElem));
|
||||
|
||||
int v = 0;
|
||||
for (int i : Range(limit)) {
|
||||
setVertexPositions(i, vertexBuffer.get() + NODE_FACES.size() * i);
|
||||
setVertexPositions(i, vertexBuffer.data() + NODE_FACES.size() * i);
|
||||
const auto vertexBase = static_cast<int>(i * NODE_FACES.size() / 3);
|
||||
|
||||
// Define the colors for the vertices
|
||||
@@ -57,7 +56,13 @@ FlatLayerVisualisation::FlatLayerVisualisation(const LayerData &layer, Ordering
|
||||
indexBuffer[v++] = vertexBase + faceNode;
|
||||
}
|
||||
}
|
||||
assert(v == (int) faceCount * 3);
|
||||
|
||||
// Compute which nodes are active, add those to the active indices
|
||||
for (auto i : Range(limit)) {
|
||||
if (abs(data[i]) > EPSILON) {
|
||||
std::copy_n(&indexBuffer[NODE_FACES.size() * i], NODE_FACES.size(), std::back_inserter(activeIndexBuffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FlatLayerVisualisation::render()
|
||||
@@ -65,15 +70,17 @@ void FlatLayerVisualisation::render()
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, vertexBuffer.get());
|
||||
glColorPointer(3, GL_FLOAT, 0, colorBuffer.get());
|
||||
glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_INT, indexBuffer.get());
|
||||
const auto& indices = RenderingState::instance().renderActivatedOnly() ? activeIndexBuffer : indexBuffer;
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, vertexBuffer.data());
|
||||
glColorPointer(3, GL_FLOAT, 0, colorBuffer.data());
|
||||
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, indices.data());
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
// Now draw wireframe
|
||||
glColor4f(0, 0, 0, 1);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_INT, indexBuffer.get());
|
||||
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, indices.data());
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
|
||||
@@ -87,15 +94,15 @@ void FlatLayerVisualisation::setVertexPositions(const int vertexNo, float *desti
|
||||
}
|
||||
}
|
||||
|
||||
void FlatLayerVisualisation::initializeNodePositions()
|
||||
void FlatLayerVisualisation::initializeNodePositions(std::size_t entries)
|
||||
{
|
||||
switch (ordering) {
|
||||
case Ordering::LINE:
|
||||
initNodePositions<Ordering::LINE>(faceCount / 4, 2);
|
||||
initNodePositions<Ordering::LINE>(entries, 2);
|
||||
break;
|
||||
|
||||
case Ordering::SQUARE:
|
||||
initNodePositions<Ordering::SQUARE>(faceCount / 4, 2);
|
||||
initNodePositions<Ordering::SQUARE>(entries, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@ namespace fmri
|
||||
|
||||
private:
|
||||
Ordering ordering;
|
||||
std::size_t faceCount;
|
||||
std::unique_ptr<float[]> vertexBuffer;
|
||||
std::unique_ptr<float[]> colorBuffer;
|
||||
std::unique_ptr<int[]> indexBuffer;
|
||||
std::vector<float> vertexBuffer;
|
||||
std::vector<float> colorBuffer;
|
||||
std::vector<int> indexBuffer;
|
||||
std::vector<int> activeIndexBuffer;
|
||||
|
||||
static constexpr const std::array<float, 12> NODE_SHAPE = {
|
||||
-0.5f, 0, 0.5f,
|
||||
@@ -37,6 +37,6 @@ namespace fmri
|
||||
void setVertexPositions(int vertexNo, float *destination);
|
||||
|
||||
// Various functions defining the way the nodes will be aligned.
|
||||
void initializeNodePositions();
|
||||
void initializeNodePositions(std::size_t entries);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -91,7 +91,11 @@ void RenderingState::handleKey(unsigned char x)
|
||||
exit(0);
|
||||
|
||||
case 'h':
|
||||
RenderingState::instance().reset();
|
||||
reset();
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
toggle(options.activatedOnly);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -249,6 +253,7 @@ void RenderingState::renderOverlayText() const
|
||||
"F2: toggle debug info\n"
|
||||
"l: toggle layers visible\n"
|
||||
"i: toggle interactions visible\n"
|
||||
"o: toggle activated nodes only\n"
|
||||
"q: quit\n";
|
||||
}
|
||||
|
||||
@@ -302,3 +307,8 @@ void RenderingState::handleSpecialKey(int key)
|
||||
LOG(INFO) << "Received keystroke " << key;
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderingState::renderActivatedOnly() const
|
||||
{
|
||||
return options.activatedOnly;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,10 @@ namespace fmri
|
||||
void render(float time) const;
|
||||
|
||||
void loadSimulationData(const std::map<string, LayerInfo> &info, std::vector<std::vector<LayerData>> &&data);
|
||||
/**
|
||||
* @return Whether the network should only render activated nodes, rather than all of them.
|
||||
*/
|
||||
bool renderActivatedOnly() const;
|
||||
|
||||
static RenderingState& instance();
|
||||
|
||||
@@ -48,6 +52,7 @@ namespace fmri
|
||||
bool showHelp = true;
|
||||
bool renderLayers = true;
|
||||
bool renderInteractions = true;
|
||||
bool activatedOnly = false;
|
||||
} options;
|
||||
std::array<float, 3> pos;
|
||||
std::array<float, 2> angle;
|
||||
|
||||
Reference in New Issue
Block a user