// // AnimationRendererJ3D.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 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.java3d; import visad.*; import visad.util.Delay; import javax.media.j3d.*; import java.rmi.*; import java.io.IOException; import java.awt.event.*; import javax.swing.*; import java.util.Vector; public class AnimationRendererJ3D extends DefaultRendererJ3D { boolean animation1D; String nameMappedToAnimation = null; private boolean reUseFrames = false; private boolean setSetOnReUseFrames = true; public ShadowType makeShadowFunctionType( FunctionType type, DataDisplayLink link, ShadowType parent) throws VisADException, RemoteException { return new ShadowAnimationFunctionTypeJ3D(type, link, parent); } public void setReUseFrames(boolean reuse) { reUseFrames = reuse; } public void setReUseFrames() { setReUseFrames(true); } public boolean getReUseFrames() { return reUseFrames; } public void setSetSetOnReUseFrames(boolean ss) { setSetOnReUseFrames = ss; } public boolean getSetSetOnReUseFrames() { return setSetOnReUseFrames; } // logic to 'mark' missing frames private VisADBranchGroup vbranch = null; public void clearScene() { vbranch = null; super.clearScene(); } void setVisADBranch(VisADBranchGroup branch) { vbranch = branch; } void markMissingVisADBranch() { if (vbranch != null) vbranch.scratchTime(); } // end of logic to 'mark' missing frames public BranchGroup doTransform() throws VisADException, RemoteException { BranchGroup branch = getBranch(); if (branch == null) { branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); } DataDisplayLink[] Links = getLinks(); if (Links == null || Links.length == 0) { return null; } DataDisplayLink link = Links[0]; ShadowTypeJ3D type = (ShadowTypeJ3D) link.getShadow(); // initialize valueArray to missing int valueArrayLength = getDisplay().getValueArrayLength(); float[] valueArray = new float[valueArrayLength]; for (int i=0; i<valueArrayLength; i++) { valueArray[i] = Float.NaN; } Data data; try { data = link.getData(); } catch (RemoteException re) { if (visad.collab.CollabUtil.isDisconnectException(re)) { getDisplay().connectionFailed(this, link); removeLink(link); return null; } throw re; } if (data == null) { branch = null; addException( new DisplayException("Data is null: AnimationRendererJ3D.doTransform")); } else { animation1D = false; MathType mtype = link.getType(); if (mtype instanceof FunctionType) { FunctionType function = (FunctionType) mtype; RealTupleType functionD = function.getDomain(); Vector scalarMaps = link.getSelectedMapVector(); for (int kk = 0; kk < scalarMaps.size(); kk++) { ScalarMap scalar_map = (ScalarMap)scalarMaps.elementAt(kk); String scalar_name = scalar_map.getScalarName(); if (scalar_name.equals(((RealType)functionD.getComponent(0)).getName())) { if (((scalar_map.getDisplayScalar()).equals(Display.Animation))&& (functionD.getDimension() == 1)) { animation1D = true; nameMappedToAnimation = scalar_name; } } } } link.start_time = System.currentTimeMillis(); link.time_flag = false; vbranch = null; if (!animation1D) { // TDR, 3-2003: // make sure branch not live for default logic, ie. super.doTransform() branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); } // transform data into a depiction under branch try { type.doTransform(branch, data, valueArray, link.getDefaultValues(), this); } catch (RemoteException re) { if (visad.collab.CollabUtil.isDisconnectException(re)) { getDisplay().connectionFailed(this, link); removeLink(link); return null; } throw re; } } link.clearData(); return branch; } public Object clone() { return new AnimationRendererJ3D(); } public static void main(String args[]) throws VisADException, RemoteException, IOException { String test = "new"; if (args.length > 0) { test = args[0]; if (!(test.equals("new") || test.equals("old"))) { System.out.println("arg must be 'old' or 'new'"); System.exit(0); } } int size = 80; int nr = size; int nc = size; int nz = size; double ang = 2*Math.PI/nr; RealType[] types = {RealType.Latitude, RealType.Longitude, RealType.Altitude}; RealTupleType earth_location = new RealTupleType(types); RealType radiance = RealType.getRealType("radiance", null, null); RealType index = RealType.getRealType("index", null, null); FunctionType image_type = new FunctionType(earth_location, radiance); Integer3DSet image_domain_set = new Integer3DSet(RealTupleType.SpatialCartesian3DTuple, nr, nc, nz); FunctionType field_type = new FunctionType(index, image_type); Integer1DSet field_domain_set = new Integer1DSet(index, 6); FieldImpl field = new FieldImpl(field_type, field_domain_set); for (int tt = 0; tt < field_domain_set.getLength(); tt++) { float[][] values = new float[1][nr*nc*nz]; for ( int kk = 0; kk < nz; kk++) { for ( int jj = 0; jj < nc; jj++ ) { for ( int ii = 0; ii < nr; ii++ ) { int idx = kk*nr*nc + jj*nr + ii; values[0][idx] = (tt+1)*(2f*((float)Math.sin(2*ang*ii)) + 2f*((float)Math.sin(2*ang*jj))) + kk; } } } FlatField image = new FlatField(image_type, image_domain_set); image.setSamples(values); field.setSample(tt, image, false); } DisplayImplJ3D dpys = new DisplayImplJ3D("AnimationRendererJ3D Test"); JFrame jframe = new JFrame("AnimationRendererTest"); jframe.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); jframe.setContentPane((JPanel) dpys.getComponent()); jframe.pack(); jframe.setVisible(true); ScalarMap xmap = new ScalarMap(RealType.Longitude, Display.XAxis); dpys.addMap(xmap); ScalarMap ymap = new ScalarMap(RealType.Latitude, Display.YAxis); dpys.addMap(ymap); ScalarMap zmap = new ScalarMap(RealType.Altitude, Display.ZAxis); dpys.addMap(zmap); ScalarMap rgbaMap = new ScalarMap(radiance, Display.RGBA); //-ScalarMap rgbaMap = new ScalarMap(RealType.Altitude, Display.RGBA); dpys.addMap(rgbaMap); ScalarMap amap = new ScalarMap(index, Display.Animation); dpys.addMap(amap); ScalarMap map1contour = new ScalarMap(radiance, Display.IsoContour); dpys.addMap(map1contour); ContourControl ctr_cntrl = (ContourControl) map1contour.getControl(); ctr_cntrl.setSurfaceValue(24f); AnimationControl acontrol = (AnimationControl) amap.getControl(); acontrol.setOn(false); acontrol.setStep(1000); DataReferenceImpl ref = new DataReferenceImpl("field_ref"); ref.setData(field); AnimationRendererJ3D renderer = new AnimationRendererJ3D(); renderer.setReUseFrames(true); if (test.equals("old")) { dpys.addReference(ref); } else { dpys.addReferences(renderer, new DataReferenceImpl[] {ref}, null); } System.out.println("replace test in 40 sec..."); new Delay(50000); Linear1DSet new_set = new Linear1DSet(index, 1, 6, 6); FieldImpl new_field = new FieldImpl(field_type, new_set); for (int i=0; i<field_domain_set.getLength(); i++) { new_field.setSample(i, field.getSample((i + 1) % field_domain_set.getLength())); } if (test.equals("old")) { dpys.reAutoScale(); } System.out.println("replace test start"); ref.setData(new_field); } }