/* JWildfire - an image and animation processor written in Java Copyright (C) 1995-2015 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 java.io.Serializable; import org.jwildfire.base.mathlib.MathLib; import org.jwildfire.base.mathlib.VecMathLib.Matrix3D; import org.jwildfire.base.mathlib.VecMathLib.VectorD; import org.jwildfire.create.tina.base.Flame; import org.jwildfire.create.tina.base.XYZPoint; import org.jwildfire.create.tina.base.XYZProjectedPoint; import org.jwildfire.create.tina.base.solidrender.DistantLight; @SuppressWarnings("serial") public class LightViewCalculator implements Serializable { private final Matrix3D lightProjectionMatrix[]; private final VectorD lightDir[]; public LightViewCalculator(Flame flame) { lightProjectionMatrix = new Matrix3D[flame.getSolidRenderSettings().getLights().size()]; lightDir = new VectorD[flame.getSolidRenderSettings().getLights().size()]; for (int i = 0; i < flame.getSolidRenderSettings().getLights().size(); i++) { DistantLight light = flame.getSolidRenderSettings().getLights().get(i); double alpha = Math.toRadians(-light.getAltitude()); double beta = Math.toRadians(-light.getAzimuth()); double sina = MathLib.sin(alpha); double cosa = MathLib.cos(alpha); double sinb = MathLib.sin(beta); double cosb = MathLib.cos(beta); Matrix3D a = new Matrix3D(); a.m[0][0] = cosb; a.m[0][1] = 0; a.m[0][2] = sinb; a.m[1][0] = sina * sinb; a.m[1][1] = cosa; a.m[1][2] = -sina * cosb; a.m[2][0] = -cosa * sinb; a.m[2][1] = sina; a.m[2][2] = cosa * cosb; lightDir[i] = Matrix3D.multiply(a, new VectorD(0.0, 0.0, -1.0)); if (light.isCastShadows()) { lightProjectionMatrix[i] = a; } else { lightProjectionMatrix[i] = null; } } } public double applyLightProjectionX(int idx, double x, double y, double z) { return x * lightProjectionMatrix[idx].m[0][0] + y * lightProjectionMatrix[idx].m[0][1] + z * lightProjectionMatrix[idx].m[0][2]; } public double applyLightProjectionY(int idx, double x, double y, double z) { return x * lightProjectionMatrix[idx].m[1][0] + y * lightProjectionMatrix[idx].m[1][1] + z * lightProjectionMatrix[idx].m[1][2]; } public double applyLightProjectionZ(int idx, double x, double y, double z) { return x * lightProjectionMatrix[idx].m[2][0] + y * lightProjectionMatrix[idx].m[2][1] + z * lightProjectionMatrix[idx].m[2][2]; } public void project(XYZPoint pPoint, XYZProjectedPoint pProjectedPoint) { for (int i = 0; i < lightProjectionMatrix.length; i++) { if (lightProjectionMatrix[i] != null) { pProjectedPoint.lightX[i] = applyLightProjectionX(i, pPoint.x, pPoint.y, pPoint.z); pProjectedPoint.lightY[i] = applyLightProjectionY(i, pPoint.x, pPoint.y, pPoint.z); pProjectedPoint.lightZ[i] = applyLightProjectionZ(i, pPoint.x, pPoint.y, pPoint.z); pProjectedPoint.hasLight[i] = true; } else { pProjectedPoint.hasLight[i] = false; } } } public VectorD[] getLightDir() { return lightDir; } }