package org.jwildfire.create.tina.variation;
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;
import static org.jwildfire.base.mathlib.MathLib.*;
public class Hourglass3DFunc extends VariationFunc {
private static final long serialVersionUID = 1L;
private static final String PARAM_KX = "kx";
private static final String PARAM_KY = "ky";
private static final String PARAM_KZ = "kz";
private static final String PARAM_MAXHEIGHT = "maxheight";
private static final String PARAM_USELIMIT = "uselimit";
private static final String PARAM_ZERO_EDGES = "zero_edges";
private static final String[] paramNames = {PARAM_KX, PARAM_KY, PARAM_KX, PARAM_MAXHEIGHT, PARAM_USELIMIT, PARAM_ZERO_EDGES};
private double kx = 1.0;
private double ky = 1.0;
private double kz = 1.0;
private double maxheight = 3.0;
private int limit = 1;
private int zero = 0;
private double vkx, vky, vkz, h, hb;
@Override
public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) {
vkx = pAmount * kx;
vky = pAmount * ky;
vkz = pAmount * kz;
h = sqrt(1 + sqr(maxheight / ky));
hb = sqrt(sqr(h) - 1);
}
@Override
public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) {
double sn, cn, sh, ch;
sn = sin(pAffineTP.x);
cn = cos(pAffineTP.x);
sh = sinh(pAffineTP.y);
ch = cosh(pAffineTP.y);
if (limit == 0) {
// Function
pVarTP.x += vkx * ch * sn;
pVarTP.y += vky * sh;
pVarTP.z += vkz * ch * cn;
} else if (zero == 0) {
// CutBorder
if (ch < h) { // cut the surface
pVarTP.x += vkx * ch * sn;
pVarTP.y += vky * sh;
pVarTP.z += vkz * ch * cn;
} else { // place the point on it's boarder
pVarTP.x += vkx * h * sn;
pVarTP.y += vky * sign(sh) * hb;
pVarTP.z += vkz * h * cn;
}
} else {
// Cut
if (ch < h) { // cut the surface
pVarTP.x += vkx * ch * sn;
pVarTP.y += vky * sh;
pVarTP.z += vkz * ch * cn;
}
}
}
@Override
public String[] getParameterNames() {
return paramNames;
}
@Override
public Object[] getParameterValues() {
return new Object[]{kx, ky, kz, maxheight, limit, zero};
}
@Override
public void setParameter(String pName, double pValue) {
if (PARAM_KX.equalsIgnoreCase(pName))
kx = (pValue < 1E-5) ? 1E-5 : pValue;
else if (PARAM_KY.equalsIgnoreCase(pName))
ky = (pValue < 1E-5) ? 1E-5 : pValue;
else if (PARAM_KZ.equalsIgnoreCase(pName))
kz = (pValue < 1E-5) ? 1E-5 : pValue;
else if (PARAM_MAXHEIGHT.equalsIgnoreCase(pName))
maxheight = (pValue < 0.1) ? 0.1 : pValue;
else if (PARAM_USELIMIT.equalsIgnoreCase(pName))
limit = limitIntVal(Tools.FTOI(pValue), 0, 1);
else if (PARAM_ZERO_EDGES.equalsIgnoreCase(pName))
zero = limitIntVal(Tools.FTOI(pValue), 0, 1);
else
throw new IllegalArgumentException(pName);
}
public String getName() {
return "hourglass3D";
}
public VariationFuncType[] getVariationTypes() {
// return new VariationFuncType[]{VariationFuncType.VARTYPE_3D, VariationFuncType.VARTYPE_SUPPORTS_GPU};
return new VariationFuncType[]{VariationFuncType.VARTYPE_3D};
}
}
Comments