import artofillusion.*; import java.awt.*; import java.awt.event.*; import java.io.*; public class PatchyFog extends Material3D { RGBColor color; float thickness, scattering; boolean shadows; public PatchyFog() { color = new RGBColor(1.0f, 1.0f, 1.0f); thickness = 0.5f; scattering = 0.0f; shadows = false; } public static String getTypeName() { return "Patchy Fog"; } public void getMaterialSpec(MaterialSpec spec, double x, double y, double z, double xsize, double ysize, double zsize, double t) { double size = 1.0, scale = 1.0; float d = 0.0f; for (int i = 0; i < 3 && xsize < size && ysize < size && zsize < size; i++) { d += (float) (size*Noise.value(x*scale+123.456, y*scale+123.456, z*scale+123.456)); size *= 0.5; scale *= 2.0; } d = 0.5f*d + 1.0f - thickness; if (d > 1.0f) d = 1.0f; else if (d < 0.0f) d = 0.0f; spec.transparency.setRGB(d, d, d); spec.color.copy(color); if (scattering > 0.0f) { d = scattering*(1.0f-d); spec.scattering.setRGB(d, d, d); spec.eccentricity = 0.0; } } public boolean isScattering() { return (scattering > 0.0f); } public boolean castsShadows() { return shadows; } public Material duplicate() { PatchyFog mat = new PatchyFog(); mat.color.copy(color); mat.thickness = thickness; mat.scattering = scattering; mat.shadows = shadows; return mat; } public void edit(java.awt.Frame fr, Scene sc) { RGBColor oldColor = color.duplicate(); float oldThickness = thickness, oldScattering = scattering; boolean oldShadows = shadows; final Panel colorPatch = color.getSample(50, 30); final ValueSlider thicknessSlider = new ValueSlider(0.0, 1.0, 100, thickness); final ValueSlider scatteringSlider = new ValueSlider(0.0, 1.0, 100, scattering); final Checkbox shadowBox = new Checkbox("Casts Shadows", shadows); final MaterialPreviewer preview = new MaterialPreviewer(null, this, 200, 160); final Frame parent = fr; TextField nameField = new TextField(getName()); ComponentsDialog dlg; colorPatch.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { new ColorChooser(parent, "Fog Color", color); colorPatch.setBackground(color.getColor()); colorPatch.repaint(); preview.render(); } }); thicknessSlider.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { thickness = (float) thicknessSlider.getValue(); preview.render(); } }); scatteringSlider.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { scattering = (float) scatteringSlider.getValue(); preview.render(); } }); shadowBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { shadows = shadowBox.getState(); preview.render(); } }); dlg = new ComponentsDialog(parent, getName(), new Component [] {preview, nameField, colorPatch, thicknessSlider, scatteringSlider, shadowBox}, new String [] {"", "Name", "Fog Color", "Thickness", "Scattering", ""}); if (!dlg.clickedOk()) { color.copy(oldColor); thickness = oldThickness; scattering = oldScattering; shadows = oldShadows; } else setName(nameField.getText()); } public PatchyFog(DataInputStream in, Scene theScene) throws IOException, InvalidObjectException { setName(in.readUTF()); color = new RGBColor(in); thickness = in.readFloat(); scattering = in.readFloat(); shadows = in.readBoolean(); } public void writeToFile(DataOutputStream out, Scene theScene) throws IOException { out.writeUTF(getName()); color.writeToFile(out); out.writeFloat(thickness); out.writeFloat(scattering); out.writeBoolean(shadows); } }