rsidwell icon

Hourglass3DFunc.java

rsidwell | PRO | 02/15/23 03:03:38 AM UTC | 0 ⭐ | 1216 👁️ | Never ⏰ | []
Java |

3.52 KB

|

None

|

0 👍

/

0 👎

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