467 lines
16 KiB
Java
467 lines
16 KiB
Java
|
/*
|
||
|
File: ScenePlanet.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/planets/ScenePlanet.java,v 1.18 2000/12/15 02:53:25 portm Exp $
|
||
|
$Author: portm $
|
||
|
$Date: 2000/12/15 02:53:25 $
|
||
|
$State: Exp $
|
||
|
|
||
|
*/
|
||
|
package sss3d.contentbranch.planets;
|
||
|
|
||
|
import sss3d.contentbranch.*;
|
||
|
import sss3d.utils.SSS3dConstants;
|
||
|
import sss3d.utils.observer.*;
|
||
|
import sss3d.contentbranch.orbit.*;
|
||
|
import sss3d.utils.xmlparser.XMLConstants;
|
||
|
|
||
|
import javax.media.j3d.*;
|
||
|
import javax.vecmath.*;
|
||
|
import com.sun.j3d.utils.behaviors.interpolators.*;
|
||
|
import java.util.Date;
|
||
|
import java.awt.Color;
|
||
|
|
||
|
/**
|
||
|
* This class describe the scene of a planet.
|
||
|
*
|
||
|
* @author Marcel Portner & Bernhard Hari
|
||
|
* @version $Revision: 1.18 $
|
||
|
* @see Planet
|
||
|
*/
|
||
|
public class ScenePlanet implements SceneCelestialObjects, PositionObserver, InfoObserver {
|
||
|
|
||
|
private RotPosScaleTCBSplinePathInterpolator spline;
|
||
|
|
||
|
private RotationInterpolator rotator;
|
||
|
private Alpha rotationAlpha;
|
||
|
private Alpha animAlpha;
|
||
|
private long alphaTime = 0;
|
||
|
private Date date;
|
||
|
|
||
|
private BranchGroup removableCoordBG;
|
||
|
private BranchGroup removableOrbitBG;
|
||
|
private TransformGroup trGrRotAndLeafs;
|
||
|
private TransformGroup trGrOrbit;
|
||
|
private TransformGroup trGrTendSpline;
|
||
|
|
||
|
private ColorOrbit colorOrbit;
|
||
|
|
||
|
private Planet planet;
|
||
|
|
||
|
private ObjectsPositions objPos;
|
||
|
private ObjectsInformation objInfo;
|
||
|
private InitializationObject iniObject;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Initializes a new ScenePlanet.
|
||
|
*
|
||
|
* @param planet a object reference of a given planet.
|
||
|
* @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 ScenePlanet(Planet planet, ObjectsPositions objPos,
|
||
|
ObjectsInformation objInfo ) {
|
||
|
this.planet = planet;
|
||
|
this.objPos = objPos;
|
||
|
this.objPos.attach(this);
|
||
|
this.objInfo = objInfo;
|
||
|
this.objInfo.attach(this);
|
||
|
this.iniObject = objInfo.getInitializationObject();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* .Removes this object from the position observer list.
|
||
|
*/
|
||
|
public void destroy() {
|
||
|
objPos.detach(this);
|
||
|
objInfo.detach(this);
|
||
|
planet = null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Updates the position state of the object.<br>
|
||
|
*
|
||
|
* @param orbitPos a reference to the list containing all position observer
|
||
|
*/
|
||
|
public void update(OrbitPositions orbitPos) {
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Updates the information state of the object.<br>
|
||
|
*
|
||
|
* @param id identification of the object that has to be updated
|
||
|
* @param parameter the parameter that has been updated
|
||
|
*/
|
||
|
public void update( String id, int parameter ) {
|
||
|
|
||
|
if ( id.equals( planet.getId() ) ||
|
||
|
id.equals("all") ) {
|
||
|
|
||
|
IniData data = (IniData)objInfo.getParameter( XMLConstants.PLANET, planet.getId() );
|
||
|
|
||
|
switch ( parameter ) {
|
||
|
case XMLConstants.VISIBLE :
|
||
|
// implemented inside SceneSolarSystem
|
||
|
break;
|
||
|
case XMLConstants.COORDINATESYSTEM :
|
||
|
if(data.hasCoordinateSystem()) {
|
||
|
addCoord();
|
||
|
} else {
|
||
|
removeCoord();
|
||
|
}
|
||
|
break;
|
||
|
case XMLConstants.ORBIT :
|
||
|
if(data.hasOrbit()) {
|
||
|
addOrbit();
|
||
|
} else {
|
||
|
removeOrbit();
|
||
|
}
|
||
|
break;
|
||
|
case XMLConstants.COLORORBIT :
|
||
|
setOrbitColor(data.getColorOrbit());
|
||
|
break;
|
||
|
case XMLConstants.ANIMATIONSPEED :
|
||
|
setAnimSpeed();
|
||
|
break;
|
||
|
default : break;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the ID of the current planet.
|
||
|
*
|
||
|
* @return the ID to idendification the planet.
|
||
|
*/
|
||
|
public String getId() {
|
||
|
return planet.getId();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a CelestialObjectInfo of the current planet.
|
||
|
* This object has all specific information of the current planet.
|
||
|
*
|
||
|
* @return a CelestialObjectInfo of the current planet.
|
||
|
*/
|
||
|
public CelestialObjectInfo getInfo() {
|
||
|
return planet.getInfo();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This method handle the animation and rotation of the celestial objects.
|
||
|
*
|
||
|
* @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) {
|
||
|
date = new Date();
|
||
|
if(animate) {
|
||
|
/*
|
||
|
Set the stop time for the animation and rotation.
|
||
|
Without this trick, the celestial objects are jumping around.
|
||
|
Because when the animation is stop, the objects goes on
|
||
|
in the background.
|
||
|
*/
|
||
|
alphaTime = date.getTime() - alphaTime;
|
||
|
rotationAlpha.setStartTime(alphaTime);
|
||
|
animAlpha.setStartTime(alphaTime);
|
||
|
} else {
|
||
|
// save the stop time for the animation and rotation.
|
||
|
alphaTime = animAlpha.getStartTime();
|
||
|
alphaTime = date.getTime() - alphaTime;
|
||
|
}
|
||
|
// set the animation and rotation to stop or go.
|
||
|
spline.setEnable(animate);
|
||
|
rotator.setEnable(rotate);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the animation speed for the planet.
|
||
|
*/
|
||
|
public void setAnimSpeed() {
|
||
|
date = new Date();
|
||
|
|
||
|
AnimationSpeed animationSpeed = (AnimationSpeed)objInfo.getInitializationObject().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();
|
||
|
long duration = (long)(planet.getRotOwnAxis() * factor / animSpeed);
|
||
|
|
||
|
long increasing = rotationAlpha.getIncreasingAlphaDuration();
|
||
|
// delta t = t1*(1-T2/T1)
|
||
|
long diff = (long)((date.getTime() - rotationAlpha.getStartTime()) *
|
||
|
(1.0f - (float)duration / (float)increasing));
|
||
|
rotationAlpha.setIncreasingAlphaDuration(duration);
|
||
|
rotationAlpha.setStartTime(rotationAlpha.getStartTime() + diff);
|
||
|
|
||
|
duration = (long)(planet.getRotOrbit() * factor / animSpeed);
|
||
|
|
||
|
increasing = animAlpha.getIncreasingAlphaDuration();
|
||
|
// delta t = t1*(1-T2/T1)
|
||
|
diff = (long)((date.getTime() - animAlpha.getStartTime()) *
|
||
|
(1.0f - (float)duration / (float)increasing));
|
||
|
|
||
|
animAlpha.setIncreasingAlphaDuration(duration);
|
||
|
animAlpha.setStartTime(animAlpha.getStartTime() + diff);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add the coordinate system to this scenegraph.
|
||
|
*/
|
||
|
public void addCoord() {
|
||
|
trGrRotAndLeafs.addChild(removableCoordBG);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Remove the coordinate system from this scenegraph.
|
||
|
*/
|
||
|
public void removeCoord() {
|
||
|
removableCoordBG.detach();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add the color orbit to this scenegraph.
|
||
|
*/
|
||
|
public void addOrbit() {
|
||
|
trGrOrbit.addChild(removableOrbitBG);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Remove the color orbit from this scenegraph.
|
||
|
*/
|
||
|
public void removeOrbit() {
|
||
|
removableOrbitBG.detach();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set a new orbit color.
|
||
|
*
|
||
|
* @param orbitColor the new color of the orbit
|
||
|
*/
|
||
|
public void setOrbitColor(Color orbitColor) {
|
||
|
colorOrbit.setColor(orbitColor);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the current position of the planet.
|
||
|
*
|
||
|
* @return a Transform3D with the current position.
|
||
|
*/
|
||
|
public Transform3D getCurrentPosition() {
|
||
|
Transform3D transVec = new Transform3D();
|
||
|
Transform3D transRot = new Transform3D();
|
||
|
trGrTendSpline.getTransform(transVec);
|
||
|
trGrRotAndLeafs.getTransform(transRot);
|
||
|
Vector3d vec = new Vector3d();
|
||
|
transVec.get(vec);
|
||
|
transRot.setTranslation(vec);
|
||
|
return transRot;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the BranchGroup of the created planet scene.
|
||
|
* It has a planet as leaf, make a rotation to the own axis and
|
||
|
* make with a TCB-spline function a rotation around the sun.
|
||
|
*
|
||
|
* @return the BranchGroup of the given planet.
|
||
|
*/
|
||
|
public BranchGroup createSceneGraph() {
|
||
|
// A BoundingSphere instance as general bounding region.
|
||
|
BoundingSphere boundsGen = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
|
||
|
SSS3dConstants.BOUNDRADIUS);
|
||
|
|
||
|
// Create the first TransformGroup node trGrRotAndLeafs for the planet,
|
||
|
// the coordinate system and the rotation
|
||
|
trGrRotAndLeafs = new TransformGroup();
|
||
|
|
||
|
// With the ALLOW_TRANSFORM_READ and ALLOW_TRANSFORM_WRITE
|
||
|
// capabilities, we allow the modification of the TransformGroup's
|
||
|
// code by the Behavior's code at run time.
|
||
|
trGrRotAndLeafs.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
|
||
|
trGrRotAndLeafs.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
|
||
|
|
||
|
trGrRotAndLeafs.setCapability(Group.ALLOW_CHILDREN_READ);
|
||
|
trGrRotAndLeafs.setCapability(Group.ALLOW_CHILDREN_WRITE);
|
||
|
trGrRotAndLeafs.setCapability(Group.ALLOW_CHILDREN_EXTEND);
|
||
|
|
||
|
// Attach the ring of the Saturn
|
||
|
if(getId().equals("saturn")) {
|
||
|
TransformGroup trGrRing = new TransformGroup();
|
||
|
|
||
|
// Set the picking of the CoordinateSystem BranchGroup to false.
|
||
|
trGrRing.setPickable(false);
|
||
|
|
||
|
SaturnRing ring = new SaturnRing(1.3, 2.0, new Color3f(0.99f, 0.88f, 0.79f), 160);
|
||
|
trGrRing.addChild(ring);
|
||
|
|
||
|
// Duplicate the ring strip geometry and set the
|
||
|
// appearance of the new Shape3D object without culling.
|
||
|
// This is done because we will see the ring on both side!!!!
|
||
|
PolygonAttributes polyAttrib = new PolygonAttributes();
|
||
|
polyAttrib.setCullFace(PolygonAttributes.CULL_NONE);
|
||
|
|
||
|
Appearance polyAppear = ring.getAppearance();
|
||
|
polyAppear.setPolygonAttributes(polyAttrib);
|
||
|
trGrRing.addChild(new Shape3D(ring.getGeometry(), polyAppear));
|
||
|
trGrRotAndLeafs.addChild(trGrRing);
|
||
|
}
|
||
|
|
||
|
// Attach the leaf node "planet" to the TransformGroup trGrRotAndLeafs.
|
||
|
trGrRotAndLeafs.addChild(planet);
|
||
|
|
||
|
removableCoordBG = new BranchGroup();
|
||
|
|
||
|
// Create and attach a coordinate system to the TransformGroup node
|
||
|
// trGrRotAndLeafs, that is to the planet.
|
||
|
removableCoordBG.addChild(new CoordinateSystem(1.2f));
|
||
|
|
||
|
// Allow to detach the Coordinate System
|
||
|
removableCoordBG.setCapability(BranchGroup.ALLOW_DETACH);
|
||
|
|
||
|
// Set the picking of the CoordinateSystem BranchGroup to false.
|
||
|
removableCoordBG.setPickable(false);
|
||
|
|
||
|
trGrRotAndLeafs.addChild(removableCoordBG);
|
||
|
|
||
|
// Prepare the RotationInterpolator (Behavior) for the
|
||
|
// planet's rotation about its own axis.
|
||
|
Transform3D tr3Drot = new Transform3D();
|
||
|
|
||
|
float startRot, endRot;
|
||
|
if(planet.getRotOwnAxis() > 0) {
|
||
|
// Create the alpha(t) function. Positiv rotation!
|
||
|
rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0,
|
||
|
/*planet.getRotOwnAxis()*/Long.MAX_VALUE, 0, 0, 0, 0, 0);
|
||
|
startRot = 0.0f;
|
||
|
endRot = (float)(2.0 * Math.PI);
|
||
|
} else {
|
||
|
// Create the alpha(t) function. Negativ rotation!
|
||
|
rotationAlpha = new Alpha(-1, Alpha.DECREASING_ENABLE, 0, 0, 0, 0, 0,
|
||
|
/*Math.abs(planet.getRotOwnAxis())*/Long.MAX_VALUE, 0, 0);
|
||
|
startRot = (float)(2.0 * Math.PI);
|
||
|
endRot = 0.0f;
|
||
|
}
|
||
|
// Create the planet's rotation about its own axis.
|
||
|
rotator = new RotationInterpolator(rotationAlpha,
|
||
|
trGrRotAndLeafs, tr3Drot,
|
||
|
startRot, endRot);
|
||
|
rotator.setSchedulingBounds(boundsGen);
|
||
|
trGrRotAndLeafs.addChild(rotator);
|
||
|
|
||
|
// Create the second TransformGroup node trGrTendSpline for the planet's
|
||
|
// rotation around the sun and the tend.
|
||
|
trGrTendSpline = new TransformGroup();
|
||
|
|
||
|
// With the ALLOW_TRANSFORM_READ and ALLOW_TRANSFORM_WRITE
|
||
|
// capabilities, we allow the modification of the TransformGroup's
|
||
|
// code by the Behavior's code at run time.
|
||
|
trGrTendSpline.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
|
||
|
trGrTendSpline.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
|
||
|
|
||
|
// Attach trGrRotAndLeafs node to the trGrTendSpline node.
|
||
|
trGrTendSpline.addChild(trGrRotAndLeafs);
|
||
|
|
||
|
Transform3D yAxis = new Transform3D();
|
||
|
|
||
|
// Create the alpha(t) function.
|
||
|
animAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0,
|
||
|
/*planet.getRotOrbit()*/Long.MAX_VALUE, 0, 0, 0, 0, 0);
|
||
|
|
||
|
// rotate the planet to his true tend
|
||
|
Matrix4d mat = new Matrix4d();
|
||
|
mat.rotX(Math.toRadians(planet.getDegree()));
|
||
|
Quat4f r = new Quat4f();
|
||
|
r.set(mat);
|
||
|
// set scale of the planet
|
||
|
float scale;
|
||
|
boolean compressed = ((Boolean)iniObject.getParameter(XMLConstants.COMPRESSED)).booleanValue();
|
||
|
if(compressed) {
|
||
|
scale = planet.getLogRadius();
|
||
|
} else {
|
||
|
scale = planet.getRadius();
|
||
|
}
|
||
|
Point3f s = new Point3f(scale, scale, scale);
|
||
|
|
||
|
Double time = (Double)iniObject.getParameter(XMLConstants.JDAY);
|
||
|
// take the positions of the planet
|
||
|
Point3f[] pos = objPos.getPositions(getInfo(), time.doubleValue(), compressed);
|
||
|
int pointNrs = pos.length;
|
||
|
float stepLength = 1 / (float)pointNrs;
|
||
|
float stepPos = 0.0f;
|
||
|
// save the positions in the TCBKeyFrame
|
||
|
TCBKeyFrame[] keyFrames = new TCBKeyFrame[pointNrs+1];
|
||
|
for(int i = 0; i < pointNrs; i++) {
|
||
|
keyFrames[i] = new TCBKeyFrame(stepPos, 0, pos[i], r, s, 0.0f, 0.0f, 0.0f);
|
||
|
stepPos += stepLength;
|
||
|
}
|
||
|
keyFrames[pointNrs] = new TCBKeyFrame(1.0f, 0, pos[0], r, s, 0.0f, 0.0f, 0.0f);
|
||
|
|
||
|
// make a spline courve of the position points
|
||
|
spline = new RotPosScaleTCBSplinePathInterpolator(animAlpha,
|
||
|
trGrTendSpline,
|
||
|
yAxis,
|
||
|
keyFrames);
|
||
|
spline.setSchedulingBounds(boundsGen);
|
||
|
trGrTendSpline.addChild(spline);
|
||
|
|
||
|
// Create the TransformGroup node trGrOrbit for the planet orbit.
|
||
|
trGrOrbit = new TransformGroup();
|
||
|
|
||
|
trGrOrbit.addChild(trGrTendSpline);
|
||
|
|
||
|
trGrOrbit.setCapability(Group.ALLOW_CHILDREN_READ);
|
||
|
trGrOrbit.setCapability(Group.ALLOW_CHILDREN_WRITE);
|
||
|
trGrOrbit.setCapability(Group.ALLOW_CHILDREN_EXTEND);
|
||
|
|
||
|
removableOrbitBG = new BranchGroup();
|
||
|
|
||
|
colorOrbit = new ColorLineOrbit(Color.red);
|
||
|
|
||
|
colorOrbit.setPositions(pos);
|
||
|
|
||
|
// Attach the leaf node "orbit" to the BranchGroup removableOrbitBG.
|
||
|
removableOrbitBG.addChild(colorOrbit);
|
||
|
|
||
|
removableOrbitBG.setCapability(BranchGroup.ALLOW_DETACH);
|
||
|
|
||
|
// Set the picking of the ColorOrbit BranchGroup to false.
|
||
|
removableOrbitBG.setPickable(false);
|
||
|
|
||
|
trGrOrbit.addChild(removableOrbitBG);
|
||
|
|
||
|
BranchGroup brGrAll = new BranchGroup();
|
||
|
brGrAll.addChild(trGrOrbit);
|
||
|
|
||
|
brGrAll.setCapability(BranchGroup.ALLOW_DETACH);
|
||
|
|
||
|
// Return the final version of the BranchGroup node brGrAll.
|
||
|
return brGrAll;
|
||
|
}
|
||
|
}
|
||
|
|