[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: Demo for screen locked renderer.



Hi Jim,

Thanks for the demo and detailed explanation.

> Look forward to hearing your thoughts on this.   I hope
> the main javadoc makes sense to you.

I will reply to the comments in ScreenLockedDemo, since
they had the real content of your message.

* Conclusions:
*
*      ScalarMap.setRange() is having an effect that I am not
*      accounting for.
*
*      It seems that setRange() needs to be accounted for, regardless
*      of which scalar is involved in the setRange.  In "Test 3", visad
*      would have done an auto-setRange on the scalar map that maps
*      the field's range type to Display.RGB.

setRange() determines the linear mapping from RealType
values to DisplayRealType values. You could view these
linear mappings in XAxis, YAxis and ZAxis values as a
matrix that is applied before the normal ProjectionControl
matrix. So if you multiply the matrix currently passed to
transformGroup.setTransform(), by a matrix that undoes the
*change* in Axis linear mapping (you may need to experiment
with the order of the multiply), then this gives this matrix
that you need to pass to transformGroup.setTransform().

Note that the linear maps for XAxis, YAxis and ZAxis all
have different scales, so the matrix that undoes the
*change* in the ScalarMap linear mappings needs to have
3 scales (these are the first 3 diagonal elements in the
matrix) and 3 translations.

Your ScreenLockedRendererJ3D or ShadowScreenLocked*TypeJ3D
will need to find the ScalarMaps to XAxis, YAxis and ZAxis,
save the results of getRange() calls for these ScalarMaps
as part of the initialization code, then call getRange()
again in the controlChanged() code and compute the change
in scale and translate for each axis.

If I were doing this, I'd count on the need to experiment
with matrices to get it right. Please let us know if you
encounter serious problems.

* Future problems:
*
*      Even if we can learn to correctly handle ScalarMap.setRange(),
*      there is another problem waiting.
*
*      This is the problem that I described earlier regarding the
*      re-initialisation of the x/y/z translations and scale.  If
*      a user is pushing the system hard, and "please wait" is
*      displayed, and the display is zoomed/panned, notification of
*      changes in the projection control matrix become coarse-grained,
*      and re-initialisation is done to the wrong location.

This is a pretty messy problem. I'd experiment with putting
the code that gets and saves the initial* values (inside
"if (first) { }") in its own Thread, that waits for a
DisplayEvent.TRANSFORM_DONE from the DisplayImpl.

Of course this won't make the depictions right while the
"please wait" is on (by definition, depictions are not
ready yet), but may make things right after it goes off.

For this to work right, it is probably necessary for all
display change triggers to be inside a display.disableAction()...
display.enableAction() pair, so there is only one
DisplayEvent.TRANSFORM_DONE.

If this still doesn't get it, you might experiment with
calling MouseHelper.setFunctionMap() to all MouseHelper.NONE
before any event that will trigger re-transform, and restore
the MouseHelper.setFunctionMap() after DisplayEvent.TRANSFORM_DONE.

* Other:
*
*      As an aside, I would like to mention that the projection
*      control listeners need to be removed when the shadow is
*      destroyed.

Is this a problem, or just a warning to folks who work
with these classes?

* Question:
*
*      Is it possible to not have to re-initialise the x/y/z translations
*      and scale?  Perhaps extra logic can be added to
ScreenLockedRendererJ3D
*      and the ShadowScreenLocked*J3D classes that allow the
*      translations and scale to be initialised only once?

You could experiment with initialising the x/y/z translations
and scale when the DisplayImpl is created. This would be a bit
messy. I'd do this in ScreenLockedRendererJ3D.setDisplay(DisplayImpl),
overriding that method in DataRenderer, as follows:

  public void setDisplay(DisplayImpl d) {
    super.setDisplay(d);
    // get and save translations and scale
    // . . .
  }

Then the controlChanged() methods of your ShadowScreenLocked*TypeJ3D
classes would call some method of ScreenLockedRendererJ3D to get
these saved values(any ShadowType can call getLink().getRenderer()
to get its DataRenderer).

I am not sure exactly what effect moving the initialization
cdoe like this would be on the placement of your screen
locked depictions. I think it should be OK, but only some\
experiments will tell for sure.

Cheers,
Bill
----------------------------------------------------------
Bill Hibbard, SSEC, 1225 W. Dayton St., Madison, WI  53706
hibbard@facstaff.wisc.edu  608-263-4427  fax: 608-263-6738
http://www.ssec.wisc.edu/~billh/vis.html