[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: ScreenLockedRendererJ3D() (fwd)
Here's Jim's initial answer to Don's question, which I
am also taking the liberty of forwarding. This forward
is not meant to be a substitute for a later response
from Jim.
---------- Forwarded message ----------
Date: Tue, 20 May 2003 10:56:59 +1000
From: Jim Koutsovasilis <jimk@bom.gov.au>
To: dmurray@unidata.ucar.edu
Cc: Bill Hibbard <billh@ssec.wisc.edu>
Subject: Re: ScreenLockedRendererJ3D()
Hello Don,
thanks for the encouraging email.
We have disabled rotation by using MouseHelper.setFunctionMap(),
so we don't experience the problem you are having.
I ran a quick test, and re-enabled rotation, and as you noted, the
scale does behave strangely. The scale was not written to handle
rotation, and I'm not sure (off the top of my head) how I would
go about changing SignalStrengthScale.redraw() to allow for this.
SignalStrenghScale.setupDataCoords() converts from screen-coordinates
to data-coordinates, so this is probably the place to account for rotation.
However, there is a bigger problem...SignalStrengthScale.java does
not use the screen-locked renderer. Instead, the scale is redrawn
when the user releases the left mouse button (ie. the display may have
been zoomed/panned). So this is like "pseudo-screenlocked".
I have had problems with ShadowScreenLockedFunctionTypeJ3D to
the point where I had to stop using it, and will be posting to the
visad-renderer list soon.
By the way, your extension to ShadowScreenLockedFunctionTypeJ3D is
spot-on. That's exactly what I had done when I tried using the
screen locked renderer for our radar rain-rate scale. I haven't fed the
changes back to Bill because I've had some problems with
ShadowScreenLockedFunctionTypeJ3D.
I'll post an email to the visad-renderer list today/tomorrow. I'll have to
put together a sample program that illustrates the problem.
PS. as a quick fix to your problem, comment out the calls to
SignalStrength.redraw(), except for this one:
if (!firstFrameDone) {
firstFrameDone = true;
redraw();
return;
}
and use the attached "visad.bom.ShadowScreenLockedFunctionTypeJ3D.java".
This will draw the scale once, right at the start, when the rotation is
zero,
and the scale will be locked to the screen, even if you try rotating. The
problems I am having are related to when the user pans/zooms while
"please wait" is displayed, but I'll talk about that more in my
visad-renderer
email.
Hope this is of some help.
Regards,
Jim.
---
jimk@bom.gov.au
Don Murray wrote:
> Hi Jim-
>
> You've been doing some great work in VisAD and I'm trying
> to use it as much as possible. I'm working with your
> SignalStrengthScale example that you sent out recently
> to add in color scales to the displays of our IDV.
>
> What I'd like to do is make these screen locked, so I
> was looking at your ScreenLockedRenderer which handles
> text. I'm wondering if this could be adapted to handle
> shapes as well, or if it would need to be a different
> class?
>
> I don't know anything about DataRenderers, but it looks
> like in your ShadowScreenLocked* classes, you've overridden
> addTextToGroup to add in the transform group that holds the
> text. It seems like to do this for shapes, one would have
> to override addToGroup somehow to add in the transform group.
> What I tried was overriding addToGroup in the ScreenLockedRenderer
> to be:
>
> public boolean addToGroup(Object group, VisADGeometryArray geomArray,
> GraphicsModeControl control, float alpha, float [] color)
> throws VisADException
> {
> ((Group) group).addChild(transformGroup);
> return super.addToGroup(transformGroup, geomArray, control, alpha,
> color);
> }
>
> This kept the main in ScreenLockedRenderer working fine.
> For the shape, it almost worked. Zooming in and zooming out
> kept the color bar (i haven't added labels) in the same place.
> Rotating the cube caused the color bar to jump around, presumably
> because the transforms for line arrays are different from
> triangle arrays.
>
> Do you have any suggestions on how I might get this to work?
>
> Thanks in advance.
>
> Don
> *************************************************************
> Don Murray UCAR Unidata Program
> dmurray@unidata.ucar.edu P.O. Box 3000
> (303) 497-8628 Boulder, CO 80307
> http://www.unidata.ucar.edu/staff/donm
> *************************************************************
>
>
>
//
// ShadowScreenLockedFunctionTypeJ3D.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2002 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad.bom;
// Java
import java.rmi.RemoteException;
// VisAD
import visad.ControlEvent;
import visad.ControlListener;
import visad.DataDisplayLink;
import visad.GraphicsModeControl;
import visad.MathType;
import visad.ShadowType;
import visad.VisADException;
import visad.VisADGeometryArray;
import visad.java3d.ShadowFunctionTypeJ3D;
import visad.java3d.MouseBehaviorJ3D;
import visad.java3d.ProjectionControlJ3D;
import visad.java3d.DisplayImplJ3D;
// Java 3D
import javax.media.j3d.Group;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.Transform3D;
import javax.vecmath.Vector3d;
import javax.vecmath.Matrix3d;
/**
* This renderer locks text to the screen. The display can be
* panned and zoomed, but the text stays locked to its
* initial position.
*/
public class ShadowScreenLockedFunctionTypeJ3D extends ShadowFunctionTypeJ3D
{
private TransformGroup transformGroup = null;
private ProjectionControlListener projectionControlListener = null;
/*
private static boolean first = true;
private static double initialScale;
private static double initialXTrans;
private static double initialYTrans;
private static double initialZTrans;
*/
private static Object lock = new Object();
public ShadowScreenLockedFunctionTypeJ3D(MathType type, DataDisplayLink link,
ShadowType parent)
throws RemoteException, VisADException
{
super(type, link, parent);
/*
first = true;
*/
transformGroup = new TransformGroup();
transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transformGroup.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
// Add our listener to the projection control.
DisplayImplJ3D display = (DisplayImplJ3D) getDisplay();
ProjectionControlJ3D control = (ProjectionControlJ3D)
display.getProjectionControl();
projectionControlListener = new ProjectionControlListener();
control.addControlListener(projectionControlListener);
}
/**
* Adds the text to the scene graph hierarchy.
* Create a new transform group and place the text under this
* transform group. This allows us to set the scale, translation
* and rotation of the text independently of the rest of the nodes
* in the scene graph.
*/
public boolean addTextToGroup(Object group, VisADGeometryArray geomArray,
GraphicsModeControl control, float alpha, float [] color)
throws VisADException
{
((Group) group).addChild(transformGroup);
return super.addTextToGroup(transformGroup, geomArray, control, alpha,
color);
}
/**
* Adds the group to the scene graph hierarchy.
* Create a new transform group and place the text under this
* transform group. This allows us to set the scale, translation
* and rotation of the data independently of the rest of the nodes
* in the scene graph.
*/
public boolean addToGroup(Object group, VisADGeometryArray geomArray,
GraphicsModeControl control, float alpha, float [] color)
throws VisADException
{
((Group) group).addChild(transformGroup);
return super.addToGroup(transformGroup, geomArray, control, alpha,
color);
}
/**
* When the projection control matrix is changed, this listener
* will undo the scale, translation and rotation of the text
* thus locking it to its initial position on the screen.
*/
private class ProjectionControlListener implements ControlListener
{
private boolean first = true;
private double initialScale;
private double initialXTrans;
private double initialYTrans;
private double initialZTrans;
private double [] rotation = null;
private double [] translation = null;
private double [] scale = null;
/**
* Default constructor.
*/
public ProjectionControlListener()
{
rotation = new double[ 3 ];
translation = new double[ 3 ];
scale = new double[ 1 ];
}
/**
* Undo all scale, translation and rotation transformations.
* @param event contains information about this event
*/
public void controlChanged(ControlEvent event)
{
synchronized (lock) {
ProjectionControlJ3D control =
(ProjectionControlJ3D) event.getControl();
double [] projectionControlMatrix = control.getMatrix();
control = null;
MouseBehaviorJ3D.unmake_matrix(rotation, scale, translation,
projectionControlMatrix);
if (first) {
// This is the first time through, so keep a copy
// of our initial scale and translation.
// We assume that there is no rotation.
initialScale = scale[0];
initialXTrans = translation[0];
initialYTrans = translation[1];
initialZTrans = translation[2];
first = false;
projectionControlMatrix = null;
return;
}
Transform3D transform = new Transform3D();
transformGroup.getTransform(transform);
// Get the rotation.
double [][] matrix = new double[4][4];
int k = 0;
for ( int i = 0; i < 4; ++i ) {
for ( int j = 0; j < 4; ++j ) {
matrix[i][j] = projectionControlMatrix[k++];
}
}
projectionControlMatrix = null;
Matrix3d rotationMatrix = new Matrix3d();
rotationMatrix.m00 = matrix[0][0];
rotationMatrix.m01 = matrix[0][1];
rotationMatrix.m02 = matrix[0][2];
rotationMatrix.m10 = matrix[1][0];
rotationMatrix.m11 = matrix[1][1];
rotationMatrix.m12 = matrix[1][2];
rotationMatrix.m20 = matrix[2][0];
rotationMatrix.m21 = matrix[2][1];
rotationMatrix.m22 = matrix[2][2];
matrix = null;
// Undo the rotaion by finding the inverse of the rotation matrix.
rotationMatrix.invert();
rotationMatrix.normalize();
Transform3D rotationTransform = new Transform3D();
rotationTransform.set(rotationMatrix);
// Undo the scaling.
final double newScale = initialScale / scale[0];
// Undo the translation by translating back to our initial location.
Vector3d translationVector = new Vector3d();
translationVector.x = -1 * (translation[0] - initialXTrans) / scale[0];
translationVector.y = -1 * (translation[1] - initialYTrans) / scale[0];
translationVector.z = -1 * (translation[2] - initialZTrans) / scale[0];
Transform3D scaleTranslationTransform = new Transform3D();
scaleTranslationTransform.set(newScale, translationVector );
transform = rotationTransform;
transform.mul( scaleTranslationTransform );
transformGroup.setTransform(transform);
rotationTransform = null;
scaleTranslationTransform = null;
transform = null;
}
}
} // class ShadowScreenLockedFunctionTypeJ3D.ProjectionControlListener
}