Package org.jwildfire.create.tina.render

Source Code of org.jwildfire.create.tina.render.Pseudo3DShader

/*
  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.create.tina.render;

import org.jwildfire.base.Tools;
import org.jwildfire.base.mathlib.MathLib;
import org.jwildfire.create.tina.base.ShadingInfo;
import org.jwildfire.create.tina.base.XYZPoint;
import org.jwildfire.create.tina.palette.RenderColor;

// TODO really a quick hack, copied the ugly shading stuff from the Mesh3DRenderer
public class Pseudo3DShader {
  // internal stuff
  private double reff, refx, refy, refz;
  private double nfx, nfy, nfz;
  private int r, g, b, pb, pr, pg;
  private final ShadingInfo shadingInfo;
  // derived from shadingInfo
  private final int MAXLIGHTS = 4;
  private double lightX[] = new double[MAXLIGHTS];
  private double lightY[] = new double[MAXLIGHTS];
  private double lightZ[] = new double[MAXLIGHTS];
  private double lightRed[] = new double[MAXLIGHTS];
  private double lightGreen[] = new double[MAXLIGHTS];
  private double lightBlue[] = new double[MAXLIGHTS];
  private int lightCount;
  private double ambient;
  private double diffuse;
  private double phong;
  private double phongSize;
  //
  protected final int PASIZE = 4096;
  protected double dPhong = 0.0;
  protected double phongArray[] = new double[PASIZE + 4];

  public Pseudo3DShader(ShadingInfo pShadingInfo) {
    shadingInfo = pShadingInfo;
  }

  public void init() {
    ambient = shadingInfo.getAmbient();
    diffuse = shadingInfo.getDiffuse();
    phong = shadingInfo.getPhong();
    phongSize = shadingInfo.getPhongSize();
    lightCount = 0;
    for (int i = 0; i < shadingInfo.getLightRed().length && lightCount < lightRed.length; i++) {
      if (shadingInfo.getLightRed()[i] > 0 || shadingInfo.getLightGreen()[i] > 0 || shadingInfo.getLightBlue()[i] > 0) {
        lightX[lightCount] = shadingInfo.getLightPosX()[i];
        lightY[lightCount] = shadingInfo.getLightPosY()[i];
        lightZ[lightCount] = shadingInfo.getLightPosZ()[i];
        lightRed[lightCount] = (double) shadingInfo.getLightRed()[i] / 255.0;
        lightGreen[lightCount] = (double) shadingInfo.getLightGreen()[i] / 255.0;
        lightBlue[lightCount] = (double) shadingInfo.getLightBlue()[i] / 255.0;
        lightCount++;
      }
    }
    initPhongArray(phong, phongSize);
  }

  protected void initPhongArray(double pPhong, double pPhongSize) {
    dPhong = 1.0 / (double) (PASIZE - 1);
    double a = 0.0;
    for (int i = 0; i < (PASIZE + 4); i++) {
      phongArray[i] = pPhong * Math.pow(a, pPhongSize);
      a += dPhong;
    }
  }

  protected double phongInt(double cosa) {
    return phongArray[(int) (cosa / dPhong + 0.5)];
  }

  public void distributeInitialPoints(XYZPoint[] p) {
    p[1].x = p[0].x + 0.001;
    p[1].y = p[0].y;
    p[1].z = p[0].z;
    p[2].x = p[0].x;
    p[2].y = p[0].y + 0.001;
    p[2].z = p[0].z;
  }

  public RenderColor calculateColor(XYZPoint[] pP, RenderColor pColor) {
    double vax = pP[1].x - pP[0].x;
    double vay = pP[1].y - pP[0].y;
    double vaz = pP[1].z - pP[0].z;
    double vbx = pP[2].x - pP[0].x;
    double vby = pP[2].y - pP[0].y;
    double vbz = pP[2].z - pP[0].z;
    nfx = vay * vbz - vaz * vby;
    nfy = vaz * vbx - vax * vbz;
    nfz = vax * vby - vay * vbx;
    double rr = Math.sqrt(nfx * nfx + nfy * nfy + nfz * nfz);
    if (Math.abs(rr) < MathLib.EPSILON) {
      nfx = pP[0].x;
      nfy = pP[0].y;
      nfz = pP[0].z;
      rr = Math.sqrt(nfx * nfx + nfy * nfy + nfz * nfz);
    }
    if (Math.abs(rr) < MathLib.EPSILON) {
      nfx = nfy = 0.0;
      nfz = -1.0;
    }
    else {
      nfx = 0.0 - nfx / rr;
      nfy = 0.0 - nfy / rr;
      nfz = 0.0 - nfz / rr;
    }

    reflectViewVector();
    // TODO
    //    double cosa = 0.0 - nfz;
    //    if (cosa >= 0.0) {
    //      nfx = 0.0 - nfx;
    //      nfy = 0.0 - nfy;
    //      nfz = 0.0 - nfz;
    //      reflectViewVector();
    //      cosa = 0.0 - nfz;
    //    }

    this.r = Tools.FTOI(pColor.red);
    this.g = Tools.FTOI(pColor.green);
    this.b = Tools.FTOI(pColor.blue);
    addLight(pP[0].x, pP[0].y, pP[0].z);

    RenderColor res = new RenderColor();
    res.red = pr;
    res.green = pg;
    res.blue = pb;
    return res;
  }

  private static double VIEWZ = -1.0;

  protected void reflectViewVector() {

    reff = nfz + nfz;
    refx = reff * nfx;
    refy = reff * nfy;
    refz = reff * nfz - VIEWZ;
    double rr = Math.sqrt(refx * refx + refy * refy + refz * refz);
    if (Math.abs(rr) < MathLib.EPSILON) {
      refx = refy = refz = 0;
    }
    else {
      refx /= rr;
      refy /= rr;
      refz /= rr;
    }
  }

  protected void addLight(double px, double py, double pz) {
    double ttfr = 0.0, ttfg = 0.0, ttfb = 0.0;
    double rn = (double) r / 255.0;
    double gn = (double) g / 255.0;
    double bn = (double) b / 255.0;
    for (int q = 0; q < lightCount; q++) {
      double dint = 0.0;
      double pint = 0.0;

      double lx = px - lightX[q];
      double ly = py - lightY[q];
      double lz = pz - lightZ[q];
      double rr = Math.sqrt(lx * lx + ly * ly + lz * lz);
      if (Math.abs(rr) <= MathLib.EPSILON) {
        lx = ly = 0.0;
        lz = -1.0;
      }
      else {
        lx /= rr;
        ly /= rr;
        lz /= rr;
      }
      double cosa = nfx * lx + nfy * ly + nfz * lz;

      // TODO
      //      if (cosa < 0.0) {
      //        cosa = 0.0 - cosa;
      //        nfx = 0.0 - nfx;
      //        nfy = 0.0 - nfy;
      //        nfz = 0.0 - nfz;
      //        reflectViewVector();
      //      }

      dint = diffuse * cosa;

      cosa = refx * lx + refy * ly + refz * lz;
      if (cosa > 0.0)
        pint = phongInt(cosa);

      dint = (dint > 1.0 ? 1.0 : dint);
      pint = (pint > 1.0 ? 1.0 : pint);
      ttfr += ((dint * rn + pint) * lightRed[q]);
      ttfg += ((dint * gn + pint) * lightGreen[q]);
      ttfb += ((dint * bn + pint) * lightBlue[q]);
    }
    ttfr += rn * ambient;
    ttfg += gn * ambient;
    ttfb += bn * ambient;
    //System.out.println(ttfr + " " + ttfg + " " + ttfb);
    int tt = (int) (ttfr * 255.0 + 0.5);
    if (tt < 0)
      tt = 0;
    else if (tt > 255)
      tt = 255;
    pr = tt;
    tt = (int) (ttfg * 255.0 + 0.5);
    if (tt < 0)
      tt = 0;
    else if (tt > 255)
      tt = 255;
    pg = tt;
    tt = (int) (ttfb * 255.0 + 0.5);
    if (tt < 0)
      tt = 0;
    else if (tt > 255)
      tt = 255;
    pb = tt;
  }

}
TOP

Related Classes of org.jwildfire.create.tina.render.Pseudo3DShader

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.