/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.app.heatbugs3d;
import sim.engine.*;
import sim.display.*;
import sim.display3d.*;
import sim.portrayal3d.*;
import sim.portrayal3d.simple.*;
import sim.portrayal3d.grid.*;
import sim.portrayal3d.grid.quad.*;
import sim.app.heatbugs.*;
import sim.util.gui.*;
import java.awt.*;
import javax.swing.*;
/**
* @author Gabriel Catalin Balan
*
* This is a HeatBugs view.
* -the bugs can be displayed STACKED or CLASSIC way (only one shown
* when more on top of one another).
* -the heat is both color and altitude coded. You can turn off
* altitudes by using NOZ.
*/
public class HeatBugs3DWithUI extends GUIState
{
public JFrame displayFrame;
public static final int CLASSIC = 0;
public static final int STACKED = 1;
public static final int TILE = 0;
public static final int MESH = 1;
public static final int NOZ = 2;
int heatmode = MESH;
ValueGrid2DPortrayal3D heatPortrayal = new ValueGrid2DPortrayal3D();
FieldPortrayal3D bugPortrayal = null;
QuadPortrayal quadP = null;
public static void main(String[] args)
{
HeatBugs3DWithUI heatbugs =
new HeatBugs3DWithUI( new HeatBugs( System.currentTimeMillis(),
100,100,100),
HeatBugs3DWithUI.STACKED,
// HeatBugs3DWithUI.CLASSIC,
// HeatBugs3DWithUI.TILE);
// HeatBugs3DWithUI.NOZ);
HeatBugs3DWithUI.MESH);
Console c = new Console(heatbugs);
c.setVisible(true);
}
public HeatBugs3DWithUI()
{
this(new HeatBugs(System.currentTimeMillis()), STACKED, MESH);
}
public HeatBugs3DWithUI(SimState state, final int bugmode, final int heatmode)
{
super(state);
this.heatmode = heatmode;
// Here we define the bugPortrayal so it can be attached in init(). Otherwise
// if we defined it in start(), we'd have to detatch the bugPortrayal and reattach
// a new one, which is kinda dorky.
//
// The particular heatmode can be done in start() without any trouble.
if (bugmode == STACKED)
bugPortrayal = new SparseGrid2DPortrayal3D();
else // if bugmode == CLASSIC
bugPortrayal = new SparseGridPortrayal3D();
}
public static String getName()
{
return "3D HeatBugs";
}
public void start()
{
super.start();
setupPortrayals();
}
public void load(SimState state)
{
super.load(state);
// we now have new grids. Set up the portrayals to reflect that
setupPortrayals();
}
public void setupPortrayals()
{
// display.destroySceneGraph();
// determine
SimpleColorMap cm = new SimpleColorMap();
cm.setLevels(0.0,HeatBugs.MAX_HEAT,Color.blue,Color.red);
// specify that the "bugs" are going to be cones pointing straight up.
TransformedPortrayal3D p = new TransformedPortrayal3D(new ConePortrayal3D());
p.rotateX(90.0);
bugPortrayal.setPortrayalForAll(p);
// the heat can be tiles, meshes, or tiles with no change in height (NOZ).
// Specify which one here.
switch(heatmode)
{
case TILE : quadP = new TilePortrayal(cm, 1f/2000); break;
case MESH : quadP = new MeshPortrayal(cm, 1f/2000); break;
case NOZ :
quadP = new TilePortrayal(cm); // no height changes, but we need to raise the bugs a little bit
bugPortrayal.translate(0,0,1.0f);
break;
default:
throw new RuntimeException("default case should never occur");
}
heatPortrayal.setPortrayalForAll(quadP);
// With this line we can tell the bug portrayal to use two triangles rather than
// a rect to draw each cell. See the documentation for ValueGrid2DPortrayal3D for
// why this would be useful and when it is not.
// heatPortrayal.setUsingTriangles(true);
heatPortrayal.setField(((HeatBugs)state).valgrid);
bugPortrayal.setField(((HeatBugs)state).buggrid);
// reschedule the displayer
display.reset();
// rebuild the scene graph
display.createSceneGraph();
}
public Display3D display;
public void init(Controller c)
{
super.init(c);
// Make the Display3D. We'll have it display stuff later.
display = new Display3D(600,600,this);
// attach the portrayals to the displayer, from bottom to top
display.attach(heatPortrayal,"Heat");
display.attach(bugPortrayal, "Bugs");
heatPortrayal.setValueName("Heat");
HeatBugs hbState = (HeatBugs)state;
// center the bug graph. Right now it's located at the (0,0) position. For
// example, if it's a 5x5 graph, and the origin is at (0,0), we want to move it
// to (2,2). So we want it to be at ( (5-1)/2 = 2, (5-1/2) = 2 ). Similarly,
// if it's a 6x6 graph we want the origin to be at (2.5, 2.5), dead center between
// the (2,2) and (3,3) grid positions. To center
// the origin there, we need to move the graph in the opposite direction.
// so the general equation for each dimension: (numGridPoints - 1) / -2.0.
display.translate((hbState.gridWidth - 1)/-2.0, (hbState.gridHeight - 1)/-2.0, 0);
// now let's scale it so it fits inside a 1x1x1 cube centered at the origin. We don't
// have to, but it'll look nicer.
display.scale(1.0/Math.max(hbState.gridWidth,hbState.gridHeight));
displayFrame = display.createFrame();
c.registerFrame(displayFrame); // register the frame so it appears in the "Display" list
displayFrame.setVisible(true);
}
public void quit()
{
super.quit();
if (displayFrame!=null) displayFrame.dispose();
displayFrame = null;
display = null;
}
}