Commit 293d43dd authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Moved invalidation level from AbstractProperty to AbstractProcessor:

To now, each property hat an _invalidationLevel field that was evaluated by processors when the property had changed in order to determine what has to be done. However, since properties could also be owned by other classes, this design was semantically misleading.
Therefore, it was removed with this commit and replaced by the invalidation map of each processor. Now, this per-processor mapping of property -> invalidation level is managed by the processor itself. Furthermore, the invalidation level is no longer setup during property creation but during AbstractProcessor::addProperty(), which also makes much more sense.

ATTENTION: Due to these intrusive API changes, the code of all processors and other classes handling properties needs to be changed. As a reminder, the implementation of addProperty() also now takes a reference instead of a pointer, so that old code does no longer compile.

refs #542
parent 94a730da
......@@ -49,11 +49,11 @@ namespace campvis {
, p_kernelSize("KernelSize", "Kernel Size", 3, 3, 15)
, p_sigma("Sigma", "Sigma", 1.f, .1f, 10.f, 0.1f)
{
addProperty(&p_sourceImageID);
addProperty(&p_targetImageID);
addProperty(&p_filterMode);
addProperty(&p_kernelSize);
addProperty(&p_sigma);
addProperty(p_sourceImageID);
addProperty(p_targetImageID);
addProperty(p_filterMode);
addProperty(p_kernelSize);
addProperty(p_sigma);
}
ImageFilter::~ImageFilter() {
......
......@@ -144,10 +144,10 @@ namespace campvis {
, p_outputFL("OutputFL", "FL Output Volume", "fl", DataNameProperty::WRITE)
, p_outputFH("OutputFH", "FH Output Volume", "fh", DataNameProperty::WRITE)
{
addProperty(&p_intensitiesId);
addProperty(&p_gradientsId);
addProperty(&p_outputFL);
addProperty(&p_outputFH);
addProperty(p_intensitiesId);
addProperty(p_gradientsId);
addProperty(p_outputFL);
addProperty(p_outputFH);
}
LHHistogram::~LHHistogram() {
......
......@@ -173,18 +173,18 @@ namespace campvis {
, p_lengths("PolarLengths", "Polar Lengths", tgt::vec2(0.f, 100.f), tgt::vec2(0.f), tgt::vec2(1000.f), tgt::vec2(0.1f))
{
addProperty(&p_sourceImageID);
addProperty(&p_targetImageID);
addProperty(&p_alpha);
addProperty(&p_beta);
addProperty(&p_gamma);
addProperty(&p_normalizeValues);
addProperty(&p_solver);
addProperty(&p_numSteps);
addProperty(&p_curvilinear);
addProperty(&p_origin);
addProperty(&p_angles);
addProperty(&p_lengths);
addProperty(p_sourceImageID);
addProperty(p_targetImageID);
addProperty(p_alpha);
addProperty(p_beta);
addProperty(p_gamma);
addProperty(p_normalizeValues);
addProperty(p_solver);
addProperty(p_numSteps);
addProperty(p_curvilinear);
addProperty(p_origin);
addProperty(p_angles);
addProperty(p_lengths);
}
ConfidenceMapGenerator::~ConfidenceMapGenerator() {
......
......@@ -46,8 +46,8 @@ namespace campvis {
: AutoEvaluationPipeline(dc)
, p_optimizer("Optimizer", "Optimizer", optimizers, 3)
, p_liveUpdate("LiveUpdate", "Live Update of Difference Image", false)
, p_performOptimization("PerformOptimization", "Perform Optimization", AbstractProcessor::INVALID_RESULT)
, p_forceStop("Force Stop", "Force Stop", AbstractProcessor::VALID)
, p_performOptimization("PerformOptimization", "Perform Optimization")
, p_forceStop("Force Stop", "Force Stop")
, p_translationStepSize("TranslationStepSize", "Initial Step Size Translation", 8.f, .1f, 100.f)
, p_rotationStepSize("RotationStepSize", "Initial Step Size Rotation", .5f, .01f, tgt::PIf)
, _referenceReader()
......@@ -61,12 +61,12 @@ namespace campvis {
addProcessor(&_sm);
addProcessor(&_ve);
addProperty(&p_optimizer);
addProperty(&p_liveUpdate);
addProperty(&p_performOptimization);
addProperty(&p_forceStop);
addProperty(&p_translationStepSize);
addProperty(&p_rotationStepSize);
addProperty(p_optimizer);
addProperty(p_liveUpdate);
addProperty(p_performOptimization);
addProperty(p_forceStop);
addProperty(p_translationStepSize);
addProperty(p_rotationStepSize);
p_performOptimization.s_clicked.connect(this, &NloptRegistration::onPerformOptimizationClicked);
p_forceStop.s_clicked.connect(this, &NloptRegistration::forceStop);
......
......@@ -52,8 +52,8 @@ namespace campvis {
SimilarityMeasure::SimilarityMeasure()
: VisualizationProcessor(0)
, p_referenceId("ReferenceId", "Reference Image", "", DataNameProperty::READ, AbstractProcessor::INVALID_PROPERTIES)
, p_movingId("MovingId", "Moving Image", "", DataNameProperty::READ, AbstractProcessor::VALID)
, p_referenceId("ReferenceId", "Reference Image", "", DataNameProperty::READ)
, p_movingId("MovingId", "Moving Image", "", DataNameProperty::READ)
, p_clipX("clipX", "X Axis Clip Coordinates", tgt::ivec2(0), tgt::ivec2(0), tgt::ivec2(0))
, p_clipY("clipY", "Y Axis Clip Coordinates", tgt::ivec2(0), tgt::ivec2(0), tgt::ivec2(0))
, p_clipZ("clipZ", "Z Axis Clip Coordinates", tgt::ivec2(0), tgt::ivec2(0), tgt::ivec2(0))
......@@ -62,29 +62,29 @@ namespace campvis {
, p_rotation("Rotation", "Moving Image Rotation", tgt::vec3(0.f), tgt::vec3(-tgt::PIf), tgt::vec3(tgt::PIf), tgt::vec3(.01f), tgt::vec3(7.f))
, p_metric("Metric", "Similarity Metric", metrics, 5)
, p_computeSimilarity("ComputeSimilarity", "Compute Similarity")
, p_differenceImageId("DifferenceImageId", "Difference Image", "difference", DataNameProperty::WRITE, AbstractProcessor::VALID)
, p_computeDifferenceImage("ComputeDifferenceImage", "Compute Difference Image", AbstractProcessor::INVALID_RESULT | COMPUTE_DIFFERENCE_IMAGE)
, p_viewportSize("ViewportSize", "Viewport Size", tgt::ivec2(1), tgt::ivec2(1), tgt::ivec2(1000), tgt::ivec2(1), AbstractProcessor::VALID)
, p_differenceImageId("DifferenceImageId", "Difference Image", "difference", DataNameProperty::WRITE)
, p_computeDifferenceImage("ComputeDifferenceImage", "Compute Difference Image")
, p_viewportSize("ViewportSize", "Viewport Size", tgt::ivec2(1), tgt::ivec2(1), tgt::ivec2(1000), tgt::ivec2(1))
, _sadssdCostFunctionShader(0)
, _nccsnrCostFunctionShader(0)
, _differenceShader(0)
, _glr(0)
{
addProperty(&p_referenceId);
addProperty(&p_movingId);
addProperty(p_referenceId, INVALID_RESULT | INVALID_PROPERTIES);
addProperty(p_movingId, VALID);
addProperty(&p_clipX);
addProperty(&p_clipY);
addProperty(&p_clipZ);
addProperty(&p_applyMask);
addProperty(p_clipX);
addProperty(p_clipY);
addProperty(p_clipZ);
addProperty(p_applyMask);
addProperty(&p_translation);
addProperty(&p_rotation);
addProperty(&p_metric);
addProperty(&p_computeSimilarity);
addProperty(p_translation);
addProperty(p_rotation);
addProperty(p_metric);
addProperty(p_computeSimilarity);
addProperty(&p_differenceImageId);
addProperty(&p_computeDifferenceImage);
addProperty(p_differenceImageId, VALID);
addProperty(p_computeDifferenceImage, INVALID_RESULT | COMPUTE_DIFFERENCE_IMAGE);
_viewportSizeProperty = &p_viewportSize;
......@@ -316,7 +316,7 @@ namespace campvis {
glViewport(0, 0, static_cast<GLsizei>(viewportSize.x), static_cast<GLsizei>(viewportSize.y));
// render quad to compute difference measure by shader
for (tgt::svec3::ElemType z = 0; z < size.z; ++z) {
for (int z = 0; z < static_cast<int>(size.z); ++z) {
float texZ = static_cast<float>(z)/static_cast<float>(size.z) + .5f/static_cast<float>(size.z);
_differenceShader->setUniform("_zTex", texZ);
_fbo->attachTexture(differenceImage, GL_COLOR_ATTACHMENT0, 0, z);
......
......@@ -43,8 +43,8 @@ namespace campvis {
, _trackballEH(0)
{
addProperty(&p_camera);
addProperty(&p_sliceNumber);
addProperty(p_camera);
addProperty(p_sliceNumber);
_trackballEH = new TrackballNavigationEventListener(&p_camera, &_canvasSize);
addEventListenerToBack(_trackballEH);
......@@ -82,7 +82,7 @@ namespace campvis {
_glyphRenderer.p_renderOutput.addSharedProperty(&_rtc.p_firstImageId);
Geometry1DTransferFunction* tf = new Geometry1DTransferFunction(128, tgt::vec2(0.f, 1.f));
tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(255, 255, 255, 255)));
tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 255), tgt::col4(255, 255, 255, 255)));
_sliceRenderer.p_transferFunction.replaceTF(tf);
_sliceRenderer.p_targetImageID.setValue("slice");
_sliceRenderer.p_targetImageID.addSharedProperty(&_rtc.p_secondImageId);
......
......@@ -71,21 +71,21 @@ namespace campvis {
TensorAnalyzer::TensorAnalyzer()
: AbstractProcessor()
, p_inputImage("InputImage", "Input Tensor Image", "tensors", DataNameProperty::READ, AbstractProcessor::INVALID_RESULT | EIGENSYSTEM_INVALID)
, p_inputImage("InputImage", "Input Tensor Image", "tensors", DataNameProperty::READ)
, p_evalsImage("EvalsImage", "Output Eigenvalues Image", "TensorAnalyzer.eigenvalues", DataNameProperty::WRITE)
, p_evecsImage("EvecsImage", "Output Eigenvectors Image", "TensorAnalyzer.eigenvectors", DataNameProperty::WRITE)
, p_degeneratedHandling("DegeneratedHandling", "Handling of Degenerated Tensors", handlingModes, 4)
, p_maskMixedTensors("MaskMixedTensors", "Mask Mixed Tensors", true)
, p_addOutputButton("AddOutputButton", "Add Output", AbstractProcessor::VALID)
, p_addOutputButton("AddOutputButton", "Add Output")
, _eigenvalues(0)
, _eigenvectors(0)
{
addProperty(&p_inputImage);
addProperty(&p_evalsImage);
addProperty(&p_evecsImage);
addProperty(&p_degeneratedHandling);
addProperty(&p_maskMixedTensors);
addProperty(&p_addOutputButton);
addProperty(p_inputImage, INVALID_RESULT | EIGENSYSTEM_INVALID);
addProperty(p_evalsImage);
addProperty(p_evecsImage);
addProperty(p_degeneratedHandling);
addProperty(p_maskMixedTensors);
addProperty(p_addOutputButton, VALID);
addOutput();
p_addOutputButton.s_clicked.connect(this, &TensorAnalyzer::addOutput);
......@@ -471,8 +471,8 @@ namespace campvis {
void TensorAnalyzer::addOutput() {
OutputPropertyPair* opp = new OutputPropertyPair(p_outputProperties.size() + 1);
p_outputProperties.push_back(opp);
addProperty(&opp->_imageId);
addProperty(&opp->_imageType);
addProperty(opp->_imageId);
addProperty(opp->_imageType);
}
void TensorAnalyzer::deinit() {
......
......@@ -52,27 +52,27 @@ namespace campvis {
TensorGlyphRenderer::TensorGlyphRenderer(IVec2Property* viewportSizeProp)
: VisualizationProcessor(viewportSizeProp)
, p_inputEigenvalues("InputEigenvalues", "Input Eigenvalues Image", "eigenvalues", DataNameProperty::READ, INVALID_RESULT | INVALID_PROPERTIES)
, p_inputEigenvectors("InputEigenvectors", "Input Eigenvectors Image", "eigenvectors", DataNameProperty::READ, INVALID_RESULT | INVALID_PROPERTIES)
, p_inputEigenvalues("InputEigenvalues", "Input Eigenvalues Image", "eigenvalues", DataNameProperty::READ)
, p_inputEigenvectors("InputEigenvectors", "Input Eigenvectors Image", "eigenvectors", DataNameProperty::READ)
, p_renderOutput("RenderOutput", "Output Image", "TensorGlyphRenderer.output", DataNameProperty::WRITE)
, p_glyphType("GlyphType", "Glyph Type to Render", glyphTypes, 3)
, p_glyphSize("GlyphSize", "Glyph Size", 1.f, .1f, 5.f)
, p_camera("Camera", "Camera", tgt::Camera())
, p_sliceOrientation("SliceOrientation", "Slice Orientation", sliceOrientationOptions, 3, INVALID_RESULT | INVALID_PROPERTIES)
, p_sliceOrientation("SliceOrientation", "Slice Orientation", sliceOrientationOptions, 3)
, p_sliceNumber("SliceNumber", "Slice Number", 0, 0, 0)
, _ellipsoidGeometry(0)
, _cubeGeometry(0)
{
addDecorator(new ProcessorDecoratorShading());
addProperty(&p_inputEigenvalues);
addProperty(&p_inputEigenvectors);
addProperty(&p_renderOutput);
addProperty(&p_glyphType);
addProperty(&p_glyphSize);
addProperty(&p_camera);
addProperty(&p_sliceOrientation);
addProperty(&p_sliceNumber);
addProperty(p_inputEigenvalues, INVALID_RESULT | INVALID_PROPERTIES);
addProperty(p_inputEigenvectors, INVALID_RESULT | INVALID_PROPERTIES);
addProperty(p_renderOutput);
addProperty(p_glyphType);
addProperty(p_glyphSize);
addProperty(p_camera);
addProperty(p_sliceOrientation, INVALID_RESULT | INVALID_PROPERTIES);
addProperty(p_sliceNumber);
decoratePropertyCollection(this);
}
......
......@@ -43,8 +43,8 @@ namespace campvis {
, _trackballEH(0)
{
addProperty(&p_camera);
addProperty(&p_sliceNumber);
addProperty(p_camera);
addProperty(p_sliceNumber);
_trackballEH = new TrackballNavigationEventListener(&p_camera, &_canvasSize);
addEventListenerToBack(_trackballEH);
......@@ -89,7 +89,7 @@ namespace campvis {
_vectorFieldRenderer.p_sliceOrientation.setValue(3);
Geometry1DTransferFunction* tf = new Geometry1DTransferFunction(128, tgt::vec2(0.f, 1.f));
tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 0), tgt::col4(255, 255, 255, 255)));
tf->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 255), tgt::col4(255, 255, 255, 255)));
_sliceRenderer.p_transferFunction.replaceTF(tf);
_sliceRenderer.p_targetImageID.setValue("slice");
_sliceRenderer.p_targetImageID.addSharedProperty(&_rtc.p_secondImageId);
......
......@@ -40,43 +40,43 @@ namespace campvis {
GenericOption<VectorFieldRenderer::SliceOrientation>("z", "XY Plane", VectorFieldRenderer::XY_PLANE),
GenericOption<VectorFieldRenderer::SliceOrientation>("y", "XZ Plane", VectorFieldRenderer::XZ_PLANE),
GenericOption<VectorFieldRenderer::SliceOrientation>("x", "YZ Plane", VectorFieldRenderer::YZ_PLANE),
GenericOption<VectorFieldRenderer::SliceOrientation>("a", "XYZ Volume", VectorFieldRenderer::XYZ_VOLUME)
GenericOption<VectorFieldRenderer::SliceOrientation>("a", "XYZ Volume", VectorFieldRenderer::XYZ_VOLUME)
};
const std::string VectorFieldRenderer::loggerCat_ = "CAMPVis.modules.classification.VectorFieldRenderer";
VectorFieldRenderer::VectorFieldRenderer(IVec2Property* viewportSizeProp)
: VisualizationProcessor(viewportSizeProp)
, p_inputVectors("InputImage", "Input Image Vectors", "vectors", DataNameProperty::READ, INVALID_RESULT | INVALID_PROPERTIES)
, p_inputVectors("InputImage", "Input Image Vectors", "vectors", DataNameProperty::READ)
, p_renderOutput("RenderOutput", "Output Image", "VectorFieldRenderer.output", DataNameProperty::WRITE)
, p_arrowSize("ArrowSize", "Arrow Size", 1.f, .001f, 5.f)
, p_lenThresholdMin("LenThresholdMin", "Length Threshold Min", .001f, 0.f, 1000.f, 0.005f)
, p_lenThresholdMax("LenThresholdMax", "Length Threshold Max", 10.f, 0.f, 10000.f, 10.f)
, p_flowProfile1("FlowSpline1", "Flow Profile - Spline 1", 1.f, .0f, 2.f)
, p_flowProfile2("FlowSpline2", "Flow Profile - Spline 2", 1.f, .0f, 2.f)
, p_flowProfile3("FlowSpline3", "Flow Profile - Spline 3", 1.f, .0f, 2.f)
, p_flowProfile4("FlowSpline4", "Flow Profile - Spline 4", 1.f, .0f, 2.f)
, p_Time("time", "Time", 0, 0, 100)
, p_lenThresholdMin("LenThresholdMin", "Length Threshold Min", .001f, 0.f, 1000.f, 0.005f)
, p_lenThresholdMax("LenThresholdMax", "Length Threshold Max", 10.f, 0.f, 10000.f, 10.f)
, p_flowProfile1("FlowSpline1", "Flow Profile - Spline 1", 1.f, .0f, 2.f)
, p_flowProfile2("FlowSpline2", "Flow Profile - Spline 2", 1.f, .0f, 2.f)
, p_flowProfile3("FlowSpline3", "Flow Profile - Spline 3", 1.f, .0f, 2.f)
, p_flowProfile4("FlowSpline4", "Flow Profile - Spline 4", 1.f, .0f, 2.f)
, p_Time("time", "Time", 0, 0, 100)
, p_camera("Camera", "Camera", tgt::Camera())
, p_sliceOrientation("SliceOrientation", "Slice Orientation", sliceOrientationOptions, 4, INVALID_RESULT | INVALID_PROPERTIES)
, p_sliceOrientation("SliceOrientation", "Slice Orientation", sliceOrientationOptions, 4)
, p_sliceNumber("SliceNumber", "Slice Number", 0, 0, 0)
, _arrowGeometry(0)
{
addDecorator(new ProcessorDecoratorShading());
addProperty(&p_inputVectors);
addProperty(&p_renderOutput);
addProperty(&p_arrowSize);
addProperty(&p_lenThresholdMin);
addProperty(&p_lenThresholdMax);
addProperty(&p_camera);
addProperty(&p_sliceOrientation);
addProperty(&p_sliceNumber);
addProperty(&p_Time);
addProperty(&p_flowProfile1);
addProperty(&p_flowProfile2);
addProperty(&p_flowProfile3);
addProperty(&p_flowProfile4);
addProperty(p_inputVectors, INVALID_RESULT | INVALID_PROPERTIES);
addProperty(p_renderOutput);
addProperty(p_arrowSize);
addProperty(p_lenThresholdMin);
addProperty(p_lenThresholdMax);
addProperty(p_camera);
addProperty(p_sliceOrientation, INVALID_RESULT | INVALID_PROPERTIES);
addProperty(p_sliceNumber);
addProperty(p_Time);
addProperty(p_flowProfile1);
addProperty(p_flowProfile2);
addProperty(p_flowProfile3);
addProperty(p_flowProfile4);
decoratePropertyCollection(this);
}
......@@ -107,12 +107,12 @@ namespace campvis {
return;
}
GenericImageRepresentationLocal<float, 3>::ScopedRepresentation vectors(dataContainer, p_inputVectors.getValue());
GenericImageRepresentationLocal<float, 3>::ScopedRepresentation vectors(dataContainer, p_inputVectors.getValue());
if(vectors) {
const tgt::Camera& cam = p_camera.getValue();
const tgt::svec3& imgSize = vectors->getSize();
const int sliceNumber = p_sliceNumber.getValue();
const int sliceNumber = p_sliceNumber.getValue();
glEnable(GL_DEPTH_TEST);
_shader->activate();
......@@ -128,11 +128,11 @@ namespace campvis {
createAndAttachDepthTexture();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float scale = getTemporalFlowScaling((float)p_Time.getValue() / 100.f,
p_flowProfile1.getValue(),
p_flowProfile2.getValue(),
p_flowProfile3.getValue(),
p_flowProfile4.getValue());
float scale = getTemporalFlowScaling((float)p_Time.getValue() / 100.f,
p_flowProfile1.getValue(),
p_flowProfile2.getValue(),
p_flowProfile3.getValue(),
p_flowProfile4.getValue());
switch (p_sliceOrientation.getOptionValue()) {
case XY_PLANE:
......@@ -156,15 +156,15 @@ namespace campvis {
}
}
break;
case XYZ_VOLUME:
for (size_t x = 0; x < imgSize.x; ++x) {
for (size_t y = 0; y < imgSize.y; ++y) {
for (size_t z = 0; z < imgSize.z; ++z) {
renderVectorArrow(vectors, tgt::ivec3(static_cast<int>(x), static_cast<int>(y), static_cast<int>(z)), scale);
}
}
}
break;
case XYZ_VOLUME:
for (size_t x = 0; x < imgSize.x; ++x) {
for (size_t y = 0; y < imgSize.y; ++y) {
for (size_t z = 0; z < imgSize.z; ++z) {
renderVectorArrow(vectors, tgt::ivec3(static_cast<int>(x), static_cast<int>(y), static_cast<int>(z)), scale);
}
}
}
break;
}
decorateRenderEpilog(_shader);
......@@ -182,10 +182,10 @@ namespace campvis {
void VectorFieldRenderer::updateProperties(DataContainer& dataContainer) {
GenericImageRepresentationLocal<float, 3>::ScopedRepresentation vectors(dataContainer, p_inputVectors.getValue());
GenericImageRepresentationLocal<float, 3>::ScopedRepresentation vectors(dataContainer, p_inputVectors.getValue());
if(vectors) {
switch (p_sliceOrientation.getOptionValue()) {
switch (p_sliceOrientation.getOptionValue()) {
case XY_PLANE:
p_sliceNumber.setMaxValue(static_cast<int>(vectors->getSize().z - 1));
break;
......@@ -195,13 +195,13 @@ namespace campvis {
case YZ_PLANE:
p_sliceNumber.setMaxValue(static_cast<int>(vectors->getSize().x - 1));
break;
case XYZ_VOLUME:
p_sliceNumber.setMaxValue(0);
case XYZ_VOLUME:
p_sliceNumber.setMaxValue(0);
}
}
}
else {
LERROR("No suitable input data found or size of images mismatch!");
}
LERROR("No suitable input data found or size of images mismatch!");
}
validate(INVALID_PROPERTIES);
}
......@@ -219,92 +219,92 @@ namespace campvis {
void VectorFieldRenderer::renderVectorArrow(const GenericImageRepresentationLocal<float, 3>* vectors, const tgt::vec3& position, float scale) {
// avoid overflows
if(position.x >= vectors->getSize().x || position.x < 0 ||
position.y >= vectors->getSize().y || position.y < 0 ||
position.z >= vectors->getSize().z || position.z < 0)
return;
// gather vector direction
const tgt::vec3& dir = vectors->getElement(position);
float len = tgt::length(dir);
// threshold
if(len < p_lenThresholdMin.getValue() || len > p_lenThresholdMax.getValue())
return;
tgt::vec3 up(0.f, 0.f, 1.f);
tgt::vec3 dirNorm = tgt::normalize(dir);
tgt::vec3 axis = tgt::cross(up, dirNorm);
float dotPr = tgt::dot(up, dirNorm);
tgt::mat4 rotationMatrix;
if(abs(dotPr-1)<1.e-3f)
rotationMatrix = tgt::mat4::identity;
else if(abs(dotPr+1)<1.e-3f)
rotationMatrix = tgt::mat4::createRotation(tgt::PIf, tgt::vec3(1.f, 0.f, 0.f));
else {
rotationMatrix = tgt::mat4::createRotation(acos(dotPr), tgt::normalize(axis));
}
// avoid overflows
if(position.x >= vectors->getSize().x || position.x < 0 ||
position.y >= vectors->getSize().y || position.y < 0 ||
position.z >= vectors->getSize().z || position.z < 0)
return;
// gather vector direction
const tgt::vec3& dir = vectors->getElement(position);
float len = tgt::length(dir);
// threshold
if(len < p_lenThresholdMin.getValue() || len > p_lenThresholdMax.getValue())
return;
tgt::vec3 up(0.f, 0.f, 1.f);
tgt::vec3 dirNorm = tgt::normalize(dir);
tgt::vec3 axis = tgt::cross(up, dirNorm);
float dotPr = tgt::dot(up, dirNorm);
tgt::mat4 rotationMatrix;
if(abs(dotPr-1)<1.e-3f)
rotationMatrix = tgt::mat4::identity;
else if(abs(dotPr+1)<1.e-3f)
rotationMatrix = tgt::mat4::createRotation(tgt::PIf, tgt::vec3(1.f, 0.f, 0.f));
else {
rotationMatrix = tgt::mat4::createRotation(acos(dotPr), tgt::normalize(axis));
}
const tgt::mat4& voxelToWorldMatrix = vectors->getParent()->getMappingInformation().getVoxelToWorldMatrix();
// compute model matrix
tgt::mat4 modelMatrix = voxelToWorldMatrix * tgt::mat4::createTranslation(position) * rotationMatrix *
tgt::mat4::createScale(tgt::vec3(len * p_arrowSize.getValue())) * tgt::mat4::createScale(tgt::vec3(scale));
tgt::mat4::createScale(tgt::vec3(len * p_arrowSize.getValue())) * tgt::mat4::createScale(tgt::vec3(scale));
// setup shader
//_shader->setUniform("_color", tgt::vec4(dirNorm, 1.f));
float color = (len - p_lenThresholdMin.getValue()) / (p_lenThresholdMax.getValue() - p_lenThresholdMin.getValue());
_shader->setUniform("_color", tgt::vec4(1.f, 1-color, 1-color, 1.f));
float color = (len - p_lenThresholdMin.getValue()) / (p_lenThresholdMax.getValue() - p_lenThresholdMin.getValue());
_shader->setUniform("_color", tgt::vec4(1.f, 1-color, 1-color, 1.f));
// render single ellipsoid
_shader->setUniform("_modelMatrix", modelMatrix);
_arrowGeometry->render(GL_TRIANGLE_STRIP);
// render single ellipsoid
_shader->setUniform("_modelMatrix", modelMatrix);
_arrowGeometry->render(GL_TRIANGLE_STRIP);
}
float VectorFieldRenderer::getTemporalFlowScaling(float t, float Ct0, float Ct1, float Ct2, float Ct3)
{
const float halfPeriod = 0.5f;
const float spacing = 0.25f;
float St[4];
for(int j = 0; j < 4; ++j) { // iterate over spline positions
float splinePos = spacing * (j+1);
// periodic alignment of samples -> contribution to all splines => dense sampling matrix
if(t > splinePos + halfPeriod)
t -= 1;
else if(t < splinePos - halfPeriod)
t += 1;
float p = (splinePos - t) / spacing;
St[j] = evaluateCubicBSpline(p);
}
return St[0]*Ct0 + St[1]*Ct1 + St[2]*Ct2 + St[3]*Ct3;
}
float VectorFieldRenderer::evaluateCubicBSpline(float t)
{
t += 2; // t is given zero-centered => shift peak from 2 to 0
if(t <= 0 || t >= 4)
return 0;
else if(t <= 1)
return t*t*t / 6.0f;
else if(t <= 2) {
t -= 1;
return (-3*t*t*t + 3*t*t + 3*t + 1) / 6.0f;
}
else if(t <= 3) {
t -= 2;
return (3*t*t*t - 6*t*t + 4) / 6.0f;
}
else {
t -= 3;