The “vo” package
1. Package description
The “vo” package implements the 3D visualized objects. It contains the following classes:
- EnvObjectFactory
- EvacuationEnvObjectVO
- EvacuationEventVO
- EvacuationHumanAgentVO
- EventFactory
- Skybox
2. Implementing package
To implement the “EnvObjectFactory” class:
- Create a new class inside the “edu.utdallas.mavs.evacuation.visualization.vis3D.vo” package and name it “EnvObjectFactory”.
- Copy the code given below that describes the full implementation of a “EnvObjectFactory” class.
package edu.utdallas.mavs.evacuation.visualization.vis3D.vo; import com.jme3.math.Vector3f; import com.jme3.scene.Spatial; import edu.utdallas.mavs.divas.core.config.VisConfig; import edu.utdallas.mavs.divas.core.sim.common.state.EnvObjectState; import edu.utdallas.mavs.divas.visualization.vis3D.Visualizer3DApplication; import edu.utdallas.mavs.evacuation.simulation.config.EvacuationVisConfig; import edu.utdallas.mavs.evacuation.simulation.config.SkyboxEnum; /** * This class describes a factory for visualized environment objects. */ public class EnvObjectFactory { /** * This is a factory method for visualized environment objects. * * @param state * an environment object state to be factored into a visualized event * @return a spatial associated with the newly created visualized environment object */ public static Spatial createEnvObjectVO(EnvObjectState state) { Spatial envObjModel; SkyboxEnum skybox = VisConfig.getInstance().getCustomProperty(EvacuationVisConfig.SKYBOX); if(skybox.equals(SkyboxEnum.Night_Stars) || VisConfig.getInstance().getCustomProperty(EvacuationVisConfig.SKYBOX).equals(SkyboxEnum.Night_Red)) { envObjModel = Visualizer3DApplication.getInstance().getAssetManager().loadModel(state.getModelName().replace(".j3o", "_night.j3o")); } else { envObjModel = Visualizer3DApplication.getInstance().getAssetManager().loadModel(state.getModelName()); } return envObjModel; } /** * @param modelName The model to get local scale for * @param x Scale X * @param y Scale Y * @param z Scale Z * @return The required local scale for the model */ public static Vector3f getLocalScale(String modelName, float x, float y, float z) { if(modelName.equals("objects/Tree.mesh.j3o")) { return new Vector3f(x * 4, y * 4, z * 4); } return new Vector3f(x, y, z); } }
To implement the “EvacuationEnvObjectVO” class:
- Create a new class inside the “edu.utdallas.mavs.evacuation.visualization.vis3D.vo” package and name it “EvacuationEnvObjectVO”.
- Copy the code given below that describes the full implementation of a “EvacuationEnvObjectVO” class.
package edu.utdallas.mavs.evacuation.visualization.vis3D.vo; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jme3.bounding.BoundingBox; import com.jme3.light.AmbientLight; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapMode; import edu.utdallas.mavs.divas.core.sim.common.state.EnvObjectState; import edu.utdallas.mavs.divas.visualization.vis3D.Visualizer3DApplication; import edu.utdallas.mavs.divas.visualization.vis3D.utils.VisToolbox; import edu.utdallas.mavs.divas.visualization.vis3D.vo.EnvObjectVO; import edu.utdallas.mavs.evacuation.simulation.sim.common.state.DoorObjectState; /** * This class describes a visualized environment object */ public class EvacuationEnvObjectVO extends EnvObjectVO { private final static Logger logger = LoggerFactory.getLogger(EvacuationEnvObjectVO.class); /** * A list conttains the list of environemnet object models names */ protected static List<String> modifiedBoundingBoxList = new ArrayList<>(); // protected Geometry skeleton; // // protected boolean skeletonMade = false; /** * @param state * the VO's environment object state * @param cycle * the cycle of the simulation associated with the environment object state */ public EvacuationEnvObjectVO(EnvObjectState state, long cycle) { super(state, cycle); } /** * Constructs an empty interpolated VO * To be called only for cloning purposes. Not to be called if the VO is to be actually created in the visualization. * * @param state * the VO's environment object state */ public EvacuationEnvObjectVO(EnvObjectState state) { super(state); } @Override public void updateState() { /* * update position and rotation (handled by InterpolatedVO.updateState(vector, quaternion) to enable smooth * motion) */ if(state.getType().equals("door") && state instanceof DoorObjectState && ((DoorObjectState) state).isOpen()) { updateState(state.getPosition().add(new Vector3f(0, state.getScale().y - .5f, 0)), state.getRotation(), new Vector3f(state.getScale().x, .5f, state.getScale().z)); } else if(state.getType().equals("door") && state instanceof DoorObjectState && !((DoorObjectState) state).isOpen()) { updateState(state.getPosition().add(new Vector3f(0, 0, 0)), state.getRotation(), new Vector3f(state.getScale())); } else if(state.getType().equals("door")) // assume open { updateState(state.getPosition().add(new Vector3f(0, 7.5f, 0)), state.getRotation(), new Vector3f(state.getScale().x, .5f, state.getScale().z)); } else { updateState(state.getPosition(), state.getRotation(), state.getScale()); } } /** * Attaches this model geometric form */ @Override protected void attachModel() { setLocalTranslation(state.getPosition()); if(state.getType().equals("floor")) { isLocked = true; } // Attach 3D Models if(state.getType().equals("3DModel")) { attachEnvObjectModel(); } else { attachGeometry(); } } /** * Attaches a 3D model representing this VO */ protected void attachEnvObjectModel() { envObjModel = EnvObjectFactory.createEnvObjectVO(state); float stateX = 1; float stateY = 1; float stateZ = 1; float modelX = ((BoundingBox) envObjModel.getWorldBound()).getXExtent(); float modelY = ((BoundingBox) envObjModel.getWorldBound()).getYExtent(); float modelZ = ((BoundingBox) envObjModel.getWorldBound()).getZExtent(); float x = stateX / modelX; float y = stateY / modelY; float z = stateZ / modelZ; Vector3f localScale = EnvObjectFactory.getLocalScale(state.getModelName(), x, y, z); // If the model is attached before there is no need to update the bounding box because the update is cached if(!modifiedBoundingBoxList.contains(state.getModelName())) { BoundingBox bb = (BoundingBox) envObjModel.getWorldBound(); modifiedBoundingBoxList.add(state.getModelName()); bb.setYExtent(bb.getYExtent() * 2); envObjModel.setModelBound(bb); envObjModel.setLocalScale(localScale); } // If the model is cached then you should multiply the Y scale by 2, otherwise the Y access will be the half else { envObjModel.setLocalScale(localScale.getX(), localScale.getY() * 2, localScale.getZ()); } if(Visualizer3DApplication.getInstance().getVisRootNode() != null) { attachChild(envObjModel); } } /** * Attaches a textured geometry representing this VO */ protected void attachGeometry() { Box box = new Box(new Vector3f(0, 0, 0), 1, 1, 1); Geometry geometry = new Geometry("Box", box); Material material = new Material(getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); try { Texture texture = getAssetManager().loadTexture(TEXTURES_DIR + state.getMaterial() + ".jpg"); if(state.getType().equals("wall")) { texture.setWrap(WrapMode.Repeat); if(state.getScale().getZ() > 5) { box.scaleTextureCoordinates(new Vector2f(state.getScale().getZ() / 2, 2.5f)); } else { box.scaleTextureCoordinates(new Vector2f(state.getScale().getX() / 2, 2.5f)); } } material.setTexture("DiffuseMap", texture); } catch(Exception e) { if(state.getType().equals("door")) { Texture tex1 = getAssetManager().loadTexture(TEXTURES_DIR + "plasterwall.jpg"); material.setTexture("DiffuseMap", tex1); AmbientLight doorLight = VisToolbox.createAmbientLight(ColorRGBA.White.mult(2f)); addLight(doorLight); } else { material = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); material.setColor("Color", ColorRGBA.randomColor()); } } geometry.setMaterial(material); attachChild(geometry); } @Override protected EnvObjectVO createClone(EnvObjectState clone) { return new EvacuationEnvObjectVO(clone); } }
To implement the “EvacuationEventVO” class:
- Create a new class inside the “edu.utdallas.mavs.evacuation.visualization.vis3D.vo” package and name it “EvacuationEventVO”.
- Copy the code given below that describes the full implementation of a “EvacuationEventVO” class.
package edu.utdallas.mavs.evacuation.visualization.vis3D.vo; import com.jme3.scene.Spatial; import edu.utdallas.mavs.divas.core.sim.common.event.EnvEvent; import edu.utdallas.mavs.divas.visualization.vis3D.vo.EventVO; /** * This class represents a visualized event */ public class EvacuationEventVO extends EventVO { /** * Cosntructs a new event VO * * @param event the event state associated with this VO * @param cycle the simulation cycle number associated with this event */ public EvacuationEventVO(EnvEvent event, long cycle) { super(event, cycle); } @Override protected Spatial createEventVO(EnvEvent event) { return EventFactory.createEventVO(event); } }
To implement the “EvacuationHumanAgentVO” class:
- Create a new class inside the “edu.utdallas.mavs.evacuation.visualization.vis3D.vo” package and name it “EvacuationHumanAgentVO”.
- Copy the code given below that describes the full implementation of a “EvacuationHumanAgentVO” class.
package edu.utdallas.mavs.evacuation.visualization.vis3D.vo; import java.util.ArrayList; import java.util.List; import com.jme3.animation.AnimControl; import com.jme3.animation.LoopMode; import com.jme3.light.AmbientLight; import com.jme3.material.Material; import com.jme3.material.RenderState.BlendMode; import com.jme3.math.ColorRGBA; import com.jme3.math.Vector3f; import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.shape.Sphere; import edu.utdallas.mavs.divas.visualization.vis3D.Visualizer3DApplication; import edu.utdallas.mavs.divas.visualization.vis3D.utils.VisToolbox; import edu.utdallas.mavs.divas.visualization.vis3D.vo.AgentVO; import edu.utdallas.mavs.evacuation.simulation.sim.common.state.EHumanAgentState; import edu.utdallas.mavs.evacuation.simulation.sim.common.state.Posture; /** * This class describes a visualized agent */ public class EvacuationHumanAgentVO extends AgentVO<EHumanAgentState> { /** * A ratio constant to correct the mismatch between the 3D models and the simulation entity */ private static final float MODEL_RATIO = 0.55f; /** * The previous posture of this VO */ protected Posture prevPosture = null; /** * The agent path of this VO */ protected List<Geometry> myPath = new ArrayList<Geometry>(); private boolean agentPath = false; private List<Vector3f> lastPath = null; ColorRGBA agentMarkColor; private Geometry idSphere = null; protected Node myRootChild; /** * Creates a new agent VO * * @param state * the agent state to be associated with this VO * @param cycle * the simulation cycle number associated with the agent state */ public EvacuationHumanAgentVO(EHumanAgentState state, long cycle) { super(state, cycle); createIdSphere(); myRootChild = new Node(); AmbientLight agentLight = VisToolbox.createAmbientLight(ColorRGBA.White); addLight(agentLight); } @Override protected float getModelRatio() { return MODEL_RATIO; } protected void createIdSphere() { agentMarkColor = ColorRGBA.randomColor(); agentMarkColor.a = .5f; Sphere sphere = new Sphere(30, 30, 1); idSphere = new Geometry("AgentPathF", sphere); Material mat = new Material(Visualizer3DApplication.getInstance().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); mat.setColor("Color", agentMarkColor); idSphere.setMaterial(mat); idSphere.setQueueBucket(Bucket.Translucent); idSphere.setLocalTranslation(Vector3f.UNIT_Y.mult(7)); } @Override protected void setupAgentModel() { String agentPath = new String(); boolean lqModels = Visualizer3DApplication.getVisConfig().lowQualityModels; boolean animated = Visualizer3DApplication.getVisConfig().animatedModels; if(animated) { agentPath = AGENTS_MODELS_DIR + state.getModelName() + ((lqModels) ? "_lq" : "") + ".j3o"; } else { agentPath = AGENTS_MODELS_DIR + "simple_model" + ".j3o"; } agentModel = getAssetManager().loadModel(agentPath); } /** * Updates this VO's visible properties (e.g., posture, vision cone) */ @Override protected void updateVisibleProperties() { updateAgentPath(); if(Visualizer3DApplication.getVisConfig().animatedModels) { if(prevPosture != state.getPosture()) { for(Posture posture : Posture.values()) { if(state.getPosture() == posture) { channel.setAnim(state.getPosture().toString().toLowerCase()); channel.setLoopMode(isLooping(posture)); } } } } prevPosture = state.getPosture(); if(prevFov != state.getFOV() || prevVisibleDistance != state.getVisibleDistance()) { if(visionConeEnabled) { detachVisionCone(); attachVisionCone(); } } prevFov = state.getFOV(); prevVisibleDistance = state.getVisibleDistance(); } private LoopMode isLooping(Posture posture) { if(posture == Posture.Death_backward || posture == Posture.Death_forward || posture == Posture.sit_g_start) { return LoopMode.DontLoop; } return LoopMode.Loop; } private void updateAgentPath() { if(pathHasChanged(lastPath, state.getAgentPath())) { if(pathIsContinue(lastPath, state.getAgentPath())) { if(myPath != null && myPath.get(0) != null) { myRootChild.detachChild(myPath.remove(0)); } } else { detachAgentPath(); myPath = VisToolbox.createAgentPath(state.getPosition(), state.getAgentPath(), agentMarkColor); attachAgentPath(); } } lastPath = state.getAgentPath(); } private boolean pathIsContinue(List<Vector3f> oldPath, List<Vector3f> newPath) { if(oldPath == null) { return false; } if(oldPath.size() == (newPath.size() + 1)) { for(int i = 0; i < newPath.size(); i++) { if(!newPath.get(i).equals(oldPath.get(i + 1))) { return false; } } } else { return false; } return true; } /** * Attaches the path */ private void checkAgentPath() { // if(agentPath) // { // myRootChild.updateGeometricState(); // } if(Visualizer3DApplication.getInstance().getApp().isDebugMode() && !agentPath) { // attachAgentPath(); Visualizer3DApplication.getInstance().getVisRootNode().attachChild(myRootChild); agentPath = true; attachChild(idSphere); } else if(!Visualizer3DApplication.getInstance().getApp().isDebugMode() && agentPath) { // detachAgentPath(); Visualizer3DApplication.getInstance().getVisRootNode().detachChild(myRootChild); agentPath = false; detachChild(idSphere); } } protected void attachAgentPath() { if(myPath != null) { // agentPath = true; for(Geometry c : myPath) { myRootChild.attachChild(c); } } // if(idSphere != null) // { // attachChild(idSphere); // } } protected void detachAgentPath() { if(myPath != null) { // agentPath = false; for(Geometry g : myPath) { myRootChild.detachChild(g); } } // if(idSphere != null) // { // detachChild(idSphere); // } } @Override protected void setupAnimation() { if(Visualizer3DApplication.getVisConfig().animatedModels) { control = agentModel.getControl(AnimControl.class); channel = control.createChannel(); channel.setAnim((Posture.Walk).toString().toLowerCase()); } } private boolean pathHasChanged(List<Vector3f> lastPath2, List<Vector3f> agentPath2) { if(lastPath2 == null) { return true; } if(lastPath2.size() != agentPath2.size()) { return true; } for(int i = 0; i < lastPath2.size(); i++) { Vector3f last = lastPath2.get(i); Vector3f current = agentPath2.get(i); if(last != null && current != null) { if(!last.equals(current)) { return true; } } else if(last == null && current != null) { return true; } else if(last != null && current == null) { return true; } } return false; } @Override protected void detachSpatial() { detachAgentPath(); Visualizer3DApplication.getInstance().getVisRootNode().detachChild(myRootChild); super.detachSpatial(); } @Override protected void updateSelfObjects() { checkAgentPath(); } }
To implement the “EventFactory” class:
- Create a new class inside the “edu.utdallas.mavs.evacuation.visualization.vis3D.vo” package and name it “EventFactory”.
- Copy the code given below that describes the full implementation of a “EventFactory” class.
package edu.utdallas.mavs.evacuation.visualization.vis3D.vo; import com.jme3.light.AmbientLight; import com.jme3.material.Material; import com.jme3.material.RenderState.BlendMode; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.shape.Dome; import com.jme3.scene.shape.Sphere; import edu.utdallas.mavs.divas.core.sim.common.event.BombEvent; import edu.utdallas.mavs.divas.core.sim.common.event.DrumsEvent; import edu.utdallas.mavs.divas.core.sim.common.event.DynamiteEvent; import edu.utdallas.mavs.divas.core.sim.common.event.EnvEvent; import edu.utdallas.mavs.divas.core.sim.common.event.FireworkEvent; import edu.utdallas.mavs.divas.core.sim.common.event.GrillingFoodEvent; import edu.utdallas.mavs.divas.core.sim.common.event.SirenEvent; import edu.utdallas.mavs.divas.core.sim.common.event.SpotlightEvent; import edu.utdallas.mavs.divas.visualization.vis3D.Visualizer3DApplication; import edu.utdallas.mavs.divas.visualization.vis3D.utils.VisToolbox; import edu.utdallas.mavs.divas.visualization.vis3D.vo.effect.Drum; import edu.utdallas.mavs.divas.visualization.vis3D.vo.effect.Dynamite; import edu.utdallas.mavs.divas.visualization.vis3D.vo.effect.Explosion; import edu.utdallas.mavs.divas.visualization.vis3D.vo.effect.Fireworks; import edu.utdallas.mavs.divas.visualization.vis3D.vo.effect.Grill; import edu.utdallas.mavs.divas.visualization.vis3D.vo.effect.ShockWave; /** * This class describes a factory for visualized events. */ public class EventFactory { /** * This is a factory method for visualized events. * * @param event * an event to be factored into a visualized event * @return a spatial associated with the newly created visualized event */ public static Spatial createEventVO(EnvEvent event) { Spatial vo = null; if(event instanceof FireworkEvent) { vo = createFireworksVO(event); } else if(event instanceof BombEvent) { vo = cretateExplosionVO(event); } else if(event instanceof GrillingFoodEvent) { vo = createGrillVO(event); } else if(event instanceof DrumsEvent) { vo = createDrumsVO(event); } else if(event instanceof SpotlightEvent) { vo = createSpotlight(event); } else if(event instanceof SirenEvent) { vo = createSiren(event); } else if(event instanceof DynamiteEvent) { vo = createDynamite(event); } return vo; } private static Spatial createSpotlight(EnvEvent event) { Node n = new Node(); n.setLocalTranslation(event.getOrigin().add(0, 1.1f, 0)); String path = "objects/" + "light7.mesh" + ".j3o"; Spatial model = Visualizer3DApplication.getInstance().getAssetManager().loadModel(path); model.setLocalScale(.005f); n.attachChild(model); Sphere box1 = new Sphere(50, 50, .4f); Geometry vo = new Geometry("Box", box1); vo.setLocalTranslation(0, 6.2f, .8f); Material mat1 = new Material(Visualizer3DApplication.getInstance().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); mat1.setColor("Color", ColorRGBA.White); mat1.setColor("GlowColor", ColorRGBA.White); vo.setMaterial(mat1); AmbientLight agentLight = VisToolbox.createAmbientLight(ColorRGBA.White); vo.addLight(agentLight); n.attachChild(vo); Dome cone = new Dome(Vector3f.ZERO, 2, 30, 1f, false); Geometry geometry = new Geometry("VisionCone", cone); Material mat = new Material(Visualizer3DApplication.getInstance().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); // mat.setColor("Color", new ColorRGBA(1.0f, 0.2f, 0, alpha)); ColorRGBA visionColor = ColorRGBA.White; mat.setColor("Color", new ColorRGBA(visionColor.r, visionColor.g, visionColor.b, .1f)); mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); mat.getAdditionalRenderState().setDepthWrite(false); geometry.setMaterial(mat); geometry.setQueueBucket(Bucket.Translucent); geometry.setLocalScale(new Vector3f(25, 50, 25)); geometry.rotate(new Quaternion().fromAngleAxis(-FastMath.PI / 2, Vector3f.UNIT_X)); geometry.setLocalTranslation(0, 6.2f, 50); n.attachChild(geometry); cone = new Dome(Vector3f.ZERO, 2, 30, 1f, true); geometry = new Geometry("VisionCone", cone); mat = new Material(Visualizer3DApplication.getInstance().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); // mat.setColor("Color", new ColorRGBA(1.0f, 0.2f, 0, alpha)); visionColor = ColorRGBA.White; mat.setColor("Color", new ColorRGBA(visionColor.r, visionColor.g, visionColor.b, .1f)); mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); mat.getAdditionalRenderState().setDepthWrite(false); geometry.setMaterial(mat); geometry.setQueueBucket(Bucket.Translucent); geometry.setLocalScale(new Vector3f(25, 50, 25)); geometry.rotate(new Quaternion().fromAngleAxis(-FastMath.PI / 2, Vector3f.UNIT_X)); geometry.setLocalTranslation(0, 6.2f, 50); n.attachChild(geometry); return n; } private static Spatial createDrumsVO(EnvEvent event) { Drum vo = new Drum((DrumsEvent) event); return vo; } private static Spatial createGrillVO(EnvEvent event) { Grill vo = new Grill((GrillingFoodEvent) event); return vo; } private static Spatial cretateExplosionVO(EnvEvent event) { Explosion vo = new Explosion((BombEvent) event); event.setIntensity(10f); return vo; } private static Spatial createDynamite(EnvEvent event) { Dynamite vo = new Dynamite((DynamiteEvent) event); event.setIntensity(17f); return vo; } private static Spatial createSiren(EnvEvent event) { ShockWave vo = new ShockWave((SirenEvent) event); return vo; } private static Spatial createFireworksVO(EnvEvent event) { Fireworks vo = new Fireworks(event); event.setIntensity(25f); return vo; } }
To implement the “Skybox” class:
- Create a new class inside the “edu.utdallas.mavs.evacuation.visualization.vis3D.vo” package and name it “Skybox”.
- Copy the code given below that describes the full implementation of a “Skybox” class.
package edu.utdallas.mavs.evacuation.visualization.vis3D.vo; import java.util.concurrent.Callable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jme3.app.Application; import com.jme3.asset.AssetManager; import com.jme3.math.Vector3f; import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.texture.Texture; import com.jme3.util.SkyFactory; import edu.utdallas.mavs.divas.core.config.VisConfig; import edu.utdallas.mavs.divas.visualization.vis3D.BaseApplication; import edu.utdallas.mavs.divas.visualization.vis3D.Visualizer3DApplication; import edu.utdallas.mavs.evacuation.simulation.config.EvacuationVisConfig; import edu.utdallas.mavs.evacuation.simulation.config.SkyboxEnum; /** * This class describes the skybox of the 3D visualization. */ public class Skybox { private final static Logger logger = LoggerFactory.getLogger(Skybox.class); private static Spatial sky; private Skybox() {} /** * Unloads the skybox in the visualization */ public static void unloadSky() { try { Visualizer3DApplication.getInstance().getApp().enqueue(new Callable<Object>() { @Override public Object call() throws Exception { dettachSky(); return null; } }); } catch(Exception e) { e.printStackTrace(); } } private static void dettachSky() { Visualizer3DApplication.getInstance().getApp().getRootNode().detachChild(sky); } /** * Loads the skybox in the visualization */ public static void loadSky() { try { Visualizer3DApplication.getInstance().getApp().enqueue(new Callable<Object>() { @Override public Object call() throws Exception { updateSky(); return null; } }); } catch(Exception e) { e.printStackTrace(); } } private static void updateSky() { Application app = Visualizer3DApplication.getInstance().getApp(); AssetManager assetManager = app.getAssetManager(); SkyboxEnum skyboxName = VisConfig.getInstance().getCustomProperty(EvacuationVisConfig.SKYBOX); String skyboxPath = String.format("skybox/%s/", skyboxName.toString()); try { if(skyboxName.equals(SkyboxEnum.Sunny) || skyboxName.equals(SkyboxEnum.Sunny_Nature) || skyboxName.equals(SkyboxEnum.Cloudy) || skyboxName.equals(SkyboxEnum.Dusk) || skyboxName.equals(SkyboxEnum.Night_Red) || skyboxName.equals(SkyboxEnum.Night_Stars) || skyboxName.equals(SkyboxEnum.Rise) || skyboxName.equals(SkyboxEnum.Sunny_Sea) || skyboxName.equals(SkyboxEnum.Sunset)) { Texture west = assetManager.loadTexture(String.format("%sW.jpg", skyboxPath)); Texture east = assetManager.loadTexture(String.format("%sE.jpg", skyboxPath)); Texture north = assetManager.loadTexture(String.format("%sN.jpg", skyboxPath)); Texture south = assetManager.loadTexture(String.format("%sS.jpg", skyboxPath)); Texture up = assetManager.loadTexture(String.format("%sU.jpg", skyboxPath)); Texture down = assetManager.loadTexture(String.format("%sD.jpg", skyboxPath)); sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ); } else { Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_west.jpg"); Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_east.jpg"); Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_north.jpg"); Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_south.jpg"); Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_up.jpg"); Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_down.jpg"); sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ); } if(sky != null) { sky.setQueueBucket(Bucket.Sky); Node node = ((BaseApplication<?,?>) app).getRootNode(); node.attachChild(sky); } } catch(Exception e) { logger.error("Error occured when loading the skybox."); } } }