blob: 5608d8b50d9fc0936015be907964370d89d2a9ad [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre Allard,
* Regent L'Archeveque,
* Sebastien Gemme - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.core.environment.impl;
import java.util.Date;
import java.util.Iterator;
import org.eclipse.apogy.common.topology.Node;
import org.eclipse.apogy.common.topology.TransformNode;
import org.eclipse.apogy.core.environment.AbstractWorksite;
import org.eclipse.apogy.core.environment.ApogyCoreEnvironmentFacade;
import org.eclipse.apogy.core.environment.ApogyCoreEnvironmentFactory;
import org.eclipse.apogy.core.environment.ApogyCoreEnvironmentPackage;
import org.eclipse.apogy.core.environment.Sky;
import org.eclipse.apogy.core.environment.SkyNode;
import org.eclipse.apogy.core.environment.StarField;
import org.eclipse.apogy.core.environment.Sun;
import org.eclipse.apogy.core.environment.Worksite;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
public class SkyCustomImpl extends SkyImpl {
protected Adapter worksiteAdapter;
protected SkyCustomImpl() {
super();
eAdapters().add(getWorksiteAdapter());
}
public NotificationChain basicSetWorksite(Worksite newWorksite, NotificationChain msgs) {
if (basicGetWorksite() != null) {
// Un-Register Listener from previous to the worksite.
basicGetWorksite().eAdapters().remove(getWorksiteAdapter());
}
if (newWorksite != null) {
// Register Listener for changes to the worksite.
newWorksite.eAdapters().add(getWorksiteAdapter());
}
return super.basicSetWorksite(newWorksite, msgs);
}
@Override
public SkyNode getSkyNode() {
if (super.getSkyNode() == null) {
this.skyNode = ApogyCoreEnvironmentFactory.eINSTANCE.createSkyNode();
ApogyCoreEnvironmentFacade.INSTANCE.initializeSkyNode(this.skyNode);
this.skyNode.setSky(this);
}
return super.getSkyNode();
}
@Override
public Sun getSun() {
// Explores children to find the Sun.
if (basicGetSun() == null) {
this.sun = findSunInTopology();
}
return this.sun;
}
@Override
public StarField getStarField() {
// Explores children to find the StarField.
if (basicGetStarField() == null) {
this.starField = findStarFieldInTopology();
}
return this.starField;
}
@Override
public double getSunAngularDiameter() {
// TODO : Fix the problem with the distance calculation.
// // Find the distance between the sun and the origin.
// TransformNode transform = (TransformNode) getSun().getParent();
// Vector3d vector = new Vector3d();
// transform.asMatrix4d().get(vector);
// double distance = vector.length();
//
// // Computes the angular diameter.
// double angularDiameter = Math.atan(getSun().getRadius() / distance) *
// 2;
// Return the average angular size for now.
double angularDiameter = Math.toRadians(0.535833333);
return angularDiameter;
}
/**
* Searches the topology to find the Sun.
*
* @return The Sun, null if not found.
*/
private Sun findSunInTopology() {
Sun sunFound = null;
EList<Node> children = getSkyNode().getChildren();
Iterator<Node> it = children.iterator();
while (it.hasNext() && (sunFound == null)) {
Node node = it.next();
if (node instanceof TransformNode) {
TransformNode t = (TransformNode) node;
EList<Node> tChildren = t.getChildren();
Iterator<Node> tIt = tChildren.iterator();
while (tIt.hasNext() && (sunFound == null)) {
Node n = tIt.next();
if (n instanceof Sun) {
sunFound = (Sun) n;
}
}
}
}
return sunFound;
}
/**
* Searches the topology to find the StarField.
*
* @return The StarField, null if not found.
*/
private StarField findStarFieldInTopology() {
StarField foundStarField = null;
EList<Node> children = getSkyNode().getChildren();
Iterator<Node> it = children.iterator();
while (it.hasNext() && (foundStarField == null)) {
Node node = it.next();
if (node instanceof TransformNode) {
TransformNode t = (TransformNode) node;
EList<Node> tChildren = t.getChildren();
Iterator<Node> tIt = tChildren.iterator();
while (tIt.hasNext() && (foundStarField == null)) {
Node n = tIt.next();
if (n instanceof StarField) {
foundStarField = (StarField) n;
}
}
}
}
return foundStarField;
}
protected Adapter getWorksiteAdapter() {
if (this.worksiteAdapter == null) {
this.worksiteAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof AbstractWorksite) {
int featureId = msg.getFeatureID(AbstractWorksite.class);
// The Worksite time has changed, update the Sky time.
if (featureId == ApogyCoreEnvironmentPackage.ABSTRACT_WORKSITE__TIME) {
if (msg.getNewValue() instanceof Date) {
Date newDate = (Date) msg.getNewValue();
setTime(newDate);
}
}
} else if (msg.getNotifier() instanceof Sky) {
int featureId = msg.getFeatureID(Sky.class);
switch (featureId) {
// The worksite has changed, unregister from previous,
// register to new and update.
case ApogyCoreEnvironmentPackage.SKY__WORKSITE: {
if (msg.getOldValue() instanceof Worksite) {
Worksite oldWorksite = (Worksite) msg.getOldValue();
oldWorksite.eAdapters().remove(getWorksiteAdapter());
}
if (msg.getNewValue() instanceof Worksite) {
Worksite newWorksite = (Worksite) msg.getNewValue();
newWorksite.eAdapters().add(getWorksiteAdapter());
// Updates time.
setTime(newWorksite.getTime());
}
}
break;
default:
break;
}
}
}
};
}
return this.worksiteAdapter;
}
} // SkyImpl