blob: 793a9b5b5e06c5ee3fe67373dad3c8586f312216 [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 - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*******************************************************************************/
package org.eclipse.apogy.core.ui.composites;
import javax.vecmath.Point3d;
import org.eclipse.apogy.common.math.ApogyCommonMathFacade;
import org.eclipse.apogy.common.math.Matrix4x4;
import org.eclipse.apogy.common.math.Tuple3d;
import org.eclipse.apogy.common.math.ui.composites.Tuple3dComposite;
import org.eclipse.apogy.core.ApogyCorePackage;
import org.eclipse.apogy.core.ApogySystemApiAdapter;
import org.eclipse.apogy.core.PoseProvider;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import com.ibm.icu.text.DecimalFormat;
public class DeltaPoseComposite extends Composite {
private Adapter poseAdapter;
private ApogySystemApiAdapter variable1ApogySystemApiAdapter;
private ApogySystemApiAdapter variable2ApogySystemApiAdapter;
private final Text textDistance;
private final Tuple3dComposite deltaDistanceComposite;
private final Tuple3dComposite deltaOrientationComposite;
private final DecimalFormat distanceFormat = new DecimalFormat("0.000");
public DeltaPoseComposite(Composite parent, int style) {
super(parent, style);
setLayout(new GridLayout(2, false));
Label lblDistancem = new Label(this, SWT.NONE);
lblDistancem.setAlignment(SWT.RIGHT);
lblDistancem.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblDistancem.setText("Distance (m):");
this.textDistance = new Text(this, SWT.BORDER);
this.textDistance.setToolTipText("Distance between the variables, in meters.");
this.textDistance.setEditable(false);
this.textDistance.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Label lblPositionDistancem = new Label(this, SWT.NONE);
lblPositionDistancem.setAlignment(SWT.RIGHT);
lblPositionDistancem.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblPositionDistancem.setText("Position Delta (m):");
this.deltaDistanceComposite = new Tuple3dComposite(this, SWT.NONE);
this.deltaDistanceComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
this.deltaDistanceComposite.setEnableEditing(false);
Label lblOrientationDeltadeg = new Label(this, SWT.NONE);
lblOrientationDeltadeg.setAlignment(SWT.RIGHT);
lblOrientationDeltadeg.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblOrientationDeltadeg.setText("Orientation Delta (deg):");
this.deltaOrientationComposite = new Tuple3dComposite(this, SWT.NONE, "0.000");
this.deltaOrientationComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
this.deltaOrientationComposite.setEnableEditing(false);
setDisplaysEnabled(false);
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (DeltaPoseComposite.this.variable1ApogySystemApiAdapter != null)
DeltaPoseComposite.this.variable1ApogySystemApiAdapter.eAdapters().remove(getPoseAdapter());
if (DeltaPoseComposite.this.variable2ApogySystemApiAdapter != null)
DeltaPoseComposite.this.variable2ApogySystemApiAdapter.eAdapters().remove(getPoseAdapter());
}
});
}
public ApogySystemApiAdapter getVariable1ApogySystemApiAdapter() {
return this.variable1ApogySystemApiAdapter;
}
public void setVariable1ApogySystemApiAdapter(ApogySystemApiAdapter apogySystemApiAdapter) {
if (this.variable1ApogySystemApiAdapter != null)
this.variable1ApogySystemApiAdapter.eAdapters().remove(getPoseAdapter());
this.variable1ApogySystemApiAdapter = apogySystemApiAdapter;
if (this.variable1ApogySystemApiAdapter != null)
this.variable1ApogySystemApiAdapter.eAdapters().add(getPoseAdapter());
updatePose();
}
public ApogySystemApiAdapter getVariable2ApogySystemApiAdapter() {
return this.variable2ApogySystemApiAdapter;
}
public void setVariable2ApogySystemApiAdapter(ApogySystemApiAdapter apogySystemApiAdapter) {
if (this.variable2ApogySystemApiAdapter != null)
this.variable2ApogySystemApiAdapter.eAdapters().remove(getPoseAdapter());
this.variable2ApogySystemApiAdapter = apogySystemApiAdapter;
if (this.variable2ApogySystemApiAdapter != null)
this.variable2ApogySystemApiAdapter.eAdapters().add(getPoseAdapter());
updatePose();
}
protected void setDisplaysEnabled(boolean enabled) {
if (this.textDistance != null && !this.textDistance.isDisposed())
this.textDistance.setEnabled(enabled);
if (this.deltaDistanceComposite != null && !this.deltaDistanceComposite.isDisposed())
this.deltaDistanceComposite.setEnabled(enabled);
if (this.deltaOrientationComposite != null && !this.deltaOrientationComposite.isDisposed())
this.deltaOrientationComposite.setEnabled(enabled);
}
protected void updatePose() {
if (!isDisposed()) {
// Do this on UI Thread.
getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
setDisplaysEnabled(DeltaPoseComposite.this.variable1ApogySystemApiAdapter != null
&& DeltaPoseComposite.this.variable2ApogySystemApiAdapter != null);
if (DeltaPoseComposite.this.variable1ApogySystemApiAdapter != null
&& DeltaPoseComposite.this.variable2ApogySystemApiAdapter != null) {
Matrix4x4 variable1Pose = DeltaPoseComposite.this.variable1ApogySystemApiAdapter
.getPoseTransform();
if (variable1Pose == null)
variable1Pose = ApogyCommonMathFacade.INSTANCE.createIdentityMatrix4x4();
Matrix4x4 variable2Pose = DeltaPoseComposite.this.variable2ApogySystemApiAdapter
.getPoseTransform();
if (variable2Pose == null)
variable2Pose = ApogyCommonMathFacade.INSTANCE.createIdentityMatrix4x4();
Tuple3d variable1Position = ApogyCommonMathFacade.INSTANCE.extractPosition(variable1Pose);
Point3d p1 = new Point3d(variable1Position.asTuple3d());
Tuple3d variable2Position = ApogyCommonMathFacade.INSTANCE.extractPosition(variable2Pose);
Point3d p2 = new Point3d(variable2Position.asTuple3d());
// Updates Distance.
double distance = p1.distance(p2);
if (DeltaPoseComposite.this.textDistance != null
&& !DeltaPoseComposite.this.textDistance.isDisposed())
DeltaPoseComposite.this.textDistance
.setText(DeltaPoseComposite.this.distanceFormat.format(distance));
double deltaX = p1.x - p2.x;
double deltaY = p1.y - p2.y;
double deltaZ = p1.z - p2.z;
// Updates Delta Position.
Tuple3d deltaPosition = ApogyCommonMathFacade.INSTANCE.createTuple3d(deltaX, deltaY, deltaZ);
if (DeltaPoseComposite.this.deltaDistanceComposite != null
&& !DeltaPoseComposite.this.deltaDistanceComposite.isDisposed())
DeltaPoseComposite.this.deltaDistanceComposite.setTuple3d(deltaPosition);
// TODO Updates Delta Orientation.
}
}
});
}
}
protected Adapter getPoseAdapter() {
if (this.poseAdapter == null) {
this.poseAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof PoseProvider) {
int featureID = msg.getFeatureID(PoseProvider.class);
switch (featureID) {
case ApogyCorePackage.POSE_PROVIDER__POSE_TRANSFORM:
if (msg.getNewValue() instanceof Matrix4x4) {
updatePose();
}
break;
default:
break;
}
}
}
};
}
return this.poseAdapter;
}
}