/* File: SceneSolarSystem.java University of Applied Science Berne,HTA-Biel/Bienne, Computer Science Department. Diploma thesis J3D Solar System Simulator Originally written by Marcel Portner & Bernhard Hari (c) 2000 CVS - Information : $Header: /var/cvsreps/projects/c450/2000/sss3d/source_diploma/sss3d/contentbranch/SceneSolarSystem.java,v 1.21 2000/12/15 02:54:45 portm Exp $ $Author: portm $ $Date: 2000/12/15 02:54:45 $ $State: Exp $ */ package sss3d.contentbranch; import sss3d.contentbranch.SceneCelestialObjects; import sss3d.contentbranch.rockets.*; import sss3d.contentbranch.planets.*; import sss3d.contentbranch.moons.*; import sss3d.contentbranch.orbit.*; import sss3d.contentbranch.sun.*; import sss3d.contentbranch.comets.*; import sss3d.gui.LoaderBar; import sss3d.utils.observer.*; import sss3d.utils.SSS3dConstants; import sss3d.utils.xmlparser.XMLConstants; import sss3d.SolarSystemSimulator; import sss3d.gui.LoaderBar; import java.util.Enumeration; import java.util.Hashtable; import javax.media.j3d.*; import javax.vecmath.*; /** * This class describe the scene of the solar system. * * @author Marcel Portner & Bernhard Hari * @version $Revision: 1.21 $ */ public class SceneSolarSystem implements InfoObserver { private BranchGroup brGrAll; private BranchGroup[] brGrSSS; private int nbOfObjects; private Hashtable celestial; private String cameraName = "null"; private boolean firstTime = true; private SceneCelestialObjects[] lnkSceneCelestialObjects; private Canvas3D canvas3D; private ObjectsPositions objPos; private ObjectsInformation objInfo; private InitializationObject iniObject; private SolarSystemSimulator sss3d; private Background backGr; private NewTextureLoader newTextureLoader; /** * Initializes a new SceneSolarSystem. * * @param canvas3D the active Canvas3D. * @param objPos a reference to the concrete subject of * the observer pattern positions * @param objInfo a reference to the concrete subject of * the observer pattern information */ public SceneSolarSystem(Canvas3D canvas3D, ObjectsPositions objPos, ObjectsInformation objInfo, SolarSystemSimulator sss3d) { this.objInfo = objInfo; this.objInfo.attach(this); this.canvas3D = canvas3D; this.objPos = objPos; this.sss3d = sss3d; iniObject = objInfo.getInitializationObject(); } /** * Returns the BranchGroup of the created scene. * It has the whole solar system. * * @return the BranchGroup of the scene. */ public BranchGroup createSceneGraph() { // do some initialization the first time only if ( firstTime ) { Enumeration cObjects = iniObject.getObjects(); celestial = new Hashtable(); int i = 0; while(cObjects.hasMoreElements()) { IniData dataStructure = (IniData)cObjects.nextElement(); celestial.put(dataStructure.getName(), new Integer(i++)); } nbOfObjects = celestial.size(); firstTime = false; } lnkSceneCelestialObjects = new SceneCelestialObjects[nbOfObjects]; System.out.println("SceneSolarSystem.createSceneGraph()"); brGrAll = new BranchGroup(); brGrAll.setCapability(BranchGroup.ALLOW_DETACH); brGrAll.setCapability(Group.ALLOW_CHILDREN_READ); brGrAll.setCapability(Group.ALLOW_CHILDREN_WRITE); brGrAll.setCapability(Group.ALLOW_CHILDREN_EXTEND); // A BoundingSphere instance as general bounding region. BoundingSphere boundsGen = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), SSS3dConstants.BOUNDRADIUS); // Background setting for the Solar System Simulator. newTextureLoader = new NewTextureLoader("images/bg.jpg"); backGr = new Background(); backGr.setCapability(backGr.ALLOW_IMAGE_WRITE); backGr.setApplicationBounds(boundsGen); brGrAll.addChild(backGr); // Create and attach an ambient light. Color3f ambColor = new Color3f(0.2f, 0.2f, 0.2f); AmbientLight ambLight = new AmbientLight(ambColor); ambLight.setInfluencingBounds(boundsGen); brGrAll.addChild(ambLight); // Create and attach a point light. Color3f pointColor = new Color3f(1.0f, 1.0f, 1.0f); Point3f pointPos = new Point3f(0.0f, 0.0f, 0.0f); Point3f pointAtt = new Point3f(1.0f, 0.0f, 0.0f); PointLight pointLight = new PointLight(pointColor, pointPos, pointAtt); pointLight.setInfluencingBounds(boundsGen); brGrAll.addChild(pointLight); brGrSSS = new BranchGroup[nbOfObjects]; LoaderBar loader = new LoaderBar(nbOfObjects, sss3d); int i = 0; Enumeration ini = iniObject.getObjects(); while(ini.hasMoreElements()) { IniData dataStructure = (IniData)ini.nextElement(); i = ((Integer)celestial.get(dataStructure.getName())).intValue(); loader.setCount(i); loader.setNote(dataStructure.getName()); switch(dataStructure.getType()) { case SSS3dConstants.STAR_TYPE : // Create the sun. lnkSceneCelestialObjects[i] = new SceneSun(new Sun(dataStructure.getName()), objPos, objInfo); break; case SSS3dConstants.PLANET_TYPE : // Create the current planet with his orbit. lnkSceneCelestialObjects[i] = new ScenePlanet(new Planet(dataStructure.getName()), objPos, objInfo); break; case SSS3dConstants.MOON_TYPE : // Create the current moon with his orbit. lnkSceneCelestialObjects[i] = new SceneMoon(new Moon(dataStructure.getName()), objPos, objInfo); break; case SSS3dConstants.COMET_TYPE : // Create the current moon with his orbit. lnkSceneCelestialObjects[i] = new SceneComet(new Comet(dataStructure.getName()), objPos, objInfo); break; // for later use /* case SSS3dConstants.SATELLITE_TYPE : // Create the current moon with his orbit. lnkSceneCelestialObjects[i] = new SceneSatellite(new Satellite(dataStructure.getName()), objPos, objInfo); break; */ case SSS3dConstants.ROCKET_TYPE : // Create the rocket or a space ship lnkSceneCelestialObjects[i] = new SceneRocket(new Rocket(dataStructure.getName()), objPos, objInfo); break; default: System.out.println("SceneSolarSystem: the used type is not defined"); } brGrSSS[i] = lnkSceneCelestialObjects[i].createSceneGraph(); brGrSSS[i].setCapability(BranchGroup.ALLOW_CHILDREN_READ); brGrAll.addChild(brGrSSS[i]); if(!dataStructure.hasCoordinateSystem()) { lnkSceneCelestialObjects[i].removeCoord(); } lnkSceneCelestialObjects[i].setOrbitColor(dataStructure.getColorOrbit()); if(!dataStructure.hasOrbit()) { lnkSceneCelestialObjects[i].removeOrbit(); } if(!dataStructure.isVisible()) { brGrSSS[i].detach(); } } // destroy the loader loader.dispose(); // Now create the simple picking behavior. brGrAll.setCapability(Node.ENABLE_PICK_REPORTING); brGrAll.setCapability(Node.ALLOW_PICKABLE_READ); PickingBehavior pickBehavior = new PickingBehavior(brGrAll, canvas3D, boundsGen, objInfo); // Compile the subgraph to optimize the performances. brGrAll.compile(); setAnimationSpeed(); // Return the final version of the BranchGroup node brGrSSS return brGrAll; } /** * Reloads the whole scene. * It's necessary to reload the whole scene after the user * changes the simulation start date at runtime. */ public void reloadScene() { // destroy each scene for( int i = 0; i < lnkSceneCelestialObjects.length; i++) { lnkSceneCelestialObjects[i].destroy(); lnkSceneCelestialObjects[i] = null; } lnkSceneCelestialObjects = null; // remove all children for( int i = 0; i < brGrSSS.length ; i++) { brGrSSS[i].detach(); brGrSSS[i] = null; } // removes the root branch group sss3d.removeScene(brGrAll); brGrAll = null; // run garbage collector System.gc(); // creates new scene sss3d.addScene(createSceneGraph()); } /** * Returns the celestial object. * * @param name * * @return SceneCelestialObjects */ public SceneCelestialObjects getCelestial(String name) { int i = ((Integer)celestial.get(name)).intValue(); return lnkSceneCelestialObjects[i]; } /** * This method handle the animation and rotation for each planet. * * @param animate if true, start animation; if false stop animation. * @param rotate if true, start rotation; if false stop rotation. */ public void setAnimation(boolean animate, boolean rotate) { for(int i = 0; i < nbOfObjects; i++) { lnkSceneCelestialObjects[i].setAnimation(animate, rotate); } } /** * Set the background in the canvas3D. * * @param hasImage if true, it would have an image; if false the * background is black. */ public void setBackground(boolean hasImage) { if(hasImage) { backGr.setImage(newTextureLoader.getImage()); } else { backGr.setImage(null); } } /** * Set the coordinate system of the celestial objects. * * @param hasCoord if true, it would have a coordinate system; if false * it has no one. */ public void setCoordinate(boolean hasCoord) { int i = 0; Enumeration ini = iniObject.getObjects(); while(ini.hasMoreElements()) { IniData dataStructure = (IniData)ini.nextElement(); if(hasCoord) { boolean hasYetCoord = ((Boolean)iniObject.getParameter(XMLConstants.COORDINATESYSTEM, dataStructure.getName())).booleanValue(); if(!hasYetCoord) { lnkSceneCelestialObjects[i].addCoord(); } } else { lnkSceneCelestialObjects[i].removeCoord(); } iniObject.setParameter(new Boolean(hasCoord), XMLConstants.COORDINATESYSTEM, dataStructure.getName()); i++; } } /** * Set the orbit of the celestial objects. * * @param hasOrbit if true, it would have a orbit; if false * it has no one. */ public void setOrbit(boolean hasOrbit) { int i = 0; Enumeration ini = iniObject.getObjects(); while(ini.hasMoreElements()) { IniData dataStructure = (IniData)ini.nextElement(); if(hasOrbit) { boolean hasYetOrbit = ((Boolean)iniObject.getParameter(XMLConstants.ORBIT, dataStructure.getName())).booleanValue(); if(!hasYetOrbit) { lnkSceneCelestialObjects[i].addOrbit(); } } else { lnkSceneCelestialObjects[i].removeOrbit(); } iniObject.setParameter(new Boolean(hasOrbit), XMLConstants.ORBIT, dataStructure.getName()); i++; } } /** * Returns the current position of an celestial object - * selected by the camera position * * @return a Transform3D . */ public Transform3D getCurrentPosition() { Integer cameraNr = (Integer)iniObject.getParameter(XMLConstants.CAMERA); if(!cameraName.equals(SSS3dConstants.CAMERA_POSITIONS[cameraNr.intValue()])) { cameraName = SSS3dConstants.CAMERA_POSITIONS[cameraNr.intValue()]; System.out.println(cameraName); sss3d.lnkViewBranch.setStartPosition(); } if(cameraName.equals(SSS3dConstants.CAMERA_POSITIONS[SSS3dConstants.CAMERA_DEFAULT])) { return null; } else { int i = ((Integer)celestial.get(cameraName.toLowerCase())).intValue(); if ( lnkSceneCelestialObjects != null ) { if ( lnkSceneCelestialObjects[i] != null ) { return lnkSceneCelestialObjects[i].getCurrentPosition(); }else { return null; } } return null; } } /** * The update methode is used to keep the state of the concrete observer * consistent with the state of the ObjectInfo.
* * @param objInfo a reference to the ObjectInfo * @param id the id of the concrete object that has to be updated */ public void update(String id, int parameter) { switch(parameter) { case XMLConstants.ANIMATIONSPEED: AnimationSpeed animationSpeed = (AnimationSpeed)iniObject.getParameter(parameter); int factor = 0; switch(animationSpeed.getType()) { case AnimationSpeed.DAYS_PER_SECOND: factor = 1; break; case AnimationSpeed.HOURS_PER_SECOND: factor = 24; break; case AnimationSpeed.MINUTES_PER_SECOND: factor = 24 * 60; break; default: } int animSpeed = animationSpeed.getValue(); if(sss3d.infoPanel != null) { sss3d.infoPanel.setStep((double)animSpeed / (double)factor); } break; case XMLConstants.DAY: case XMLConstants.MONTH: case XMLConstants.YEAR: case XMLConstants.HOUR: case XMLConstants.MINUTES: case XMLConstants.SECONDS: case XMLConstants.JDAY: double date = ((Double)iniObject.getParameter(XMLConstants.JDAY)).doubleValue(); if(sss3d.infoPanel != null) { sss3d.infoPanel.setDate(date); } break; case XMLConstants.VISIBLE: Enumeration ini = iniObject.getObjects(); while(ini.hasMoreElements()) { IniData dataStructure = (IniData)ini.nextElement(); if(dataStructure.getName().equals(id) ) { int i = ((Integer)celestial.get(id)).intValue(); if(!dataStructure.isVisible()) { brGrSSS[i].detach(); } else { brGrAll.addChild(brGrSSS[i]); } } } break; case SSS3dConstants.RELOAD : reloadScene(); break; default: } } /** * Returns the id of the concrete observer. * * @return String the id of the concrete observer */ public String getId() { return "scenesolarsystem"; } /** * Returns the information object from the concrete observer. * ( not used - returns always null ) * * @return CelestialObjectInfo the info object from the concrete observer */ public CelestialObjectInfo getInfo() { return null; } private void setAnimationSpeed() { for(int i = 0; i < nbOfObjects; i++) { lnkSceneCelestialObjects[i].setAnimSpeed(); } AnimationSpeed animationSpeed = (AnimationSpeed)iniObject.getParameter(XMLConstants.ANIMATIONSPEED); int factor = 0; switch(animationSpeed.getType()) { case AnimationSpeed.DAYS_PER_SECOND: factor = 1; break; case AnimationSpeed.HOURS_PER_SECOND: factor = 24; break; case AnimationSpeed.MINUTES_PER_SECOND: factor = 24 * 60; break; default: } int animSpeed = animationSpeed.getValue(); if(sss3d.infoPanel != null) { sss3d.infoPanel.setStep((double)animSpeed / (double)factor); } } }