Commit 4d2cfb2e authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[ADD] Now new fiber stippling is able to span quads only if probability is high.

parent afacbf21
......@@ -22,6 +22,7 @@
//
//---------------------------------------------------------------------------
#include <cstdlib>
#include <string>
#include <osg/Geometry>
......@@ -163,6 +164,69 @@ void WMFiberStipples::properties()
WModule::properties();
}
namespace {
osg::ref_ptr< osg::Geode > genScatteredDegeneratedQuads( size_t numSamples, osg::Vec3 const& base, osg::Vec3 const& a, osg::Vec3 const& b )
{
// the stuff needed by the OSG to create a geometry instance
osg::ref_ptr< osg::Vec3Array > vertices = new osg::Vec3Array( numSamples * 4 );
osg::ref_ptr< osg::Vec3Array > texcoords0 = new osg::Vec3Array( numSamples * 4 );
osg::ref_ptr< osg::Vec3Array > texcoords1 = new osg::Vec3Array( numSamples * 4 );
osg::ref_ptr< osg::Vec3Array > normals = new osg::Vec3Array;
osg::ref_ptr< osg::Vec4Array > colors = new osg::Vec4Array;
osg::Vec3 aCrossB = a ^ b;
aCrossB.normalize();
osg::Vec3 aNorm = a;
aNorm.normalize();
osg::Vec3 bNorm = b;
bNorm.normalize();
std::srand( time( NULL ) );
double lambda0, lambda1;
const double rndMax = RAND_MAX;
for( size_t i = 0; i < numSamples; ++i )
{
// The degenerated QUAD should have all points in its center
lambda0 = rand() / rndMax;
lambda1 = rand() / rndMax;
osg::Vec3 quadCenter = base + a * lambda0 + b * lambda1;
for( int j = 0; j < 4; ++j )
{
vertices->push_back( quadCenter );
}
texcoords0->push_back( ( -aNorm + -bNorm ) );
texcoords0->push_back( ( aNorm + -bNorm ) );
texcoords0->push_back( ( aNorm + bNorm ) );
texcoords0->push_back( ( -aNorm + bNorm ) );
texcoords1->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
texcoords1->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
texcoords1->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
texcoords1->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
}
normals->push_back( aCrossB );
colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
// put it all together
osg::ref_ptr< osg::Geometry > geometry = new osg::Geometry();
geometry->setVertexArray( vertices );
geometry->setTexCoordArray( 0, texcoords0 );
geometry->setTexCoordArray( 1, texcoords1 );
geometry->setNormalBinding( osg::Geometry::BIND_OVERALL );
geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
geometry->setNormalArray( normals );
geometry->setColorArray( colors );
geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, vertices->size() ) );
osg::ref_ptr< osg::Geode > geode = new osg::Geode();
geode->addDrawable( geometry );
return geode;
}
}
void WMFiberStipples::initOSG()
{
debugLog() << "Init OSG";
......@@ -198,9 +262,13 @@ void WMFiberStipples::initOSG()
}
// create a new geode containing the slices
osg::ref_ptr< osg::Node > slice = wge::genFinitePlane( minV, osg::Vec3( sizes[0], 0.0, 0.0 ),
osg::Vec3( 0.0, 0.0, sizes[2] ) );
osg::ref_ptr< osg::Node > slice = genScatteredDegeneratedQuads( 1000, minV, osg::Vec3( sizes[0], 0.0, 0.0 ),
osg::Vec3( 0.0, 0.0, sizes[2] ) );
slice->setName( "Coronal Slice" );
osg::Uniform* aVec = new osg::Uniform( "u_aVec", osg::Vec3( sizes[0], 0.0, 0.0 ) );
slice->getOrCreateStateSet()->addUniform( aVec );
osg::Uniform* bVec = new osg::Uniform( "u_bVec", osg::Vec3( 0.0, 0.0, sizes[2] ) );
slice->getOrCreateStateSet()->addUniform( bVec );
osg::Uniform* sliceUniform = new osg::Uniform( "u_WorldTransform", osg::Matrix::identity() );
slice->getOrCreateStateSet()->addUniform( sliceUniform );
slice->setCullingActive( false );
......@@ -234,7 +302,7 @@ void WMFiberStipples::moduleMain()
initOSG();
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_output );
osg::ref_ptr< WGEShader > shader = new WGEShader( "WFiberStipples", m_localPath );
WGEColormapping::apply( m_output, shader ); // this automatically applies the shader
shader->apply( m_output ); // this automatically applies the shader
// main loop
while( !m_shutdownFlag() )
......
......@@ -37,36 +37,35 @@ uniform sampler3D u_probTractSampler;
uniform float u_vectorsMin;
uniform float u_vectorsScale;
varying vec4 diffusionDirection;
//uniform float u_glyphThickness;
//uniform float u_glyphSize;
//
//varying vec4 v_middlePoint;
//
//float minimum_distance( vec3 v, vec3 w, vec3 p )
//{
// // Return minimum distance between line segment vw and point p
// float len = length( v - w );
// if( len == 0.0 ) // v == w case
// {
// return distance( p, v );
// }
// // Consider the line extending the segment, parameterized as v + t (w - v).
// // We find projection of point p onto the line.
// // It falls where t = [(p-v) . (w-v)] / |w-v|^2
// float t = dot( p - v, w - v ) / ( len * len );
//
// if( t < 0.0 ) // Beyond the 'v' end of the segment
// {
// return distance( p, v );
// }
// else if( t > 1.0 ) // Beyond the 'w' end of the segment
// {
// return distance( p, w );
// }
// vec3 projection = v + t * ( w - v ); // Projection falls on the segment
// return distance( p, projection );
//}
float minimum_distance( vec3 v, vec3 w, vec3 p )
{
// Return minimum distance between line segment vw and point p
float len = length( v - w );
if( len == 0.0 ) // v == w case
{
return distance( p, v );
}
// Consider the line extending the segment, parameterized as v + t (w - v).
// We find projection of point p onto the line.
// It falls where t = [(p-v) . (w-v)] / |w-v|^2
float t = dot( p - v, w - v ) / ( len * len );
if( t < 0.0 ) // Beyond the 'v' end of the segment
{
return distance( p, v );
}
else if( t > 1.0 ) // Beyond the 'w' end of the segment
{
return distance( p, w );
}
vec3 projection = v + t * ( w - v ); // Projection falls on the segment
return distance( p, projection );
}
......@@ -133,14 +132,16 @@ void main()
// float f_r2 = p2 - sqrt( p2 * p2 + q );
// float f_radius = max( r1, r2 );
vec4 direction = abs( texture3DUnscaled( u_vectorsSampler, gl_TexCoord[0].xyz, u_vectorsMin, u_vectorsScale ) );
vec4 probRGBA = texture3D( u_probTractSampler, gl_TexCoord[0].xyz );
probRGBA.a = 1.0; // set alpha explicity to 1
// vec4 direction = abs( texture3DUnscaled( u_vectorsSampler, gl_TexCoord[0].xyz, u_vectorsMin, u_vectorsScale ) );
// vec4 probRGBA = texture3D( u_probTractSampler, gl_TexCoord[0].xyz );
// probRGBA.a = 1.0; // set alpha explicity to 1
// vec4 value = texture3D( u_probTractSampler, vec3(gl_TexCoord[0].x, gl_TexCoord[0].y, gl_TexCoord[0].z) );
// gl_FragColor = vec4( gl_TexCoord[0].xyz, 1.0 ); // vec4( value, 1.0, 0.0, 1.0 );
// gl_FragColor = vec4( value, 0.0, 0.0, 1.0 );
gl_FragColor = 0.8 * probRGBA + 0.2 * direction;
// gl_FragColor = vec4( texture3D( u_probTractSampler, pansen.xyz ).rgb, 1.0 );//vec4( 1.0, 0.0, 0.0, 1.0 );
gl_FragColor = vec4( gl_TexCoord[1].xyz, 1.0 );
// gl_FragColor = 0.8 * probRGBA + 0.2 * direction;
// // if( minimum_distance( gl_TexCoord[1].xyz, gl_TexCoord[2].xyz, gl_TexCoord[0].xyz ) < radius )
......
......@@ -24,13 +24,35 @@
#version 120
#include "WGETextureTools.glsl"
/**
* These two uniforms are needed to transform the vectors out of their texture back to their original form
* as they are stored in RBGA (for example allowing only values between 0..1 for components but no negative
* ones).
*/
uniform float u_vectorsMin;
uniform float u_vectorsScale;
/**
* The matrix describes the transformation of gl_Vertex to OpenWalnut Scene Space
*/
uniform mat4 u_WorldTransform;
uniform sampler3D u_vectorsSampler;
uniform sampler3D u_probTractSampler;
uniform int u_probTractSizeX;
uniform int u_probTractSizeY;
uniform int u_probTractSizeZ;
// vectors spanning the plane of the quad
uniform vec3 u_aVec;
uniform vec3 u_bVec;
varying vec3 diffusionDirection;
varying vec3 focalPoint1;
varying vec3 focalPoint2;
/**
* Vertex Main. Simply transforms the geometry. The work is done per fragment.
......@@ -38,8 +60,23 @@ uniform int u_probTractSizeY;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[0].y = ( u_WorldTransform[3] / u_probTractSizeY ).y;
// transform position
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex;
gl_TexCoord[1] = gl_MultiTexCoord1;
// compute texture coordinate
vec3 texturePosition = vec3( gl_Vertex.x / float(u_probTractSizeX), gl_Vertex.y / float(u_probTractSizeY), gl_Vertex.z / float(u_probTractSizeZ) );
// span quad incase of regions with high probablility
texturePosition.y = ( u_WorldTransform[3] / u_probTractSizeY ).y;
if( texture3D( u_probTractSampler, texturePosition ).r > 0.01 ) // rgb are the same
{
// transform position, the 4th component must be explicitly set, as otherwise they would have been scaled
gl_Position = gl_ModelViewProjectionMatrix * ( vec4( gl_TexCoord[0].xyz + gl_Vertex.xyz, 1.0 ) );
}
else
{
gl_Position = ftransform(); // discard those vertices
}
// get principal diffusion direction
diffusionDirection = abs( texture3DUnscaled( u_vectorsSampler, texturePosition, u_vectorsMin, u_vectorsScale ) ).xyz;
}
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