499 lines
17 KiB
Java
499 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);
|
||
|
}
|
||
|
}
|
||
|
}
|