556 lines
17 KiB
Java
556 lines
17 KiB
Java
//This file is part of SECONDO.
|
|
|
|
//Copyright (C) 2004, University in Hagen, Department of Computer Science,
|
|
//Database Systems for New Applications.
|
|
|
|
//SECONDO is free software; you can redistribute it and/or modify
|
|
//it under the terms of the GNU General Public License as published by
|
|
//the Free Software Foundation; either version 2 of the License, or
|
|
//(at your option) any later version.
|
|
|
|
//SECONDO is distributed in the hope that it will be useful,
|
|
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
//GNU General Public License for more details.
|
|
|
|
//You should have received a copy of the GNU General Public License
|
|
//along with SECONDO; if not, write to the Free Software
|
|
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
package viewer.spatial3D;
|
|
|
|
import tools.Reporter;
|
|
|
|
import java.awt.Button;
|
|
import java.awt.Color;
|
|
import java.awt.Dimension;
|
|
import java.awt.GridBagLayout;
|
|
import java.awt.GridBagConstraints;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import javax.media.j3d.PointLight;
|
|
import javax.swing.JButton;
|
|
import javax.swing.JCheckBox;
|
|
import javax.swing.JColorChooser;
|
|
import javax.swing.JComboBox;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JSlider;
|
|
import javax.swing.JSpinner;
|
|
import javax.swing.SpinnerNumberModel;
|
|
import javax.swing.event.*;
|
|
import javax.swing.JSeparator;
|
|
import javax.swing.SwingConstants;
|
|
import javax.vecmath.Color3f;
|
|
import viewer.Spatial3DViewer;
|
|
|
|
/**
|
|
* a SWING panel class for lighting in Spatial3DViewer
|
|
*
|
|
*/
|
|
public class LightPanel extends JPanel{
|
|
|
|
private final int SPINNER_COLUMN_SIZE = 10;
|
|
private final int MAX_LIGHT_NUM = 10;
|
|
public final int STARTING_RADIUS = 500;
|
|
|
|
private double xChangeFactor;
|
|
private double yChangeFactor;
|
|
private double zChangeFactor;
|
|
|
|
private Spatial3DViewer sv;
|
|
private JCheckBox enableBox;
|
|
private JComboBox lightsBox;
|
|
private JSlider radiusSlider;
|
|
private JLabel radiusLabel;
|
|
private JButton colorButton;
|
|
private JButton delButton;
|
|
private JButton delAllButton;
|
|
private JSpinner verticalSpinner;
|
|
private JSpinner horizontalSpinner;
|
|
private JSpinner depthSpinner;
|
|
private JLabel xPosLabel;
|
|
private JLabel yPosLabel;
|
|
private JLabel zPosLabel;
|
|
private JLabel brightnessLabel;
|
|
private JCheckBox mainSW;
|
|
private JButton mainColorButton;
|
|
private JSlider brightnessSlider;
|
|
|
|
/**
|
|
* constructor
|
|
* @param Spatial3Dviewer object as parent
|
|
*/
|
|
public LightPanel(final Spatial3DViewer _sv){
|
|
|
|
this.setLayout(new GridBagLayout());
|
|
sv = _sv;
|
|
|
|
xChangeFactor = sv.getTranslateFactor();
|
|
yChangeFactor = sv.getTranslateFactor();
|
|
zChangeFactor = sv.getZoomFactor();
|
|
|
|
GridBagConstraints constraint = new GridBagConstraints();
|
|
constraint.anchor = GridBagConstraints.LINE_START;
|
|
constraint.fill = GridBagConstraints.HORIZONTAL;
|
|
|
|
//label for main light
|
|
constraint.gridx = 0;
|
|
constraint.gridy = 0;
|
|
this.add(new JLabel("global light"),constraint);
|
|
|
|
// on/off switch for the ambient light
|
|
mainSW = new JCheckBox();
|
|
mainSW.addActionListener(new ActionListener(){
|
|
@Override
|
|
public void actionPerformed(ActionEvent event){
|
|
sv.setMainLightSwitch(mainSW.isSelected());
|
|
}
|
|
});
|
|
mainSW.setText("on / off");
|
|
mainSW.setSelected(true);
|
|
constraint.gridx = 0;
|
|
constraint.gridy = 1;
|
|
this.add(mainSW,constraint);
|
|
|
|
//color chooser for the ambient light
|
|
mainColorButton = new JButton("light color");
|
|
mainColorButton.addActionListener(new ActionListener(){
|
|
@Override
|
|
public void actionPerformed(ActionEvent event){
|
|
Color3f curColor = sv.getLightColor();
|
|
Color newColor = JColorChooser.showDialog(sv.getMainFrame(),"Choose the light's color",curColor.get()) ;
|
|
if(newColor==null){
|
|
Reporter.showError("Please choose a color!");
|
|
return;
|
|
}
|
|
sv.setLightColor(newColor);
|
|
}
|
|
});
|
|
constraint.gridx = 1;
|
|
constraint.gridy = 1;
|
|
this.add(mainColorButton,constraint);
|
|
|
|
constraint.gridx=0;
|
|
constraint.gridy=2;
|
|
this.add(new JSeparator(JSeparator.HORIZONTAL),constraint);
|
|
|
|
// individual lights
|
|
constraint.gridx = 0;
|
|
constraint.gridy = 3;
|
|
this.add(new JLabel("Indiv. lights"),constraint);
|
|
|
|
constraint.gridx = 1;
|
|
constraint.gridy = 3;
|
|
lightsBox = new JComboBox();
|
|
lightsBox.addActionListener(new ActionListener(){
|
|
@Override
|
|
public void actionPerformed(ActionEvent event){
|
|
JComboBox cb = (JComboBox)event.getSource();
|
|
int index = cb.getSelectedIndex();
|
|
setPanel(index);
|
|
}
|
|
});
|
|
|
|
|
|
this.add(lightsBox,constraint);
|
|
|
|
constraint.gridx = 0;
|
|
constraint.gridy = 4;
|
|
this.add(new JLabel("Enable"),constraint);
|
|
|
|
enableBox = new JCheckBox();
|
|
enableBox.addActionListener(new ActionListener(){
|
|
@Override
|
|
public void actionPerformed(ActionEvent event){
|
|
LightBranchGroup light = sv.getLight(lightsBox.getSelectedIndex());
|
|
if(light==null){
|
|
Reporter.showError("wrong light lindex!");
|
|
return;
|
|
}
|
|
light.setEnable(enableBox.isSelected());
|
|
}
|
|
});
|
|
|
|
enableBox.setEnabled(false);
|
|
constraint.gridx = 1;
|
|
constraint.gridy = 4;
|
|
this.add(enableBox,constraint);
|
|
|
|
JButton addButton = new JButton("Add");
|
|
addButton.addActionListener(new ActionListener(){
|
|
@Override
|
|
public void actionPerformed(ActionEvent arg0){
|
|
if(lightsBox.getItemCount()> MAX_LIGHT_NUM){
|
|
Reporter.showError("There are already 10 lights. Please reduce!");
|
|
return;
|
|
}
|
|
sv.addLight();
|
|
lightsBox.addItem(makeObj("light " + lightsBox.getItemCount()));
|
|
setVisible(true);
|
|
activate(true);
|
|
lightsBox.setSelectedIndex(lightsBox.getItemCount()-1);
|
|
//reset();
|
|
}
|
|
});
|
|
constraint.gridx = 0;
|
|
constraint.gridy = 5;
|
|
this.add(addButton,constraint);
|
|
|
|
colorButton = new JButton("Change Color");
|
|
colorButton.addActionListener(new ActionListener(){
|
|
@Override
|
|
public void actionPerformed(ActionEvent arg0) {
|
|
if(lightsBox.countComponents() == 0) return;
|
|
int index = lightsBox.getSelectedIndex();
|
|
LightBranchGroup light = sv.getLight(index);
|
|
if(light==null){
|
|
Reporter.showError("wrong light lindex!");
|
|
return;
|
|
}
|
|
Color lastColor = light.getColor();
|
|
Color newColor = JColorChooser.showDialog(sv.getMainFrame(),"Choose the light's color",lastColor) ;
|
|
if(newColor==null){
|
|
Reporter.showError("Please choose a color!");
|
|
return;
|
|
}
|
|
light.setColor(newColor);
|
|
light.setEnable(true);
|
|
enableBox.setSelected(true);
|
|
//sv.setLightColor(newColor, index);
|
|
|
|
}
|
|
});
|
|
colorButton.setEnabled(false);
|
|
constraint.gridx = 1;
|
|
constraint.gridy = 5;
|
|
this.add(colorButton,constraint);
|
|
|
|
delButton = new JButton("Delete");
|
|
delButton.addActionListener(new ActionListener(){
|
|
@Override
|
|
public void actionPerformed(ActionEvent arg0){
|
|
if(lightsBox.countComponents() == 0) return;
|
|
int index = lightsBox.getSelectedIndex();
|
|
sv.delLight(index);
|
|
lightsBox.removeItemAt(index);
|
|
if(lightsBox.getItemCount()==0) activate(false);
|
|
}
|
|
});
|
|
delButton.setEnabled(false);
|
|
constraint.gridx = 0;
|
|
constraint.gridy = 6;
|
|
this.add(delButton,constraint);
|
|
|
|
delAllButton = new JButton("Delete All");
|
|
delAllButton.addActionListener(new ActionListener(){
|
|
@Override
|
|
public void actionPerformed(ActionEvent arg0){
|
|
if(lightsBox.countComponents() == 0) return;
|
|
int indeces = lightsBox.getItemCount();
|
|
sv.delAllLight(indeces);
|
|
lightsBox.removeAllItems();
|
|
//reset();
|
|
activate(false);
|
|
|
|
}
|
|
});
|
|
delAllButton.setEnabled(false);
|
|
constraint.gridx = 1;
|
|
constraint.gridy = 6;
|
|
this.add(delAllButton,constraint);
|
|
|
|
// slide bar for X position change
|
|
constraint.gridwidth = 2;
|
|
constraint.gridx = 0;
|
|
constraint.gridy = 7;
|
|
this.add(new JLabel("X-Pos"),constraint);
|
|
|
|
SpinnerNumberModel hSpModel = new SpinnerNumberModel(0, Math.round(-Double.MAX_VALUE), Math.round(Double.MAX_VALUE),1);
|
|
horizontalSpinner = new JSpinner(hSpModel);
|
|
|
|
horizontalSpinner.addChangeListener(new ChangeListener(){
|
|
@Override
|
|
public void stateChanged(ChangeEvent e){
|
|
JSpinner source = (JSpinner)e.getSource();
|
|
//Reporter.writeInfo("X-Pos changed");
|
|
//if(source.isFocusOwner()){
|
|
double xps=((SpinnerNumberModel)source.getModel()).getNumber().doubleValue();
|
|
int index = lightsBox.getSelectedIndex();
|
|
LightBranchGroup light = sv.getLight(index);
|
|
if(light==null){
|
|
//Reporter.writeError("wrong light lindex!");
|
|
return;
|
|
}
|
|
light.setX(xps);
|
|
light.setEnable(true);
|
|
enableBox.setSelected(true);
|
|
//sv.setLightX(xps,index);
|
|
//Reporter.writeInfo("X-Pos focused");
|
|
//}
|
|
}
|
|
});
|
|
|
|
((JSpinner.NumberEditor)horizontalSpinner.getEditor()).getTextField().setColumns(SPINNER_COLUMN_SIZE);
|
|
constraint.gridy = 8;
|
|
horizontalSpinner.setEnabled(false);
|
|
this.add(horizontalSpinner,constraint);
|
|
|
|
|
|
// Spinner for Y position change
|
|
constraint.gridy = 9;
|
|
this.add(new JLabel("Y-Pos"),constraint);
|
|
|
|
SpinnerNumberModel vSpModel = new SpinnerNumberModel(0, Math.round(-Double.MAX_VALUE), Math.round(Double.MAX_VALUE),1);
|
|
verticalSpinner = new JSpinner(vSpModel);
|
|
verticalSpinner.addChangeListener(new ChangeListener(){
|
|
@Override
|
|
public void stateChanged(ChangeEvent e){
|
|
JSpinner source = (JSpinner)e.getSource();
|
|
//Reporter.writeInfo("Y-Pos changed");
|
|
//if(source.isFocusOwner()){
|
|
double yps=((SpinnerNumberModel)source.getModel()).getNumber().doubleValue();
|
|
int index = lightsBox.getSelectedIndex();
|
|
LightBranchGroup light = sv.getLight(index);
|
|
if(light==null){
|
|
//Reporter.writeError("wrong light lindex!");
|
|
return;
|
|
}
|
|
light.setY(yps);
|
|
light.setEnable(true);
|
|
enableBox.setSelected(true);
|
|
//sv.setLightY(yps,index);
|
|
//Reporter.writeInfo("Y-Pos focused");
|
|
//}
|
|
}
|
|
});
|
|
|
|
((JSpinner.NumberEditor)verticalSpinner.getEditor()).getTextField().setColumns(SPINNER_COLUMN_SIZE);
|
|
constraint.gridy = 10;
|
|
verticalSpinner.setEnabled(false);
|
|
this.add(verticalSpinner,constraint);
|
|
|
|
// Spinner for Z position change
|
|
constraint.gridy = 11;
|
|
this.add(new JLabel("Z-Pos"),constraint);
|
|
|
|
SpinnerNumberModel dSpModel = new SpinnerNumberModel(0, Math.round(-Double.MAX_VALUE), Math.round(Double.MAX_VALUE),1);
|
|
depthSpinner = new JSpinner(dSpModel);
|
|
depthSpinner.addChangeListener(new ChangeListener(){
|
|
@Override
|
|
public void stateChanged(ChangeEvent e){
|
|
JSpinner source = (JSpinner)e.getSource();
|
|
//Reporter.writeInfo("Z-Pos changed");
|
|
//if(source.isFocusOwner()){
|
|
double zps=(int)((SpinnerNumberModel)source.getModel()).getNumber().doubleValue();
|
|
int index = lightsBox.getSelectedIndex();
|
|
LightBranchGroup light = sv.getLight(index);
|
|
if(light==null){
|
|
//Reporter.writeError("wrong light lindex!");
|
|
return;
|
|
}
|
|
light.setZ(zps);
|
|
light.setEnable(true);
|
|
enableBox.setSelected(true);
|
|
//sv.setLightZ(zps,index);
|
|
//Reporter.writeInfo("Z-Pos focused");
|
|
//}
|
|
}
|
|
});
|
|
|
|
|
|
((JSpinner.NumberEditor)depthSpinner.getEditor()).getTextField().setColumns(SPINNER_COLUMN_SIZE);
|
|
constraint.gridy = 12;
|
|
depthSpinner.setEnabled(false);
|
|
this.add(depthSpinner,constraint);
|
|
|
|
constraint.gridy = 13;
|
|
this.add(new JLabel("Position: 'Ctrl + mouse drag'"),constraint);
|
|
|
|
// Brightness adjuster
|
|
brightnessSlider = new JSlider(JSlider.HORIZONTAL, 0, LightBranchGroup.MAX_LEVEL, (LightBranchGroup.MAX_LEVEL/2));
|
|
brightnessSlider.addChangeListener(new ChangeListener(){
|
|
@Override
|
|
public void stateChanged(ChangeEvent e){
|
|
JSlider source = (JSlider)e.getSource();
|
|
if(!source.getValueIsAdjusting()){
|
|
int index = lightsBox.getSelectedIndex();
|
|
int brightness = (int)source.getValue();
|
|
LightBranchGroup light = sv.getLight(index);
|
|
if(light==null){
|
|
Reporter.showError("wrong light lindex!");
|
|
return;
|
|
}
|
|
light.setEnable(true);
|
|
enableBox.setSelected(true);
|
|
light.setBrightness(brightness);
|
|
//sv.setBrightness(brightness, index);
|
|
brightnessLabel.setText("Brightness: " + brightness);
|
|
|
|
}
|
|
}
|
|
});
|
|
constraint.gridy = 14;
|
|
brightnessSlider.setEnabled(false);
|
|
this.add(brightnessSlider,constraint);
|
|
|
|
constraint.gridy = 15;
|
|
brightnessLabel = new JLabel("Brightness: " + LightBranchGroup.MAX_LEVEL/2);
|
|
this.add(brightnessLabel,constraint);
|
|
|
|
radiusSlider = new JSlider(JSlider.HORIZONTAL, 0, Integer.MAX_VALUE, STARTING_RADIUS);
|
|
radiusSlider.addChangeListener(new ChangeListener(){
|
|
@Override
|
|
public void stateChanged(ChangeEvent e) {
|
|
JSlider source = (JSlider)e.getSource();
|
|
if (!source.getValueIsAdjusting()) {
|
|
int fps = (int)source.getValue();
|
|
int index = lightsBox.getSelectedIndex();
|
|
LightBranchGroup light = sv.getLight(index);
|
|
if(light==null){
|
|
Reporter.showError("wrong light lindex!");
|
|
return;
|
|
}
|
|
light.setArea(fps);
|
|
//sv.setLightArea(fps,index);
|
|
light.setEnable(true);
|
|
enableBox.setSelected(true);
|
|
radiusLabel.setText("radius: " + (int)light.getArea());
|
|
}
|
|
}
|
|
});
|
|
constraint.gridy = 16;
|
|
radiusSlider.setEnabled(false);
|
|
this.add(radiusSlider,constraint);
|
|
|
|
constraint.gridy = 17;
|
|
radiusLabel = new JLabel("radius: " + STARTING_RADIUS);
|
|
this.add(radiusLabel,constraint);
|
|
}
|
|
|
|
private Object makeObj(final String item) {
|
|
return new Object() { public String toString() { return item; } };
|
|
}
|
|
|
|
private void reset(){
|
|
enableBox.setSelected(true);
|
|
radiusSlider.setValue(STARTING_RADIUS);
|
|
brightnessSlider.setValue(LightBranchGroup.MAX_LEVEL/2);
|
|
verticalSpinner.setValue(0);
|
|
horizontalSpinner.setValue(0);
|
|
depthSpinner.setValue(0);
|
|
radiusLabel.setText("radius: " + STARTING_RADIUS);
|
|
brightnessLabel.setText("Brightness: " + LightBranchGroup.MAX_LEVEL/2);
|
|
|
|
}
|
|
|
|
private void setPanel(int index){
|
|
LightBranchGroup light = sv.getLight(index);
|
|
if(light==null)return;
|
|
sv.setLightMouseMove(index);
|
|
if(light==null){
|
|
Reporter.showError("wrong light lindex!");
|
|
return;
|
|
}
|
|
enableBox.setSelected(light.getEnable());
|
|
radiusSlider.setValue((int)light.getArea());
|
|
radiusLabel.setText("radius: " + (int)light.getArea());
|
|
brightnessSlider.setValue(light.getBrightness());
|
|
brightnessLabel.setText("Brightness: " + light.getBrightness());
|
|
verticalSpinner.setValue(light.getPosition().y);
|
|
horizontalSpinner.setValue(light.getPosition().x);
|
|
depthSpinner.setValue(light.getPosition().z);
|
|
|
|
}
|
|
|
|
/**
|
|
* set activate/deactivate panel
|
|
* @para on/off
|
|
*/
|
|
public void activate(boolean act){
|
|
enableBox.setEnabled(act);
|
|
//lightsBox.setEditable(act);
|
|
radiusSlider.setEnabled(act);
|
|
brightnessSlider.setEnabled(act);
|
|
colorButton.setEnabled(act);
|
|
delButton.setEnabled(act);
|
|
delAllButton.setEnabled(act);
|
|
verticalSpinner.setEnabled(act);
|
|
horizontalSpinner.setEnabled(act);
|
|
depthSpinner.setEnabled(act);
|
|
|
|
}
|
|
|
|
/**
|
|
* to set x-position value the light
|
|
* @param x value
|
|
*/
|
|
public void setX(double value){
|
|
((SpinnerNumberModel)horizontalSpinner.getModel()).setValue((double)value);
|
|
}
|
|
|
|
/**
|
|
* to set y-position value the light
|
|
* @param y value
|
|
*/
|
|
public void setY(double value){
|
|
((SpinnerNumberModel)verticalSpinner.getModel()).setValue((double)value);
|
|
}
|
|
|
|
/**
|
|
* to set z-position value the light
|
|
* @param z value
|
|
*/
|
|
public void setZ(double value){
|
|
((SpinnerNumberModel)depthSpinner.getModel()).setValue((double)value);
|
|
}
|
|
|
|
/**
|
|
* to set changefactor of x-movement
|
|
* @param factor
|
|
*/
|
|
public void setXChangeFactor(double factor){
|
|
xChangeFactor = factor;
|
|
}
|
|
|
|
/**
|
|
* to set changefactor of y-movement
|
|
* @param factor
|
|
*/
|
|
public void setYChangeFactor(double factor){
|
|
yChangeFactor = factor;
|
|
}
|
|
|
|
/**
|
|
* to set changefactor of z-movement
|
|
* @param factor
|
|
*/
|
|
public void setZChangeFactor(double factor){
|
|
zChangeFactor = factor;
|
|
}
|
|
|
|
/**
|
|
* getter changefactor of X
|
|
* @return change factor of x-movement
|
|
*/
|
|
public double getXChangeFactor(){
|
|
return xChangeFactor;
|
|
}
|
|
|
|
/**
|
|
* getter changefactor of Y movement
|
|
* @return change factor of y-movement
|
|
*/
|
|
public double getYChangeFactor(){
|
|
return yChangeFactor;
|
|
}
|
|
|
|
/**
|
|
* getter changefactor of Z movement
|
|
* @return change factor of z-movement
|
|
*/
|
|
public double getZChangeFactor(){
|
|
return zChangeFactor;
|
|
}
|
|
}
|