Commit 1a9f60ae authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[CHANGE] Created ISO Surface based proba tract display stub

parent 2694b455
......@@ -26,12 +26,13 @@
#define WMPROBTRACTDISPLAY_H
#include <string>
#include <vector>
#include <osg/Node>
#include <osg/Uniform>
#include "../../graphicsEngine/WShader.h"
#include "../../kernel/WModule.h"
#include "../../kernel/WModuleContainer.h"
#include "../../kernel/WModuleInputData.h"
#include "../../kernel/WModuleOutputData.h"
......@@ -40,7 +41,7 @@
* transfer functions.
* \ingroup modules
*/
class WMProbTractDisplay: public WModule
class WMProbTractDisplay: public WModuleContainer
{
public:
......@@ -106,124 +107,57 @@ protected:
*/
virtual void activate();
private:
/**
* An input connector used to get datasets from other modules. The connection management between connectors must not be handled by the module.
* In order to use sub modules we need to create, initialize (properties) and wire them.
*/
boost::shared_ptr< WModuleInputData< WDataSetScalar > > m_input;
void initSubModules();
/**
* This is a pointer to the dataset the module is currently working on.
* Update the submodules incase there has been additionally or less modules selected for isosurface generation.
*/
boost::shared_ptr< WDataSetScalar > m_dataSet;
void updateSubmoduleInstances();
/**
* If this property is true, as special shader is used which emulates isosurfaces using the m_isoValue property.
* Update the properties for each isosurface incase the number of isosurfaces has changed.
*/
WPropBool m_isoSurface;
WPropInt m_isoValue0; //!< The Isovalue used in the case m_isoSurface is true for the 0'th isosurface.
WPropInt m_isoValue1; //!< The Isovalue used in the case m_isoSurface is true for the 1'th isosurface.
WPropInt m_isoValue2; //!< The Isovalue used in the case m_isoSurface is true for the 2'th isosurface.
WPropInt m_isoValue3; //!< The Isovalue used in the case m_isoSurface is true for the 3'th isosurface.
WPropColor m_isoColor0; //!< The color used when in isosurface mode for blending for the 0'th isosurface.
WPropColor m_isoColor1; //!< The color used when in isosurface mode for blending for the 1'th isosurface.
WPropColor m_isoColor2; //!< The color used when in isosurface mode for blending for the 2'th isosurface.
WPropColor m_isoColor3; //!< The color used when in isosurface mode for blending for the 3'th isosurface.
void updateProperties();
private:
/**
* The number of steps to walk along the ray.
* Scalar dataset representing the probability field either in real numbers in [0,1] or gray values or just simply the connectivity
* score (\#visits per voxel).
*/
WPropInt m_stepCount;
WPropInt m_alpha0; //!< The alpha transparency used for the rendering
WPropInt m_alpha1; //!< The alpha transparency used for the rendering
WPropInt m_alpha2; //!< The alpha transparency used for the rendering
WPropInt m_alpha3; //!< The alpha transparency used for the rendering
boost::shared_ptr< WModuleInputData< WDataSetScalar > > m_input;
/**
* If true, the shader will only color using the depth of the point on the surface.
* This is a pointer to the dataset the module is currently working on.
*/
WPropBool m_useSimpleDepthColoring;
boost::shared_ptr< WDataSetScalar > m_dataSet;
/**
* A condition used to notify about changes in several properties.
* The number of ISO-Surfaces.
*/
boost::shared_ptr< WCondition > m_propCondition;
WPropInt m_numSurfaces;
/**
* the PTD shader.
* For each surface its corresponding isovalue.
*/
osg::ref_ptr< WShader > m_shader;
std::vector< WPropDouble > m_isoValues;
/**
* Node callback to change the color of the shapes inside the root node. For more details on this class, refer to the documentation in
* moduleMain().
* The color for each isosurface.
*/
class SafeUpdateCallback : public osg::NodeCallback
{
public: // NOLINT
/**
* Constructor.
*
* \param module just set the creating module as pointer for later reference.
*/
explicit SafeUpdateCallback( WMProbTractDisplay* module ): m_module( module ), m_initialUpdate( true )
{
};
/**
* operator () - called during the update traversal.
*
* \param node the osg node
* \param nv the node visitor
*/
virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
/**
* Pointer used to access members of the module to modify the node.
*/
WMProbTractDisplay* m_module;
/**
* Denotes whether the update callback is called the first time.
*/
bool m_initialUpdate;
};
std::vector< WPropColor > m_colors;
/**
* Class handling uniform update during render traversal
* The alpha values for each isosurface.
*/
class SafeUniformCallback: public osg::Uniform::Callback
{
public:
std::vector< WPropDouble > m_alphaValues;
/**
* Constructor.
*
* \param module just set the creating module as pointer for later reference.
*/
explicit SafeUniformCallback( WMProbTractDisplay* module ): m_module( module )
{
};
/**
* The callback. Called every render traversal for the uniform.
*
* \param uniform the uniform for which this callback is.
* \param nv the visitor.
*/
virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv );
/**
* Pointer used to access members of the module to modify the node.
*/
WMProbTractDisplay* m_module;
};
/**
* Submodules for the iso surface generation.
*/
std::vector< boost::shared_ptr< WModule > > m_isoSurfaces;
};
#endif // WMPROBTRACTDISPLAY_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#version 120
/////////////////////////////////////////////////////////////////////////////
// Varyings
/////////////////////////////////////////////////////////////////////////////
#include "WMProbTractDisplay-varyings.glsl"
#include "WGELighting-fragment.glsl"
/////////////////////////////////////////////////////////////////////////////
// Uniforms
/////////////////////////////////////////////////////////////////////////////
// texture containing the data
uniform sampler3D tex0;
// The isovalue to use.
uniform float u_isovalue0;
uniform float u_isovalue1;
uniform float u_isovalue2;
uniform float u_isovalue3;
// Should the shader create some kind of isosurface instead of a volume rendering?
uniform bool u_isosurface;
// True if only the simple depth value should be used for coloring
uniform bool u_depthCueingOnly;
// The number of steps to use.
uniform int u_steps;
// The alpha value to set
uniform float u_alpha0;
uniform float u_alpha1;
uniform float u_alpha2;
uniform float u_alpha3;
// The color values to set
uniform vec4 u_isocolor0;
uniform vec4 u_isocolor1;
uniform vec4 u_isocolor2;
uniform vec4 u_isocolor3;
/////////////////////////////////////////////////////////////////////////////
// Attributes
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Variables
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Functions
/////////////////////////////////////////////////////////////////////////////
vec3 findRayEnd( out float d )
{
vec3 r = v_ray + vec3( 0.0000001 );
vec3 p = v_rayStart;
// we need to ensure the vector components are not exactly 0.0
// v_ray in cube coordinates is used to check against the unit cube borders
// when will v_ray reach the front face?
float tFront = - p.z / r.z; // (x,x,0) = v_rayStart + t * v_ray
float tBack = ( 1.0 - p.z ) / r.z; // (x,x,1) = v_rayStart + t * v_ray
float tLeft = - p.x / r.x; // (0,x,x) = v_rayStart + t * v_ray
float tRight = ( 1.0 - p.x ) / r.x; // (1,x,x) = v_rayStart + t * v_ray
float tBottom = - p.y / r.y; // (x,0,x) = v_rayStart + t * v_ray
float tTop = ( 1.0 - p.y ) / r.y; // (x,1,x) = v_rayStart + t * v_ray
// get the nearest hit
d = min( min( max( tFront, tBack ), max( tLeft, tRight ) ), max ( tBottom, tTop ) );
return p + ( r * d );
}
float pointDistance( vec3 p1, vec3 p2 )
{
return length( p1 - p2 );
}
void computeLight( inout vec4 col, in vec3 curPoint )
{
vec3 pos = curPoint;
pos.x = curPoint.x - 1.0;
float fx1 = texture3D( tex0, pos ).r;
pos.x = curPoint.x + 1.0;
float fx2 = texture3D( tex0, pos ).r;
pos.x = curPoint.x;
pos.y = curPoint.y - 1.0;
float fy1 = texture3D( tex0, pos ).r;
pos.y = curPoint.y + 1.0;
float fy2 = texture3D( tex0, pos ).r;
pos.y = curPoint.y;
pos.z = curPoint.z - 1.0;
float fz1 = texture3D( tex0, pos ).r;
pos.z = curPoint.z + 1.0;
float fz2 = texture3D( tex0, pos ).r;
pos.z = curPoint.z;
vec3 normal;
normal.x = ( fx1 - fx2 ) / 2.0;
normal.y = ( fy1 - fy2 ) / 2.0;
normal.z = ( fz1 - fz2 ) / 2.0;
vec4 ambient = vec4(0.0);
vec4 diffuse = vec4(0.0);
vec4 specular = vec4(0.0);
calculateLighting(-normal, gl_FrontMaterial.shininess, ambient, diffuse, specular);
col = col + (ambient * col / 2.0) + (diffuse * col) + (specular * col / 2.0);
col = clamp(col, 0.0, 1.0);
}
bool computeColor( in vec3 curPoint, in float isovalue, inout vec4 colorSoFar )
{
if( abs( isovalue - u_isovalue0 ) >= 0.1 && abs( isovalue - u_isovalue1 ) >= 0.1 &&
abs( isovalue - u_isovalue2 ) >= 0.1 && abs( isovalue - u_isovalue3 ) >= 0.1 )
{
return false;
}
// we need to know the depth value of the current point inside the cube
// Therefore, the complete standard pipeline is reproduced here:
// 1: transfer to world space and right after it, to eye space
vec4 curPointProjected = gl_ModelViewProjectionMatrix * vec4( curPoint, 1.0 );
// 2: scale to screen space and [0,1]
// -> x and y is not needed
curPointProjected.z /= curPointProjected.w;
curPointProjected.z = curPointProjected.z * 0.5 + 0.5 ;
// 3: set depth value
gl_FragDepth = curPointProjected.z;
// 4: get alpha and color for the corresponding isolevel
vec4 color;
if( abs( isovalue - u_isovalue0 ) < 0.1 ) {
color = u_alpha0 * u_isocolor0;
color.a = u_alpha0;
}
else if( abs( isovalue - u_isovalue1 ) < 0.1 ) {
color = u_alpha1 * u_isocolor1;
color.a = u_alpha1;
}
else if( abs( isovalue - u_isovalue2 ) < 0.1 ) {
color = u_alpha2 * u_isocolor2;
color.a = u_alpha2;
}
else if( abs( isovalue - u_isovalue3 ) < 0.1 ) {
color = u_alpha3 * u_isocolor3;
color.a = u_alpha3;
}
else {
return false;
}
computeLight( color, curPoint );
// 5: set color
colorSoFar = (1.0 - colorSoFar.a) * color + colorSoFar;
return true;
}
/**
* Main entry point of the fragment shader.
*/
void main()
{
// please do not laugh, it is a very very very simple "isosurface" shader
gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
gl_FragDepth = gl_FragCoord.z;
// First, find the rayEnd point. We need to do it in the fragment shader as the ray end point may be interpolated wrong
// when done for each vertex.
float totalDistance = 0.0;
vec3 rayEnd = findRayEnd( totalDistance );
// Isosurface Mode
if ( u_isosurface )
{
// the point along the ray in cube coordinates
vec3 curPoint = v_rayStart;
// the current value inside the data
float value;
// the step counter
int i = 0;
float stepDistance = totalDistance / float( u_steps );
vec4 colorSoFar = vec4( 0.0, 0.0, 0.0, 0.0 );
bool hit = false;
while ( i < u_steps && colorSoFar.a < 0.95 ) // we do not need to ch
{
// get current value
value = texture3D( tex0, curPoint ).r;
hit = computeColor( curPoint, value, colorSoFar ) || hit;
curPoint += stepDistance * v_ray;
// do not miss to count the steps already done
i++;
}
gl_FragColor = colorSoFar;
// the ray did never hit the surface --> discard the pixel
if ( !hit )
{
discard;
}
}
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// Varyings
// Used in vertex and fragment shader
/////////////////////////////////////////////////////////////////////////////
// The ray's starting point in texture space
varying vec3 v_rayStart;
// The ray direction in texture space
varying vec3 v_ray;
// the Surface normal at this point
varying vec3 v_normal;
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#version 120
/////////////////////////////////////////////////////////////////////////////
// Varyings
/////////////////////////////////////////////////////////////////////////////
#include "WMProbTractDisplay-varyings.glsl"
/////////////////////////////////////////////////////////////////////////////
// Uniforms
/////////////////////////////////////////////////////////////////////////////
// texture containing the data
uniform sampler3D tex0;
/////////////////////////////////////////////////////////////////////////////
// Attributes
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Variables
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Functions
/////////////////////////////////////////////////////////////////////////////
/**
* Main entry point of the vertex shader.
*/
void main()
{
// for easy access to texture coordinates
gl_TexCoord[0] = gl_MultiTexCoord0;
v_normal = gl_Normal;
// in texture space, the starting point simply is the current surface point in texture space
v_rayStart = gl_TexCoord[0].xyz; // this equals gl_Vertex!
// transform the ray direction to texture space, which equals object space
// Therefore use two points, as we transform a vector
vec4 camLookAt = vec4( 0.0, 0.0, -1.0, 1.0 );
vec4 camPos = vec4( 0.0, 0.0, 0.0, 1.0 );
v_ray = ( gl_ModelViewMatrixInverse * ( camLookAt - camPos ) ).xyz;
// Simply project the vertex
gl_Position = ftransform();
gl_FrontColor = gl_Color;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment