Commit 149b80d2 authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

RF: Change 3D tractovis so that line/tube width//diameter is fixed in world

coords, so scales sensible w.r.t. zoom level.
parent 59ac9705
......@@ -66,8 +66,7 @@ def draw2D(self, axes, mvp):
# each vertex is drawn as a circle,
# using instanced rendering.
vertices = glroutines.unitCircle(res)
lineWidth = self.normalisedLineWidth
scales = affine.transform([lineWidth] * 3, mvp, vector=True)
scales = self.normalisedLineWidth(mvp)
vertices[:, :2] *= scales[:2]
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
......@@ -110,6 +109,9 @@ def draw3D(self, xform=None):
shader.set('MVP', mvp)
# See comments in gl33.gltractogram_funcs.draw3D
with glroutines.enabled(gl.GL_CULL_FACE):
# we don't implement line width in gl21 - we
# would need to use instanced rendering to
# draw each line segment as a rectangle.
gl.glLineWidth(lineWidth)
gl.glCullFace(gl.GL_BACK)
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
......
......@@ -92,8 +92,7 @@ def draw2D(self, axes, mvp):
colourMode = opts.effectiveColourMode
clipMode = opts.effectiveClipMode
shader = self.shaders[colourMode][clipMode][0]
lineWidth = self.normalisedLineWidth
scales = affine.transform([lineWidth] * 3, mvp, vector=True)
scales = self.normalisedLineWidth(mvp)
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
......@@ -119,7 +118,7 @@ def draw3D(self, xform=None):
lighting = canvas.opts.light
lightPos = affine.transform(canvas.lightPos, mvp)
nstrms = ovl.nstreamlines
lineWidth = self.normalisedLineWidth
lineWidth = self.normalisedLineWidth(mvp)
offsets = self.offsets
counts = self.counts
nstrms = len(offsets)
......
......@@ -237,13 +237,39 @@ class GLTractogram(globject.GLObject):
self.opts.bounds.getHi())
@property
def normalisedLineWidth(self):
def normalisedLineWidth(self, mvp):
"""Returns :attr:`lineWidth`, scaled so that it is with respect to
to world coordinate system.
normalised device coordinates. Streamline lines/tubes (in 3D) and
vertices (in 2D) are drawn such that the width/radius is fixed w.r.t.
the world coordinate system - i.e. for a given ``lineWidth``,
lines/tubes/circles will be small when zoomed out, and big when
zoomed in.
:arg mvp: Current MVP matrix
"""
# Line width is fixed at 0.1 in world units.
return self.opts.lineWidth / 10
# Line width is fixed at 0.1 in world
# units. Below we convert it so it is
# in terms of NDCs.
lineWidth = self.opts.lineWidth / 10
if self.threedee:
# We don't apply the scene3d rotation, because
# the projection matrix adds an uneven scaling
# to the depth axis (see routines.ortho3D),
# which will affect scaling when rotated to be
# in line with that axis. I may revisit this in
# the future, as the ortho3D function is a bit
# nuts in how it handles depth (caused my my
# lack of understanding of near/far clipping).
canvas = self.canvas
scaling = affine.concat(canvas.projectionMatrix,
canvas.viewScale)
lineWidth = lineWidth * scaling[0, 0]
else:
# return separate scales for each axis
lineWidth = affine.transform([lineWidth] * 3, mvp, vector=True)
return lineWidth
@property
......
Supports Markdown
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