All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sim.portrayal3d.grid.ObjectGridPortrayal3D Maven / Gradle / Ivy

Go to download

MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.

The newest version!
/*
  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.portrayal3d.grid;
import sim.portrayal3d.*;
import sim.portrayal.*;
import sim.portrayal.grid.*;
import sim.field.grid.*;
import sim.util.*;
import java.util.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.picking.*;

/** Portrays ObjectGrid2D and ObjectGrid3D in 3D space. A (0,0) or (0,0,0) object is centered
 * on the origin.  2D fields are spread through the XY plane and are presumed to have Z=0. 
 *
 * 

You should be aware that ObjectGrid3DPortrayal3D is slow, especially if objects change * a lot at given locations. This is because it has to update * all the objects on a per location basis rather than on a per object basis. * This is a worst-case scenario for Java3D. * *

Note for Java3D users: We experimented with a number of approaches to dealing with this. * One approach was to use shared groups and only portray an object once, then use links to draw * it in many locations. This has two subapproaches: you can wrap the link in a BranchGroup and * replace it and the BranchGroup when the object changes at that location; or you can just change * the link directly. The first approach is very slow (building BranchGroups isn't efficient). * The second approach has promise, but there are grievous bugs in Java3D's handling of links * which generate all sorts of race conditions with array bounds exceptions and null pointer exceptions * etc. internal to Java3D when you change the SharedGroup that a link is pointing to. Ultimately * we just gave up and used BranchGroups wrapping whole new submodels, entire copies for each * location. Memory inefficient, but it's the fastest method we have figured out which doesn't * break with stupid Sun bugs. It's also fairly simple to grok. Sorry. */ public class ObjectGridPortrayal3D extends FieldPortrayal3D { protected TransformGroup createModel() { TransformGroup globalTG = new TransformGroup(); globalTG.setCapability(TransformGroup.ALLOW_CHILDREN_READ); // we need a group to stick stuff into, so we create a Group here Group global = new Group(); global.setCapability(Group.ALLOW_CHILDREN_READ); global.setCapability(Group.ALLOW_CHILDREN_WRITE); global.setCapability(Group.ALLOW_CHILDREN_EXTEND); global.setUserData(this); // a sufficient tag -- a Group containing me. See LocationWrapper // this is set so he'll be in the scenegraph path global.setCapability(Group.ENABLE_PICK_REPORTING); globalTG.addChild(global); if (field==null) return globalTG; Transform3D tmpLocalT = new Transform3D(); if (field instanceof ObjectGrid2D) { Object[][] grid = ((ObjectGrid2D)field).field; for(int x=0;x 0) originalTransformGroup = (TransformGroup)(bg.getChild(0)); // could be null if we've stubbed TransformGroup newTransformGroup = null; Object originalData = bg.getUserData(); if (originalData == o) { newTransformGroup = p3d.getModel(o, originalTransformGroup); } else { Bag b = (Bag)(models.get(o)); if (b!=null && b.numObjs > 0) { // yay, we can reuse an existing model BranchGroup replacementBranchGroup = (BranchGroup)(b.remove(0)); originalTransformGroup = (TransformGroup)(replacementBranchGroup.getChild(0)); newTransformGroup = p3d.getModel(o,originalTransformGroup); if (newTransformGroup == originalTransformGroup) // we can stick the BranchGroup in global.setChild(replacementBranchGroup,count-1); } else // shoot, we have to create a new model. Rebuild. newTransformGroup = p3d.getModel(o, null); } // is the new transformGroup different? if (newTransformGroup != originalTransformGroup) { // dang! newTransformGroup.setCapability(TransformGroup.ALLOW_CHILDREN_READ); newTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); newTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); // this is set so he'll be in the scenegraph path newTransformGroup.setCapability(TransformGroup.ENABLE_PICK_REPORTING); BranchGroup bg2 = new BranchGroup(); bg2.setCapability(BranchGroup.ALLOW_CHILDREN_READ); bg2.setCapability(BranchGroup.ALLOW_DETACH); // this is set so he'll be in the scenegraph path bg2.setCapability(BranchGroup.ENABLE_PICK_REPORTING); tmpLocalT.setTranslation(new Vector3d(x,y,0)); newTransformGroup.setTransform(tmpLocalT); newTransformGroup.setUserData(new Int2D(x,y)); bg2.addChild(newTransformGroup); bg2.setUserData(o); global.setChild(bg2,count-1); // add old BranchGroup to the hashmap Bag b = (Bag)(models.get(originalData)); if (b==null) { b = new Bag(); models.put(originalData,b); } b.add(bg); } } } } else // field instanceof ObjectGrid3D { Object[][][] grid = ((ObjectGrid3D)field).field; for(int x=0;x 0) originalTransformGroup = (TransformGroup)(bg.getChild(0)); // could be null if we've stubbed TransformGroup newTransformGroup = null; Object originalData = bg.getUserData(); if (originalData == o) { newTransformGroup = p3d.getModel(o, originalTransformGroup); } else { Bag b = (Bag)(models.get(o)); if (b!=null && b.numObjs > 0) { // yay, we can reuse an existing model BranchGroup replacementBranchGroup = (BranchGroup)(b.remove(0)); originalTransformGroup = (TransformGroup)(replacementBranchGroup.getChild(0)); newTransformGroup = p3d.getModel(o,originalTransformGroup); if (newTransformGroup == originalTransformGroup) // we can stick the BranchGroup in global.setChild(replacementBranchGroup,count-1); } else { // shoot, we have to create a new model. Rebuild. newTransformGroup = p3d.getModel(o, null); } } // is the new transformGroup different? if (newTransformGroup != originalTransformGroup) { // dang! newTransformGroup.setCapability(TransformGroup.ALLOW_CHILDREN_READ); newTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); newTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); // this is set so he'll be in the scenegraph path newTransformGroup.setCapability(TransformGroup.ENABLE_PICK_REPORTING); BranchGroup bg2 = new BranchGroup(); bg2.setCapability(BranchGroup.ALLOW_CHILDREN_READ); bg2.setCapability(BranchGroup.ALLOW_DETACH); // this is set so he'll be in the scenegraph path bg2.setCapability(BranchGroup.ENABLE_PICK_REPORTING); tmpLocalT.setTranslation(new Vector3d(x,y,z)); newTransformGroup.setTransform(tmpLocalT); newTransformGroup.setUserData(new Int3D(x,y,z)); bg2.addChild(newTransformGroup); bg2.setUserData(o); global.setChild(bg2,count-1); // add old BranchGroup to the hashmap Bag b = (Bag)(models.get(originalData)); if (b==null) { b = new Bag(); models.put(originalData,b); } b.add(bg); } } } } } } public void setField(Object field) { if (field instanceof ObjectGrid3D || field instanceof ObjectGrid2D) super.setField(field); else throw new RuntimeException("Invalid field for ObjectGridPortrayal3D: " + field); } // searches for an object within a short distance of a location final static int SEARCH_DISTANCE = 2; final static int BAG_SIZE = (SEARCH_DISTANCE * 2 + 1) * (SEARCH_DISTANCE * 2 + 1) * (SEARCH_DISTANCE * 2 + 1); // 125 IntBag xPos = new IntBag(BAG_SIZE); IntBag yPos = new IntBag(BAG_SIZE); IntBag zPos = new IntBag(BAG_SIZE); Int3D searchForObject(Object object, Int3D loc) { ObjectGrid3D field = (ObjectGrid3D)(this.field); Object[][][] grid = field.field; if (grid[loc.x][loc.y][loc.z] == object) return new Int3D(loc.x, loc.y, loc.z); //field.getNeighborsMaxDistance(loc.x, loc.y, loc.z, SEARCH_DISTANCE, true, xPos, yPos, zPos); field.getMooreLocations(loc.x, loc.y, loc.z, SEARCH_DISTANCE, Grid2D.TOROIDAL, true, xPos, yPos, yPos); // we include the origin but it doesn't matter for(int i=0;i





© 2015 - 2025 Weber Informatics LLC | Privacy Policy