// Written by: Chris Weigle // Date: November 15, 2003 import java.awt.*; import java.applet.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import javax.swing.event.*; import java.util.*; /* SphereLight - illuminate a hemisphere on a plane. Light vector tracks the * mouse. View vector is fixed at z+. All calculations use the same light * vector (infinite light source) and the same view vector (infinite viewer). * It's faster, but still looks okay. */ public class SphereLightApplet extends JApplet { public void init() { final SphereLightPanel sp = new SphereLightPanel(); final JColorChooser chooser = new JColorChooser(); chooser.setPreviewPanel(new JPanel()); chooser.getSelectionModel().addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { chooser.getColor().getRGBColorComponents(sp.color); sp.illumination(); sp.repaint(); } }); JPanel panel = new JPanel(); panel.setLayout(new GridLayout(4, 2)); JLabel label = new JLabel("Ambient Term (ka):"); JFloatSlider slider = new JFloatSlider(0.f, 1.f, sp.ka, .2f); getContentPane().add(slider, BorderLayout.NORTH); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { JFloatSlider slider = (JFloatSlider)event.getSource(); if (!slider.getValueIsAdjusting()) { sp.ka = slider.getFloatValue(); sp.illumination(); sp.repaint(); } } }); panel.add(label); panel.add(slider); label = new JLabel("Diffuse Term (kd):"); slider = new JFloatSlider(0.f, 1.f, sp.kd, .2f); getContentPane().add(slider, BorderLayout.NORTH); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { JFloatSlider slider = (JFloatSlider)event.getSource(); if (!slider.getValueIsAdjusting()) { sp.kd = slider.getFloatValue(); sp.illumination(); sp.repaint(); } } }); panel.add(label); panel.add(slider); label = new JLabel("Specular Term (ks):"); slider = new JFloatSlider(0.f, 1.f, sp.ks, .2f); getContentPane().add(slider, BorderLayout.NORTH); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { JFloatSlider slider = (JFloatSlider)event.getSource(); if (!slider.getValueIsAdjusting()) { sp.ks = slider.getFloatValue(); sp.illumination(); sp.repaint(); } } }); panel.add(label); panel.add(slider); label = new JLabel("Specular Exponent (ksp):"); slider = new JFloatSlider(0.f, 50.f, sp.ksp, 10.f); getContentPane().add(slider, BorderLayout.NORTH); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { JFloatSlider slider = (JFloatSlider)event.getSource(); if (!slider.getValueIsAdjusting()) { sp.ksp = slider.getFloatValue(); sp.illumination(); sp.repaint(); } } }); panel.add(label); panel.add(slider); getContentPane().setLayout(new FlowLayout()); JTabbedPane tabs = new JTabbedPane(); tabs.addTab("Colors", chooser); tabs.addTab("Parameters", panel); getContentPane().add(sp); getContentPane().add(tabs); } class JFloatSlider extends JSlider { private final int SCALE = 100; public JFloatSlider(float min, float max, float init, float tick) { this.setPaintLabels(true); this.setPaintTicks(true); setMinimum((int)(min*SCALE)); setMaximum((int)(max*SCALE)); this.setValue((int)(init*SCALE)); Hashtable ht = new Hashtable(); for (float i = min; i <= max; i+=tick) { JLabel l = new JLabel(""+i); ht.put(new Integer((int)Math.rint(i*SCALE)), l); } this.setLabelTable(ht); this.setMinorTickSpacing((int)(tick * SCALE / 4)); } public float getFloatValue() { return (float)getValue()/(float)SCALE; } } }