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