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

511 lines
18 KiB
Java

/*
File: SceneMoon.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/moons/SceneMoon.java,v 1.11 2000/12/15 02:53:18 portm Exp $
$Author: portm $
$Date: 2000/12/15 02:53:18 $
$State: Exp $
*/
package sss3d.contentbranch.moons;
import sss3d.contentbranch.*;
import sss3d.utils.SSS3dConstants;
import sss3d.utils.observer.*;
import sss3d.contentbranch.orbit.*;
import sss3d.calculations.constants.AstronomicalConstants;
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 moon.
*
* @author Marcel Portner & Bernhard Hari
* @version $Revision: 1.11 $
* @see Moon
*/
public class SceneMoon implements SceneCelestialObjects, PositionObserver, InfoObserver {
private RotPosScaleTCBSplinePathInterpolator spline;
private RotPosScaleTCBSplinePathInterpolator parentSpline;
private RotationInterpolator rotator;
private Alpha rotationAlpha;
private Alpha animAlpha;
private Alpha parentAnimAlpha;
private long alphaTime = 0;
private Date date;
private BranchGroup removableCoordBG;
private BranchGroup removableOrbitBG;
private TransformGroup trGrRotAndLeafs;
private TransformGroup trGrOrbit;
private TransformGroup trGrTendSpline;
private TransformGroup trGrParentSpline;
private ColorOrbit colorOrbit;
private Moon moon;
private ObjectsPositions objPos;
private ObjectsInformation objInfo;
private InitializationObject iniObject;
private CelestialObjectInfo parentObject;
/**
* Initializes a new ScenePlanet.
*
* @param moon a object reference of a given moon.
* @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 SceneMoon(Moon moon, ObjectsPositions objPos,
ObjectsInformation objInfo ) {
this.moon = moon;
this.objPos = objPos;
this.objPos.attach(this);
this.objInfo = objInfo;
this.objInfo.attach(this);
iniObject = objInfo.getInitializationObject();
parentObject = objInfo.getInfo(moon.getParentName());
}
/**
* Removes this object from the position observer list.
*/
public void destroy() {
objPos.detach(this);
objInfo.detach(this);
moon = 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 changed
*/
public void update( String id, int parameter ) {
if ( id.equals( moon.getId() ) ||
id.equals("all") ) {
IniData data = (IniData)objInfo.getParameter( XMLConstants.MOON, moon.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 moon.
*
* @return the ID to idendification the moon.
*/
public String getId() {
return moon.getId();
}
/**
* Returns a CelestialObjectInfo of the current moon.
* This object has all specific information of the current moon.
*
* @return a CelestialObjectInfo of the current moon.
*/
public CelestialObjectInfo getInfo() {
return moon.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);
parentAnimAlpha.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);
parentSpline.setEnable(animate);
rotator.setEnable(rotate);
}
/**
* Set the animation speed for the moon.
*/
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:
}
// moon rotation
int animSpeed = animationSpeed.getValue();
long duration = (long)(moon.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);
// moon movement
duration = (long)(moon.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);
// parent movement
duration = (long)(parentObject.getOrbitPeriod() * 1000 * AstronomicalConstants.DAYS *
factor / animSpeed);
increasing = parentAnimAlpha.getIncreasingAlphaDuration();
// delta t = t1*(1-T2/T1)
diff = (long)((date.getTime() - parentAnimAlpha.getStartTime()) *
(1.0f - (float)duration / (float)increasing));
parentAnimAlpha.setIncreasingAlphaDuration(duration);
parentAnimAlpha.setStartTime(parentAnimAlpha.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 moon.
*
* @return a Transform3D with the current position.
*/
public Transform3D getCurrentPosition() {
Transform3D transVec = new Transform3D();
Transform3D transVecParent = new Transform3D();
Transform3D transRot = new Transform3D();
trGrTendSpline.getTransform(transVec);
trGrRotAndLeafs.getTransform(transRot);
trGrParentSpline.getTransform(transVecParent);
Vector3d vec = new Vector3d();
Vector3d vecParent = new Vector3d();
transVec.get(vec);
transVecParent.get(vecParent);
vec.add(vecParent);
transRot.setTranslation(vec);
return transRot;
}
/**
* Returns the BranchGroup of the created moon scene.
* It has a moon as leaf, make a rotation to the own axis and
* make with a TCB-spline function a rotation around the parent planet.
*
* @return the BranchGroup of the given moon.
*/
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 moon,
// 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 leaf node "moon" to the TransformGroup trGrRotAndLeafs.
trGrRotAndLeafs.addChild(moon);
removableCoordBG = new BranchGroup();
// Create and attach a coordinate system to the TransformGroup node
// trGrRotAndLeafs, that is to the moon.
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
// moon's rotation about its own axis.
Transform3D tr3Drot = new Transform3D();
float startRot, endRot;
if(moon.getRotOwnAxis() > 0) {
// Create the alpha(t) function. Positiv rotation!
rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0,
/*moon.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(moon.getRotOwnAxis())*/Long.MAX_VALUE, 0, 0);
startRot = (float)(2.0 * Math.PI);
endRot = 0.0f;
}
// Create the moon'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 moon's
// rotation around the parent planet 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,
/*moon.getRotOrbit()*/Long.MAX_VALUE, 0, 0, 0, 0, 0);
// the animation Alpha value of the parent object
long duration = (long)(parentObject.getOrbitPeriod() * 1000 * AstronomicalConstants.DAYS);
// Create the alpha(t) function.
parentAnimAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0,
/*duration*/Long.MAX_VALUE, 0, 0, 0, 0, 0);
// rotate the moon to his true tend
Matrix4d mat = new Matrix4d();
mat.rotX(Math.toRadians(moon.getDegree()));
Quat4f r = new Quat4f();
r.set(mat);
// set scale of the moon
float scale;
boolean compressed = ((Boolean)iniObject.getParameter(XMLConstants.COMPRESSED)).booleanValue();
if(compressed) {
scale = moon.getLogRadius();
} else {
scale = moon.getRadius();
}
Point3f s = new Point3f(scale, scale, scale);
Double time = (Double)iniObject.getParameter(XMLConstants.JDAY);
// take the positions of the moon
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 moon 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);
trGrParentSpline = 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.
trGrParentSpline.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
trGrParentSpline.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
// Attach trGrRotAndLeafs node to the trGrTendSpline node.
trGrParentSpline.addChild(trGrOrbit);
r = null;
s = null;
r = new Quat4f();
s = new Point3f(1.0f, 1.0f, 1.0f);
// take the positions of the parent planet
Point3f[] parentPos = objPos.getPositions(parentObject, time.doubleValue(), compressed);
pointNrs = parentPos.length;
stepLength = 1 / (float)pointNrs;
stepPos = 0.0f;
// save the positions in the TCBKeyFrame
TCBKeyFrame[] parentKeyFrames = new TCBKeyFrame[pointNrs+1];
for(int i = 0; i < pointNrs; i++) {
parentKeyFrames[i] = new TCBKeyFrame(stepPos, 0, parentPos[i], r, s, 0.0f, 0.0f, 0.0f);
stepPos += stepLength;
}
parentKeyFrames[pointNrs] = new TCBKeyFrame(1.0f, 0, parentPos[0], r, s, 0.0f, 0.0f, 0.0f);
// make a spline courve of the position points
parentSpline = new RotPosScaleTCBSplinePathInterpolator(parentAnimAlpha,
trGrParentSpline,
yAxis,
parentKeyFrames);
parentSpline.setSchedulingBounds(boundsGen);
trGrParentSpline.addChild(parentSpline);
BranchGroup brGrAll = new BranchGroup();
brGrAll.addChild(trGrParentSpline);
brGrAll.setCapability(BranchGroup.ALLOW_DETACH);
// Return the final version of the BranchGroup node brGrAll.
return brGrAll;
}
}