csharp_pain/Solar system/sss3d-source/sss3d/contentbranch/SceneSolarSystem.java
2014-06-26 17:13:46 +02:00

498 lines
17 KiB
Java

/*
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.<br>
*
* @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);
}
}
}