Initial commit: Final state of the master project
This commit is contained in:
71
Research/core/Util/TransferFunction.h
Normal file
71
Research/core/Util/TransferFunction.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
#include "../Defines.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "../MathHelper.h"
|
||||
|
||||
template<typename T>
|
||||
class TransferFunction
|
||||
{
|
||||
public:
|
||||
struct Node
|
||||
{
|
||||
unsigned32 value;
|
||||
float opacity;
|
||||
T material;
|
||||
|
||||
Node(unsigned32 value, float opacity, T mat) : value(value), opacity(opacity), material(mat) {}
|
||||
Node(unsigned32 value) : value(value), opacity(0), material(T()) {}
|
||||
};
|
||||
|
||||
struct NodeCompare { bool operator()(const Node& a, const Node& b) { return a.value < b.value; } };
|
||||
|
||||
TransferFunction()
|
||||
{
|
||||
}
|
||||
|
||||
~TransferFunction() { mFunction.clear(); }
|
||||
|
||||
void AddNode(unsigned32 value, float opacity, T mat)
|
||||
{
|
||||
Node node(value, opacity, mat);
|
||||
auto pos = LowerBound(node);
|
||||
if (pos != mFunction.end() && pos->value == value)
|
||||
mFunction[pos - mFunction.begin()] = node;
|
||||
else
|
||||
mFunction.insert(pos, node);
|
||||
}
|
||||
|
||||
template<typename Interpolator>
|
||||
void Evaluate(unsigned32 value, float& outOpacity, T& outMat, Interpolator interpolator) const
|
||||
{
|
||||
Node node(value);
|
||||
// Set default values
|
||||
outOpacity = 1.f;
|
||||
outMat = T();
|
||||
// Find the current node
|
||||
auto pos = LowerBound(node);
|
||||
if (pos == mFunction.end()) return;
|
||||
|
||||
Node after = *pos;
|
||||
if (pos == mFunction.begin())
|
||||
{
|
||||
outOpacity = after.opacity;
|
||||
outMat = after.material;
|
||||
return;
|
||||
}
|
||||
pos--;
|
||||
Node before = *pos;
|
||||
float t = float(value - before.value) / float(after.value - before.value);
|
||||
outMat = interpolator(before.material, after.material, t);
|
||||
outOpacity = MathHelper::lerp(t, before.opacity, after.opacity);
|
||||
}
|
||||
private:
|
||||
typename std::vector<Node>::const_iterator LowerBound(const Node& node) const
|
||||
{
|
||||
return std::lower_bound(mFunction.begin(), mFunction.end(), node, NodeCompare());
|
||||
}
|
||||
|
||||
std::vector<Node> mFunction;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user