/*
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.variation;
import static org.jwildfire.base.mathlib.MathLib.M_2PI;
import static org.jwildfire.base.mathlib.MathLib.cos;
import static org.jwildfire.base.mathlib.MathLib.fabs;
import static org.jwildfire.base.mathlib.MathLib.fmod;
import static org.jwildfire.base.mathlib.MathLib.max;
import org.jwildfire.base.Tools;
import org.jwildfire.create.tina.base.Layer;
import org.jwildfire.create.tina.base.XForm;
import org.jwildfire.create.tina.base.XYZPoint;
public class GDOffsFunc extends VariationFunc {
private static final long serialVersionUID = 1L;
private static final String PARAM_DELTA_X = "delta_x";
private static final String PARAM_DELTA_Y = "delta_y";
private static final String PARAM_AREA_X = "area_x";
private static final String PARAM_AREA_Y = "area_y";
private static final String PARAM_CENTER_X = "center_x";
private static final String PARAM_CENTER_Y = "center_y";
private static final String PARAM_GAMMA = "gamma";
private static final String PARAM_SQUARE = "square";
private static final String[] paramNames = { PARAM_DELTA_X, PARAM_DELTA_Y, PARAM_AREA_X, PARAM_AREA_Y, PARAM_CENTER_X, PARAM_CENTER_Y, PARAM_GAMMA, PARAM_SQUARE };
private double delta_x = 0.0;
private double delta_y = 0.0;
private double area_x = 2.0;
private double area_y = 2.0;
private double center_x = 0;
private double center_y = 0;
private int gamma = 1;
private int square = 0;
@Override
public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) {
// gdoffs by Xyrus02, http://xyrusworx.deviantart.com/art/GdOffs-Plugin-for-Apophysis-208416713?offset=0
double osc_x = fosc(gdodx, 1), osc_y = fosc(gdody, 1);
double in_x = (pAffineTP.x + gdocx), in_y = (pAffineTP.y + gdocy);
double out_x = 0, out_y = 0;
if (gdos != 0) {
out_x = flip(flip(in_x, fosc(in_x, 4), osc_x), fosc(fclp(gdob * in_x), 4), osc_x);
out_y = flip(flip(in_y, fosc(in_y, 4), osc_x), fosc(fclp(gdob * in_y), 4), osc_x);
}
else {
out_x = flip(flip(in_x, fosc(in_x, 4), osc_x), fosc(fclp(gdob * in_x), 4), osc_x);
out_y = flip(flip(in_y, fosc(in_y, 4), osc_y), fosc(fclp(gdob * in_y), 4), osc_y);
}
pVarTP.x += pAmount * out_x;
pVarTP.y += pAmount * out_y;
if (pContext.isPreserveZCoordinate()) {
pVarTP.z += pAmount * pAffineTP.z;
}
}
@Override
public String[] getParameterNames() {
return paramNames;
}
@Override
public Object[] getParameterValues() {
return new Object[] { delta_x, delta_y, area_x, area_y, center_x, center_y, gamma, square };
}
@Override
public void setParameter(String pName, double pValue) {
if (PARAM_DELTA_X.equalsIgnoreCase(pName))
delta_x = pValue;
else if (PARAM_DELTA_Y.equalsIgnoreCase(pName))
delta_y = pValue;
else if (PARAM_AREA_X.equalsIgnoreCase(pName))
area_x = pValue;
else if (PARAM_AREA_Y.equalsIgnoreCase(pName))
area_y = pValue;
else if (PARAM_CENTER_X.equalsIgnoreCase(pName))
center_x = pValue;
else if (PARAM_CENTER_Y.equalsIgnoreCase(pName))
center_y = pValue;
else if (PARAM_GAMMA.equalsIgnoreCase(pName))
gamma = Tools.FTOI(pValue);
else if (PARAM_SQUARE.equalsIgnoreCase(pName))
square = Tools.FTOI(pValue);
else
throw new IllegalArgumentException(pName);
}
@Override
public String getName() {
return "gdoffs";
}
//Fine tune stuff, try not to touch :)
private static final double __agdod = 0.1;
private static final double __agdoa = 2.0;
private static final double __agdoc = 1.0;
private double gdodx, gdody, gdoax, gdoay, gdocx, gdocy, gdob;
private int gdog, gdos;
@Override
public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) {
gdodx = delta_x * __agdod;
gdody = delta_y * __agdod;
gdoax = ((fabs(area_x) < 0.1) ? 0.1 : fabs(area_x)) * __agdoa;
gdoay = ((fabs(area_y) < 0.1) ? 0.1 : fabs(area_y)) * __agdoa;
gdocx = (center_x) * __agdoc;
gdocy = (center_y) * __agdoc;
gdog = gamma;
gdos = square;
gdob = (double) (gdog) * __agdoa / (max(gdoax, gdoay));
}
private double fclp(double a) {
return ((a < 0) ? -(fmod(fabs(a), 1)) : fmod(fabs(a), 1));
}
private double fscl(double a) {
return fclp((a + 1) / 2);
}
private double fosc(double p, double a) {
return fscl(-1 * cos(p * a * M_2PI));
}
private double flip(double a, double b, double c) {
return (c * (b - a) + a);
}
}