/*
* Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.gui.d3;
import boofcv.struct.distort.Point2Transform2_F64;
import boofcv.struct.image.ImageGray;
import org.ejml.data.DenseMatrix64F;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
/**
* Provides a simplified set of controls for changing the view in a {@link DisparityPointCloudViewer}.
* Uses the mouse to move the camera in its local X,Y plane. Widgets in the control bar
* allow the user to change the camera's tilt and distance from the origin.
*
* @author Peter Abeles
*/
public class PointCloudTiltPanel extends JPanel
implements ActionListener, ChangeListener, MouseListener, MouseMotionListener
{
// Point cloud viewer
DisparityPointCloudViewer view;
// when pressed sets the view to "home"
JButton homeButton;
// Adjusts the amount of zoom
JSpinner rangeSpinner;
// Tilts the camera up and down
JSlider tiltSlider;
// bounds on scale adjustment
double minRange = 0;
double maxRange = 20;
// previous mouse location
int prevX;
int prevY;
public PointCloudTiltPanel() {
super(new BorderLayout());
addMouseListener(this);
addMouseMotionListener(this);
view = new DisparityPointCloudViewer();
JToolBar toolBar = createToolBar();
add(toolBar, BorderLayout.PAGE_START);
add(view, BorderLayout.CENTER);
}
private JToolBar createToolBar() {
JToolBar toolBar = new JToolBar("Controls");
homeButton = new JButton("Home");
homeButton.addActionListener(this);
rangeSpinner = new JSpinner(new SpinnerNumberModel(view.range, minRange, maxRange, 0.2));
rangeSpinner.addChangeListener(this);
rangeSpinner.setMaximumSize(rangeSpinner.getPreferredSize());
tiltSlider = new JSlider(JSlider.HORIZONTAL,
-120, 120, view.tiltAngle);
tiltSlider.addChangeListener(this);
tiltSlider.setMajorTickSpacing(60);
tiltSlider.setPaintLabels(true);
toolBar.add(homeButton);
toolBar.add(new JToolBar.Separator(new Dimension(10,1)));
toolBar.add(new JLabel("Range:"));
toolBar.add(rangeSpinner);
toolBar.add(new JToolBar.Separator(new Dimension(10,1)));
toolBar.add(new JLabel("Tilt Angle:"));
toolBar.add(tiltSlider);
return toolBar;
}
/**
* Specified intrinsic camera parameters and disparity settings
*
* @param baseline Stereo baseline
* @param K rectified camera calibration matrix
*/
public void configure(double baseline,
DenseMatrix64F K,
Point2Transform2_F64 rectifiedToColor,
int minDisparity, int maxDisparity) {
view.configure(baseline, K, rectifiedToColor, minDisparity, maxDisparity);
}
/**
* Updates the view, must be called in a GUI thread
*/
public void process(ImageGray disparity , BufferedImage color ) {
view.process(disparity,color);
tiltSlider.removeChangeListener(this);
tiltSlider.setValue(view.tiltAngle);
tiltSlider.addChangeListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if( e.getSource() == homeButton ) {
view.offsetX = 0;
view.offsetY = 0;
view.tiltAngle = 0;
view.range = 1;
tiltSlider.removeChangeListener(this);
tiltSlider.setValue(view.tiltAngle);
tiltSlider.addChangeListener(this);
rangeSpinner.removeChangeListener(this);
rangeSpinner.setValue(view.range);
rangeSpinner.addChangeListener(this);
}
view.repaint();
}
@Override
public void stateChanged(ChangeEvent e) {
if( e.getSource() == rangeSpinner) {
view.range = ((Number) rangeSpinner.getValue()).doubleValue();
} else if( e.getSource() == tiltSlider ) {
view.tiltAngle = ((Number)tiltSlider.getValue()).intValue();
}
view.repaint();
}
@Override
public synchronized void mouseClicked(MouseEvent e) {
double range = view.range;
if( e.isShiftDown())
range *= 0.75;
else
range *= 1.25;
if( range < minRange) range = minRange;
if( range > maxRange) range = maxRange;
rangeSpinner.setValue(range);
}
@Override
public void mousePressed(MouseEvent e) {
prevX = e.getX();
prevY = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public synchronized void mouseDragged(MouseEvent e) {
final int deltaX = e.getX()-prevX;
final int deltaY = e.getY()-prevY;
view.offsetX += deltaX;
view.offsetY += deltaY;
prevX = e.getX();
prevY = e.getY();
view.repaint();
}
@Override
public void mouseMoved(MouseEvent e) {}
}