blob: 98d2ce8ebff0617e9dcb7236905765a3c488cdb2 [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 - initial API and implementation
* Regent L'Archeveque
*
* SPDX-License-Identifier: EPL-1.0
*******************************************************************************/
package org.eclipse.apogy.common.math.ui.composites;
import javax.vecmath.Matrix3d;
import javax.vecmath.Vector3d;
import org.eclipse.apogy.common.math.ApogyCommonMathFacade;
import org.eclipse.apogy.common.math.GeometricUtils;
import org.eclipse.apogy.common.math.Matrix3x3;
import org.eclipse.apogy.common.math.provider.MathEditUtils;
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.emf.edit.domain.EditingDomain;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Slider;
public class RotationMatrixSlidersComposite extends Composite {
enum RotationAxis {
X, Y, Z
}
private EditingDomain editingDomain;
private Matrix3x3 matrix;
private boolean disableEvent = false;
private Adapter matrixAdapter;
private final Slider rxSlider;
private final Slider rySlider;
private final Slider rzSlider;
public RotationMatrixSlidersComposite(Composite parent, int style) {
super(parent, style);
setLayout(new GridLayout(2, true));
Label rxLabel = new Label(this, SWT.NONE);
rxLabel.setAlignment(SWT.LEFT);
rxLabel.setText("Rx (deg):");
this.rxSlider = createSlider(this, SWT.BORDER | SWT.SINGLE | SWT.HORIZONTAL, RotationAxis.X);
this.rxSlider.setToolTipText("Rotation about X in degrees.");
this.rxSlider.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
Label ryLabel = new Label(this, SWT.NONE);
ryLabel.setAlignment(SWT.LEFT);
ryLabel.setText("Ry (deg):");
this.rySlider = createSlider(this, SWT.BORDER | SWT.SINGLE | SWT.HORIZONTAL, RotationAxis.Y);
this.rySlider.setToolTipText("Rotation about Y in degrees.");
this.rySlider.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
Label rzLabel = new Label(this, SWT.NONE);
rzLabel.setAlignment(SWT.LEFT);
rzLabel.setText("Rz (deg):");
this.rzSlider = createSlider(this, SWT.BORDER | SWT.SINGLE | SWT.HORIZONTAL, RotationAxis.Z);
this.rzSlider.setToolTipText("Rotation about Z in degrees.");
this.rzSlider.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
}
public RotationMatrixSlidersComposite(Composite parent, int style, EditingDomain editingDomain) {
this(parent, style);
this.editingDomain = editingDomain;
}
public void setMatrix3x3(Matrix3x3 newMatrix3x3) {
setMatrix3x3(newMatrix3x3, true);
}
public void setMatrix3x3(Matrix3x3 newMatrix3x3, boolean update) {
if (this.matrix != null) {
this.matrix.eAdapters().remove(getMatrixAdapter());
}
this.matrix = newMatrix3x3;
if (newMatrix3x3 != null) {
newMatrix3x3.eAdapters().add(getMatrixAdapter());
// Update the controls.
this.disableEvent = true;
updateRotations(newMatrix3x3);
this.disableEvent = false;
}
}
private Vector3d getRotationVector() {
Vector3d rotation = new Vector3d();
rotation.setX((this.rxSlider.getSelection() - 180));
rotation.setY((this.rySlider.getSelection() - 180));
rotation.setZ((this.rzSlider.getSelection() - 180));
return rotation;
}
private void updateXRotation(double xRotation) {
if (this.matrix != null) {
Vector3d rotationVector = getRotationVector();
rotationVector.setX(Math.toDegrees(xRotation));
Matrix3d matrix3d = GeometricUtils.packXYZ(Math.toRadians(rotationVector.getX()),
Math.toRadians(rotationVector.getY()), Math.toRadians(rotationVector.getZ()));
MathEditUtils.updateOrientation(this.matrix, ApogyCommonMathFacade.INSTANCE.createMatrix3x3(matrix3d),
this.editingDomain);
}
}
private void updateYRotation(double yRotation) {
if (this.matrix != null) {
Vector3d rotationVector = getRotationVector();
rotationVector.setY(Math.toDegrees(yRotation));
Matrix3d matrix3d = GeometricUtils.packXYZ(Math.toRadians(rotationVector.getX()),
Math.toRadians(rotationVector.getY()), Math.toRadians(rotationVector.getZ()));
MathEditUtils.updateOrientation(this.matrix, ApogyCommonMathFacade.INSTANCE.createMatrix3x3(matrix3d),
this.editingDomain);
}
}
private void updateZRotation(double zRotation) {
if (this.matrix != null) {
Vector3d rotationVector = getRotationVector();
rotationVector.setZ(Math.toDegrees(zRotation));
Matrix3d matrix3d = GeometricUtils.packXYZ(Math.toRadians(rotationVector.getX()),
Math.toRadians(rotationVector.getY()), Math.toRadians(rotationVector.getZ()));
MathEditUtils.updateOrientation(this.matrix, ApogyCommonMathFacade.INSTANCE.createMatrix3x3(matrix3d),
this.editingDomain);
}
}
protected Slider createSlider(Composite parent, int style, RotationAxis rotationAxis) {
Slider slider = new Slider(parent, style);
slider.setMinimum(0);
slider.setPageIncrement(1);
slider.setMaximum(360);
slider.setSelection(180);
if (rotationAxis == RotationAxis.X) {
slider.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
RotationMatrixSlidersComposite.this.disableEvent = true;
double newValue = Math.toRadians(slider.getSelection() - 180);
updateXRotation(newValue);
RotationMatrixSlidersComposite.this.disableEvent = false;
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
} else if (rotationAxis == RotationAxis.Y) {
slider.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
RotationMatrixSlidersComposite.this.disableEvent = true;
double newValue = Math.toRadians(slider.getSelection() - 180);
updateYRotation(newValue);
RotationMatrixSlidersComposite.this.disableEvent = false;
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
} else {
slider.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
RotationMatrixSlidersComposite.this.disableEvent = true;
double newValue = Math.toRadians(slider.getSelection() - 180);
updateZRotation(newValue);
RotationMatrixSlidersComposite.this.disableEvent = false;
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
}
return slider;
}
private void updateRotations(Matrix3x3 matrix) {
if (matrix != null) {
if (this.rxSlider != null && !this.rxSlider.isDisposed() && this.rySlider != null
&& !this.rySlider.isDisposed() && this.rzSlider != null && !this.rzSlider.isDisposed()) {
Vector3d rotationVector = GeometricUtils.extractRotationFromXYZRotMatrix(matrix.asMatrix3d());
int xRot = (int) Math.floor(Math.toDegrees(GeometricUtils.normalizeAngle(rotationVector.getX()))) + 180;
int yRot = (int) Math.floor(Math.toDegrees(GeometricUtils.normalizeAngle(rotationVector.getY()))) + 180;
int zRot = (int) Math.floor(Math.toDegrees(GeometricUtils.normalizeAngle(rotationVector.getZ()))) + 180;
this.rxSlider.setSelection(xRot);
this.rySlider.setSelection(yRot);
this.rzSlider.setSelection(zRot);
}
}
}
private Adapter getMatrixAdapter() {
if (this.matrixAdapter == null) {
this.matrixAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (!RotationMatrixSlidersComposite.this.disableEvent) {
updateRotations((Matrix3x3) msg.getNotifier());
}
};
};
}
return this.matrixAdapter;
}
}