Package org.jwildfire.transform

Source Code of org.jwildfire.transform.Mesh3DTransformer$LightEditor

/*
  JWildfire - an image and animation processor written in Java
  Copyright (C) 1995-2011 Andreas Maschke

  This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
  General Public License as published by the Free Software Foundation; either version 2.1 of the
  License, or (at your option) any later version.
  This software 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License along with this software;
  if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jwildfire.transform;

import java.awt.Color;
import java.awt.image.BufferedImage;

import org.jwildfire.base.Property;
import org.jwildfire.base.PropertyCategory;
import org.jwildfire.base.PropertyMax;
import org.jwildfire.base.PropertyMin;
import org.jwildfire.base.mathlib.MathLib;
import org.jwildfire.image.Pixel;
import org.jwildfire.image.SimpleImage;
import org.jwildfire.image.WFImage;
import org.jwildfire.swing.Buffer.BufferType;

import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;

public abstract class Mesh3DTransformer extends Transformer {

  public enum Rotate {
    XY, YZ, XZ, NONE
  }

  public enum Light {
    NORMAL, PHONG, OFF
  };

  public enum Faces {
    NORMAL, DOUBLE, MIRRORED
  };

  @Property(category = PropertyCategory.RENDERING, description = "Type of shading", editorClass = LightEditor.class)
  protected Light light = Light.NORMAL;

  @Property(category = PropertyCategory.RENDERING, description = "Treat faces as single or double sided", editorClass = FacesEditor.class)
  protected Faces faces = Faces.NORMAL;

  @Property(category = PropertyCategory.RENDERING, description = "Rotation mode", editorClass = RotateEditor.class)
  protected Rotate doRotate = Rotate.XY;

  @Property(category = PropertyCategory.RENDERING, description = "Rotation angle alpha")
  @PropertyMin(-360)
  @PropertyMax(360)
  protected double alpha = 30.0;

  @Property(category = PropertyCategory.RENDERING, description = "Rotation angle beta")
  @PropertyMin(-360)
  @PropertyMax(360)
  protected double beta = 60.0;

  @Property(category = PropertyCategory.RENDERING, description = "Object zoom factor")
  @PropertyMin(0.01)
  @PropertyMax(10.0)
  protected double zoom = 1.40;

  @Property(category = PropertyCategory.RENDERING, description = "Detail of the generated 3d-object (higher value -> less detail <-> better performance)")
  @PropertyMin(0.01)
  @PropertyMax(10.0)
  protected double quant3D = 1.0;

  @Property(category = PropertyCategory.RENDERING, description = "X-coordinate of the object centre")
  protected double centreX = 350.0;

  @Property(category = PropertyCategory.RENDERING, description = "Y-coordinate of the object centre")
  protected double centreY = 400.0;

  @Property(category = PropertyCategory.RENDERING, description = "Simulate camera view (perspective)")
  protected boolean doCam = true;

  @Property(category = PropertyCategory.RENDERING, description = "X-coordinate of the camera position")
  protected double camX = 0.0;

  @Property(category = PropertyCategory.RENDERING, description = "Y-coordinate of the camera position")
  protected double camY = 0.0;

  @Property(category = PropertyCategory.RENDERING, description = "Z-coordinate of the camera position")
  protected double camZ = -1000.0;

  @Property(category = PropertyCategory.RENDERING, description = "X-coordinate of the 1st light source")
  protected double light1X = -200.0;

  @Property(category = PropertyCategory.RENDERING, description = "Y-coordinate of the 1st light source")
  protected double light1Y = 100.0;

  @Property(category = PropertyCategory.RENDERING, description = "Z-coordinate of the 1st light source")
  protected double light1Z = -600.0;

  @Property(category = PropertyCategory.RENDERING, description = "Color of the 1st light source")
  protected Color light1Color = new Color(255, 255, 255);

  @Property(category = PropertyCategory.RENDERING, description = "X-coordinate of the 2nd light source")
  protected double light2X = 200.0;

  @Property(category = PropertyCategory.RENDERING, description = "Y-coordinate of the 2nd light source")
  protected double light2Y = 100.0;

  @Property(category = PropertyCategory.RENDERING, description = "Z-coordinate of the 2nd light source")
  protected double light2Z = -600.0;

  @Property(category = PropertyCategory.RENDERING, description = "Color of the 2nd light source")
  protected Color light2Color = new Color(0, 0, 0);

  @Property(category = PropertyCategory.RENDERING, description = "X-coordinate of the 3rd light source")
  protected double light3X = -200.0;

  @Property(category = PropertyCategory.RENDERING, description = "Y-coordinate of the 3rd light source")
  protected double light3Y = -100.0;

  @Property(category = PropertyCategory.RENDERING, description = "Z-coordinate of the 3rd light source")
  protected double light3Z = -600.0;

  @Property(category = PropertyCategory.RENDERING, description = "Color of the 3rd light source")
  protected Color light3Color = new Color(0, 0, 0);

  @Property(category = PropertyCategory.RENDERING, description = "X-coordinate of the 4th light source")
  protected double light4X = 200.0;

  @Property(category = PropertyCategory.RENDERING, description = "Y-coordinate of the 4th light source")
  protected double light4Y = -100.0;

  @Property(category = PropertyCategory.RENDERING, description = "Z-coordinate of the 4th light source")
  protected double light4Z = -600.0;

  @Property(category = PropertyCategory.RENDERING, description = "Color of the 4th light source")
  protected Color light4Color = new Color(0, 0, 0);

  @Property(category = PropertyCategory.RENDERING, description = "Ambient light intensity")
  @PropertyMin(0.0)
  @PropertyMax(1.0)
  protected double ambient = 0.06;

  @Property(category = PropertyCategory.RENDERING, description = "Diffuse light intensity")
  @PropertyMin(0.0)
  @PropertyMax(1.0)
  protected double diffuse = 0.94;

  @Property(category = PropertyCategory.RENDERING, description = "Phong light intensity")
  @PropertyMin(0.0)
  @PropertyMax(1.0)
  protected double phong = 0.900;

  @Property(category = PropertyCategory.RENDERING, description = "Sharpness of the phong spot size (the higher the value the more the sharpness)")
  @PropertyMin(0.0)
  protected double phongSize = 30.00;

  @Property(category = PropertyCategory.RENDERING, description = "Phong angle")
  @PropertyMin(-360.0)
  @PropertyMax(360.0)
  protected double phongAngle = 60.00;

  @Property(description = "Smoothing amount", category = PropertyCategory.SECONDARY)
  private int smoothing = 1;

  @Property(description = "Image scale", category = PropertyCategory.SECONDARY)
  private double imgScale = 1.0;

  protected abstract void transformMesh(Mesh3D pMesh3D, int pImageWidth, int pImageHeight);

  private Mesh3D inputMesh3D;
  private Mesh3D outputMesh3D;

  @Override
  public void setInputMesh3D(Mesh3D pInputMesh3D) {
    inputMesh3D = pInputMesh3D;
  }

  @Override
  public Mesh3D getOutputMesh3D(boolean pRemoveOwnReference) {
    Mesh3D res = outputMesh3D;
    if (pRemoveOwnReference)
      outputMesh3D = null;
    return res;
  }

  protected void createMeshFromImage(Mesh3D pMesh3D, SimpleImage pImg, double pQuant3D) {
    pMesh3D.readPixels(pImg, pQuant3D);
  }

  @Override
  protected void performImageTransformation(WFImage pImg) {
    Mesh3D lInputMesh3D;
    SimpleImage img = (SimpleImage) pImg;
    if (inputMesh3D == null) {
      lInputMesh3D = new Mesh3D();
      createMeshFromImage(lInputMesh3D, img, quant3D);
    }
    else {
      lInputMesh3D = inputMesh3D.clone();
    }
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    transformMesh(lInputMesh3D, width, height);
    if (storeMesh3D) {
      this.outputMesh3D = lInputMesh3D.clone();
      this.outputMesh3D.setLastTransformation(this);
    }
    transform3D(lInputMesh3D, width, height);
    img.fillBackground(0, 0, 0);
    render3D(lInputMesh3D, img);
    applySmoothing(img, smoothing);
    lInputMesh3D = null;
    inputMesh3D = null;
  }

  private void transform3D(Mesh3D pMesh3D, int pWidth, int pHeight) {
    /* check the parameters */
    int width = pWidth;
    int height = pHeight;
    int pCount = pMesh3D.getPCount();
    double zeroX = (double) centreX - (double) width / 2.0;
    double zeroY = (double) centreY - (double) height / 2.0;
    if ((Math.abs(alpha) <= MathLib.EPSILON) && (Math.abs(beta) <= MathLib.EPSILON))
      doRotate = Rotate.NONE;
    boolean doZoom = Math.abs(zoom - 1.0) > MathLib.EPSILON;
    double x[] = pMesh3D.getX();
    double y[] = pMesh3D.getY();
    double z[] = pMesh3D.getZ();

    /*  rotate it */
    if (doRotate != Rotate.NONE) {
      double alpha = this.alpha * Math.PI / 180.0;
      double beta = this.beta * Math.PI / 180.0;
      double sinA = Math.sin(alpha);
      double cosA = Math.cos(alpha);
      double sinB = Math.sin(beta);
      double cosB = Math.cos(beta);

      if (doRotate == Rotate.XY) {
        double sinBsinA = sinB * sinA;
        double cosBsinA = cosB * sinA;
        double sinBcosA = sinB * cosA;
        double cosBcosA = cosB * cosA;
        for (int i = 0; i < pCount; i++) {
          double dx = x[i] - zeroX;
          double dy = y[i] - zeroY;
          double dz = z[i];
          x[i] = cosA * dx - sinBsinA * dy + cosBsinA * dz + zeroX;
          y[i] = cosB * dy + sinB * dz + zeroY;
          z[i] = -sinA * dx - sinBcosA * dy + cosBcosA * dz;
        }
      }
      else if (doRotate == Rotate.YZ) {
        double cosAcosB = cosA * cosB;
        double sinAcosB = sinA * cosB;
        double cosAsinB = cosA * sinB;
        double sinAsinB = sinA * sinB;
        for (int i = 0; i < pCount; i++) {
          double dx = x[i] - zeroX;
          double dy = y[i] - zeroY;
          double dz = z[i];
          x[i] = cosAcosB * dx + sinAcosB * dy + sinB * dz + zeroX;
          y[i] = -sinA * dx + cosA * dy + zeroY;
          z[i] = -cosAsinB * dx - sinAsinB * dy + cosB * dz;
        }
      }
      else if (doRotate == Rotate.XZ) {
        double cosBsinA = cosB * sinA;
        double sinBsinA = sinB * sinA;
        double cosBcosA = cosB * cosA;
        double sinBcosA = sinB * cosA;
        for (int i = 0; i < pCount; i++) {
          double dx = x[i] - zeroX;
          double dy = y[i] - zeroY;
          double dz = z[i];
          x[i] = cosA * dx + cosBsinA * dy + sinBsinA * dz + zeroX;
          y[i] = -sinA * dx + cosBcosA * dy + sinBcosA * dz + zeroY;
          z[i] = -sinB * dy + cosB * dz;
        }
      }
    }
    /* zoom it */
    if (doZoom) {
      double zoom = this.zoom;
      for (int i = 0; i < pCount; i++) {
        double dx = x[i] - zeroX;
        double dy = y[i] - zeroY;
        x[i] = dx * zoom + zeroX;
        y[i] = dy * zoom + zeroY;
        z[i] *= zoom;
      }
    }
    /* add camera */
    if (doCam) {
      double camX = this.camX;
      double camY = this.camY;
      double camZ = this.camZ;
      if (camZ > (-50.0))
        camZ = -50.0;
      for (int i = 0; i < pCount; i++) {
        double dx = x[i];
        double dy = y[i];
        double dz = z[i];
        dx -= camX;
        dy += camY;
        double ttf = camZ / ((double) camZ - dz);
        dx *= ttf;
        dy *= ttf;
        dz *= ttf;
        x[i] = dx;
        y[i] = dy;
        z[i] = dz;
      }
    }
  }

  private void render3D(Mesh3D pMesh3D, SimpleImage pImg) {

    Mesh3DRenderer renderer;
    if (light != Light.PHONG)
      renderer = new Simple3DRenderer();
    else
      renderer = new Phong3DRenderer();
    if (Math.abs(imgScale - 1.0) > MathLib.EPSILON) {
      // scaled image
      int width = (int) ((double) pImg.getImageWidth() * imgScale + 0.5);
      int height = (int) ((double) pImg.getImageHeight() * imgScale + 0.5);
      BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      pImg.setBufferedImage(img, width, height);
      // scaled mesh
      Mesh3D mesh3D = pMesh3D.clone(imgScale);
      // scaled params
      double oCentreX = centreX;
      double oCentreY = centreY;
      double oCamX = camX;
      double oCamY = camY;
      double oCamZ = camZ;
      double oLight1X = light1X;
      double oLight1Y = light1Y;
      double oLight1Z = light1Z;
      double oLight2X = light2X;
      double oLight2Y = light2Y;
      double oLight2Z = light2Z;
      double oLight3X = light3X;
      double oLight3Y = light3Y;
      double oLight3Z = light3Z;
      double oLight4X = light4X;
      double oLight4Y = light4Y;
      double oLight4Z = light4Z;
      double oPhongSize = phongSize;
      try {
        oCentreX *= imgScale;
        oCentreY *= imgScale;
        oCamX *= imgScale;
        oCamY *= imgScale;
        oCamZ *= imgScale;
        oLight1X *= imgScale;
        oLight1Y *= imgScale;
        oLight1Z *= imgScale;
        oLight2X *= imgScale;
        oLight2Y *= imgScale;
        oLight2Z *= imgScale;
        oLight3X *= imgScale;
        oLight3Y *= imgScale;
        oLight3Z *= imgScale;
        oLight4X *= imgScale;
        oLight4Y *= imgScale;
        oLight4Z *= imgScale;
        oPhongSize *= imgScale;
        // render
        renderer.renderImage(mesh3D, this, pImg);
      }
      finally {
        // reset params
        centreX = oCentreX;
        centreY = oCentreY;
        camX = oCamX;
        camY = oCamY;
        camZ = oCamZ;
        light1X = oLight1X;
        light1Y = oLight1Y;
        light1Z = oLight1Z;
        light2X = oLight2X;
        light2Y = oLight2Y;
        light2Z = oLight2Z;
        light3X = oLight3X;
        light3Y = oLight3Y;
        light3Z = oLight3Z;
        light4X = oLight4X;
        light4Y = oLight4Y;
        light4Z = oLight4Z;
        phongSize = oPhongSize;
      }
    }
    else {

      renderer.renderImage(pMesh3D, this, pImg);
    }

    /*

    {*/
    /* antialiasing */
    /*    
          if(r3dSmoothing!=0) {
           UBYTE r1,r2,r3,g1,g2,g3,b1,b2,b3,r,g,b,*dred,*dgreen,*dblue;
           WORD av1,av2,av3,av,d1,d2,d3,rw1,k;
           ULONG rv,gv,bv;
           #ifdef SDEBUG
           ULONG pixels;
           #endif
           rw1=width16-width+1;
           for(k=0;k<r3dSmoothing;k++) {
           dred=red;
           dgreen=green;
           dblue=blue;
           #ifdef SDEBUG
           pixels=0;
           #endif
           // copy 1st line
           dred+=width16;dgreen+=width16;dblue+=width16;
           for(i=1;i<(height-1);i++) {
            // copy last pixel
            dred++;dgreen++;dblue++;
            // process pixels 2..width-1
            for(j=1;j<(width-1);j++) {
             r1=*(dred-width16);g1=*(dgreen-width16);b1=*(dblue-width16);
             r2=*(dred+1);g2=*(dgreen+1);b2=*(dblue+1);
             r3=*(dred+width16);g3=*(dgreen+width16);b3=*(dblue+width16);
             r=*(dred);g=*(dgreen);b=*(dblue);

             av1=((WORD)r1+(WORD)g1+(WORD)b1);av2=((WORD)r2+(WORD)g2+(WORD)b2);
             av3=((WORD)r3+(WORD)g3+(WORD)b3);av=((WORD)r+(WORD)g+(WORD)b);

             d1=av1-av;if(d1<0) d1=0-d1;d2=av2-av;if(d2<0) d2=0-d2;d3=av3-av;if(d3<0) d3=0-d3;

             if((d1>64) && (d2>64)) {
              rv=(LONG)r1*(LONG)d1+(LONG)r2*(LONG)d2;
              rv/=(LONG)(d1+d2);rv+=(WORD)r;rv/=2;
              gv=(LONG)g1*(LONG)d1+(LONG)g2*(LONG)d2;
              gv/=(LONG)(d1+d2);gv+=(WORD)g;gv/=2;
              bv=(LONG)b1*(LONG)d1+(LONG)b2*(LONG)d2;
              bv/=(LONG)(d1+d2);bv+=(WORD)b;bv/=2;
              *dred++=(UBYTE)rv;*dgreen++=(UBYTE)gv;*dblue++=(UBYTE)bv;
              #ifdef SDEBUG
              pixels++;
              #endif
             }
             else if((d2>64) && (d3>64)) {
              rv=(LONG)r2*(LONG)d2+(LONG)r3*(LONG)d3;
              rv/=(LONG)(d2+d3);rv+=(WORD)r;rv/=2;
              gv=(LONG)g2*(LONG)d2+(LONG)g3*(LONG)d3;
              gv/=(LONG)(d2+d3);gv+=(WORD)g;gv/=2;
              bv=(LONG)b2*(LONG)d2+(LONG)b3*(LONG)d3;
              bv/=(LONG)(d2+d3);bv+=(WORD)b;bv/=2;
              *dred++=(UBYTE)rv;*dgreen++=(UBYTE)gv;*dblue++=(UBYTE)bv;
              #ifdef SDEBUG
              pixels++;
              #endif
             }
             else {
              *dred++;*dgreen++;*dblue++;
             }
            }
            // copy last pixel
            dred+=rw1;dgreen+=rw1;dblue+=rw1;
           }
           #ifdef SDEBUG
           printf("pixels: %ld\n",pixels);
           #endif
          }
          }
         }
    */

  }

  @Override
  public void initDefaultParams(WFImage pImg) {
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    double rr = Math.sqrt(width * width + height * height);
    light = Light.NORMAL;
    faces = Faces.NORMAL;
    doRotate = Rotate.XY;
    alpha = 30.0;
    beta = 40.0;
    zoom = 1.40;
    quant3D = 1.0;
    centreX = Math.round((double) width / 2.05);
    centreY = Math.round((double) height / 1.95);
    doCam = true;
    camX = Math.round(0.005 * rr);
    camY = Math.round(-0.01 * rr);
    camZ = Math.round(-4.0 * rr);
    light1X = -200.0;
    light1Y = 100.0;
    light1Z = -600.0;
    light1Color = new Color(255, 255, 255);
    light2X = 200.0;
    light2Y = 100.0;
    light2Z = -600.0;
    light2Color = new Color(0, 0, 0);
    light3X = -200.0;
    light3Y = -100.0;
    light3Z = -600.0;
    light3Color = new Color(0, 0, 0);
    light4X = 200.0;
    light4Y = -100.0;
    light4Z = -600.0;
    light4Color = new Color(0, 0, 0);
    ambient = 0.06;
    diffuse = 0.94;
    phong = 0.900;
    phongSize = Math.round(rr / 20.0);
    phongAngle = 60.00;
    smoothing = 1;
    imgScale = 1.0;
  }

  @Override
  public boolean acceptsInputBufferType(BufferType pBufferType) {
    return (pBufferType == BufferType.IMAGE) || (pBufferType == BufferType.MESH3D);
  }

  public Light getLight() {
    return light;
  }

  public void setLight(Light light) {
    this.light = light;
  }

  public Faces getFaces() {
    return faces;
  }

  public void setFaces(Faces faces) {
    this.faces = faces;
  }

  public Rotate getDoRotate() {
    return doRotate;
  }

  public void setDoRotate(Rotate doRotate) {
    this.doRotate = doRotate;
  }

  public double getAlpha() {
    return alpha;
  }

  public void setAlpha(double alpha) {
    this.alpha = alpha;
  }

  public double getBeta() {
    return beta;
  }

  public void setBeta(double beta) {
    this.beta = beta;
  }

  public double getZoom() {
    return zoom;
  }

  public void setZoom(double zoom) {
    this.zoom = zoom;
  }

  public double getQuant3D() {
    return quant3D;
  }

  public void setQuant3D(double quant3d) {
    quant3D = quant3d;
  }

  public double getCentreX() {
    return centreX;
  }

  public void setCentreX(double centreX) {
    this.centreX = centreX;
  }

  public double getCentreY() {
    return centreY;
  }

  public void setCentreY(double centreY) {
    this.centreY = centreY;
  }

  public boolean isDoCam() {
    return doCam;
  }

  public void setDoCam(boolean doCam) {
    this.doCam = doCam;
  }

  public double getCamX() {
    return camX;
  }

  public void setCamX(double camX) {
    this.camX = camX;
  }

  public double getCamY() {
    return camY;
  }

  public void setCamY(double camY) {
    this.camY = camY;
  }

  public double getCamZ() {
    return camZ;
  }

  public void setCamZ(double camZ) {
    this.camZ = camZ;
  }

  public double getLight1X() {
    return light1X;
  }

  public void setLight1X(double light1x) {
    light1X = light1x;
  }

  public double getLight1Y() {
    return light1Y;
  }

  public void setLight1Y(double light1y) {
    light1Y = light1y;
  }

  public double getLight1Z() {
    return light1Z;
  }

  public void setLight1Z(double light1z) {
    light1Z = light1z;
  }

  public Color getLight1Color() {
    return light1Color;
  }

  public void setLight1Color(Color light1Color) {
    this.light1Color = light1Color;
  }

  public double getLight2X() {
    return light2X;
  }

  public void setLight2X(double light2x) {
    light2X = light2x;
  }

  public double getLight2Y() {
    return light2Y;
  }

  public void setLight2Y(double light2y) {
    light2Y = light2y;
  }

  public double getLight2Z() {
    return light2Z;
  }

  public void setLight2Z(double light2z) {
    light2Z = light2z;
  }

  public Color getLight2Color() {
    return light2Color;
  }

  public void setLight2Color(Color light2Color) {
    this.light2Color = light2Color;
  }

  public double getLight3X() {
    return light3X;
  }

  public void setLight3X(double light3x) {
    light3X = light3x;
  }

  public double getLight3Y() {
    return light3Y;
  }

  public void setLight3Y(double light3y) {
    light3Y = light3y;
  }

  public double getLight3Z() {
    return light3Z;
  }

  public void setLight3Z(double light3z) {
    light3Z = light3z;
  }

  public Color getLight3Color() {
    return light3Color;
  }

  public void setLight3Color(Color light3Color) {
    this.light3Color = light3Color;
  }

  public double getLight4X() {
    return light4X;
  }

  public void setLight4X(double light4x) {
    light4X = light4x;
  }

  public double getLight4Y() {
    return light4Y;
  }

  public void setLight4Y(double light4y) {
    light4Y = light4y;
  }

  public double getLight4Z() {
    return light4Z;
  }

  public void setLight4Z(double light4z) {
    light4Z = light4z;
  }

  public Color getLight4Color() {
    return light4Color;
  }

  public void setLight4Color(Color light4Color) {
    this.light4Color = light4Color;
  }

  public double getAmbient() {
    return ambient;
  }

  public void setAmbient(double ambient) {
    this.ambient = ambient;
  }

  public double getDiffuse() {
    return diffuse;
  }

  public void setDiffuse(double diffuse) {
    this.diffuse = diffuse;
  }

  public double getPhong() {
    return phong;
  }

  public void setPhong(double phong) {
    this.phong = phong;
  }

  public double getPhongSize() {
    return phongSize;
  }

  public void setPhongSize(double phongSize) {
    this.phongSize = phongSize;
  }

  public double getPhongAngle() {
    return phongAngle;
  }

  public void setPhongAngle(double phongAngle) {
    this.phongAngle = phongAngle;
  }

  public static class RotateEditor extends ComboBoxPropertyEditor {
    public RotateEditor() {
      super();
      setAvailableValues(new Rotate[] { Rotate.XY, Rotate.YZ, Rotate.XZ, Rotate.NONE });
    }
  }

  public static class LightEditor extends ComboBoxPropertyEditor {
    public LightEditor() {
      super();
      setAvailableValues(new Light[] { Light.NORMAL, Light.PHONG, Light.OFF });
    }
  }

  public static class FacesEditor extends ComboBoxPropertyEditor {
    public FacesEditor() {
      super();
      setAvailableValues(new Faces[] { Faces.NORMAL, Faces.DOUBLE, Faces.MIRRORED });
    }
  }

  @Override
  public boolean supports3DOutput() {
    return true;
  }

  protected void applySmoothing(SimpleImage pImg, int pSmoothingAmount) {
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    Pixel pixel = new Pixel();
    for (int k = 0; k < pSmoothingAmount; k++) {
      for (int i = 1; i < (height - 1); i++) {
        /* process pixels 2..width-1 */
        for (int j = 1; j < (width - 1); j++) {
          pixel.setARGBValue(pImg.getARGBValue(j, i - 1));
          int r1 = pixel.r;
          int g1 = pixel.g;
          int b1 = pixel.b;
          pixel.setARGBValue(pImg.getARGBValue(j + 1, i));
          int r2 = pixel.r;
          int g2 = pixel.g;
          int b2 = pixel.b;
          pixel.setARGBValue(pImg.getARGBValue(j, i + 1));
          int r3 = pixel.r;
          int g3 = pixel.g;
          int b3 = pixel.b;
          pixel.setARGBValue(pImg.getARGBValue(j, i));
          int r = pixel.r;
          int g = pixel.g;
          int b = pixel.b;

          int av1 = (r1 + g1 + b1);
          int av2 = (r2 + g2 + b2);
          int av3 = (r3 + g3 + b3);
          int av = (r + g + b);

          int d1 = av1 - av;
          if (d1 < 0)
            d1 = 0 - d1;
          int d2 = av2 - av;
          if (d2 < 0)
            d2 = 0 - d2;
          int d3 = av3 - av;
          if (d3 < 0)
            d3 = 0 - d3;

          if ((d1 > 64) && (d2 > 64)) {
            int rv = r1 * d1 + r2 * d2;
            rv /= (d1 + d2);
            rv += r;
            rv /= 2;
            int gv = g1 * d1 + g2 * d2;
            gv /= (d1 + d2);
            gv += g;
            gv /= 2;
            int bv = b1 * d1 + b2 * d2;
            bv /= (d1 + d2);
            bv += b;
            bv /= 2;
            pImg.setRGB(j, i, rv, gv, bv);
          }
          else if ((d2 > 64) && (d3 > 64)) {
            int rv = r2 * d2 + r3 * d3;
            rv /= (d2 + d3);
            rv += r;
            rv /= 2;
            int gv = g2 * d2 + g3 * d3;
            gv /= (d2 + d3);
            gv += g;
            gv /= 2;
            int bv = b2 * d2 + b3 * d3;
            bv /= (d2 + d3);
            bv += b;
            bv /= 2;
            pImg.setRGB(j, i, rv, gv, bv);
          }
        }
      }
    }
  }

  public int getSmoothing() {
    return smoothing;
  }

  public void setSmoothing(int smoothing) {
    this.smoothing = smoothing;
  }

  public double getImgScale() {
    return imgScale;
  }

  public void setImgScale(double imgScale) {
    this.imgScale = imgScale;
  }

}
TOP

Related Classes of org.jwildfire.transform.Mesh3DTransformer$LightEditor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.