Hi Jim,
I have two suggestions:
> I have written a renderer and some shadow types to keep visad
> objects locked on the screen, ie. their position and size does
> not vary as the display is zoomed and/or panned.
Bravo. I am glad to see someone else writing these. It is
high on my list to write a tutorial about writing
DataRenderers and ShadowTypes.
> I am working on an application that displays town names over
> a map of Australia, and only need to keep the size of the
> text constant.
>
> I have tried, but have been unable to change the code in my
> shadow type to allow the font size to remain constant, but the
> position of the text to move.
1. For this, you can use the following recent method of TextControl:
public void setAutoSize(boolean auto);
Call this with auto = true to keep text size constant. With this,
you don't need a custom DataRenderer.
> I will explain my existing "screen locking" code and show
> you what I mean. :)
>
> I have extended a shadow type class, and have overriden the
> addTextToGroup method. This allows me to add my own
> transform group and perform scale and translation matrix
> operations.
>
> My transform group undoes the scaling and translation that
> the parent transform group does, thus keeping the text
> locked to the screen. This is all done within the controlChanged
> method of the shadow type, which is triggered when the
> projection control matrix is changed.
>
> I have made some minor changes to make the code
> more readable...
>
> public void
> controlChanged(
> ControlEvent theEvent_IN
> )
> {
>
> double [] aTranslation = new double[ 3 ];
> double [] aScale = new double[ 1 ];
>
> // Get the projection matrix from the event and extract the
> // translation into the aTranslation array, and the scale into
> // the aScale array.
>
> getTranslationAndScale_( theEvent_IN, aTranslation, aScale );
>
> // Move the text back to its original location.
>
> Vector3d theTranslationVector = new Vector3d();
>
> theTranslationVector.x = -1 * aTranslation[ 0 ] / aScale[ 0 ];
> theTranslationVector.y = -1 * aTranslation[ 1 ] / aScale[ 0 ];
> theTranslationVector.z = -1 * aTranslation[ 2 ] / aScale[ 0 ];
>
> // Re-scale and set the translation.
>
> Transform3D theTransform = new Transform3D();
> theTransform.set( 1 / aScale[ 0 ], theTranslationVector );
>
> // theTransformGroup_ is a member variable which has
> // been added as a child to the transform group that was
> // passed into the addTextToGroup method.
>
> theTransformGroup_.setTransform( theTransform );
>
> } // MyShadowTupleTypeJ3D.controlChanged()
>
> Ok, so there is my current screen-locking code. I have
> tried to do the following:
>
> Transform3D theTransform = new Transform3D();
> theTransform.set( 1 / aScale[ 0 ] );
>
> this keeps the text size constant, but the text does not
> move as I want it to when I zoom in or out. The scaling
> affects the translation and this is where I get stuck.
> I have tried to "undo" the effects of the scaling on the
> translation but have had no luck.
2. Since you know that:
Transform3D theTransform = new Transform3D();
theTransform.set( 1 / aScale[ 0 ], theTranslationVector );
theTransformGroup_.setTransform( theTransform );
works for fixing the location and size, you might try:
Transform3D theTransform = new Transform3D();
theTransform.set( 1 / aScale[ 0 ], theTranslationVector );
Transform3D scale = new Transform3D();
scale.set( 1 / aScale[ 0 ] );
theTransform.mul(scale);
theTransformGroup_.setTransform( theTransform );
I may have some detail wrong, like the order of multiplying
matrices, but with a few experiments you may get it. When I
write such transform matrix code, I always have to experiment
to get it right.
Cheers,
Bill
----------------------------------------------------------
Bill Hibbard, SSEC, 1225 W. Dayton St., Madison, WI 53706
hibbard@xxxxxxxxxxxxxxxxx 608-263-4427 fax: 608-263-6738
http://www.ssec.wisc.edu/~billh/vis.html