rsidwell icon

PostPointSymmetryWFFunc

rsidwell | PRO | 01/10/23 04:37:09 PM UTC | 0 ⭐ | 1144 👁️ | Never ⏰ | []
Java |

6.25 KB

|

None

|

0 👍

/

0 👎

/*
  JWildfire - an image and animation processor written in Java 
  Copyright (C) 1995-2021 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 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 PostPointSymmetryWFFunc extends VariationFunc implements SupportsGPU {
  private static final long serialVersionUID = 1L;
 
  public static final String PARAM_CENTRE_X = "centre_x";
  public static final String PARAM_CENTRE_Y = "centre_y";
  public static final String PARAM_CENTRE_Z = "centre_z";
  public static final String PARAM_PLANE = "plane";
  public static final String PARAM_ORDER = "order";
  private static final String PARAM_COLORSHIFT = "colorshift";
  private static final String[] paramNames = {PARAM_CENTRE_X, PARAM_CENTRE_Y, PARAM_CENTRE_Z, PARAM_PLANE, PARAM_ORDER, PARAM_COLORSHIFT};
 
  private double centre_x = 0.25;
  private double centre_y = 0.5;
  private double centre_z = 0.0;
  private int plane = 0;
  private int order = 3;
  private double colorshift = 0;
 
  @Override
  public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP,
                        double pAmount) {
    double dx = (pVarTP.x - centre_x) * pAmount;
    double dy = (pVarTP.y - centre_y) * pAmount;
    double dz = (pVarTP.z - centre_z) * pAmount;
    int idx = pContext.random(order);
    if (plane == 0) {
      pVarTP.x = centre_x + dx * _cosa[idx] + dy * _sina[idx];
      pVarTP.y = centre_y + dy * _cosa[idx] - dx * _sina[idx];
    } else if (plane == 1) {
      pVarTP.y = centre_y + dy * _cosa[idx] + dz * _sina[idx];
      pVarTP.z = centre_z + dz * _cosa[idx] - dy * _sina[idx];
    } else if (plane == 2) {
      pVarTP.z = centre_z + dz * _cosa[idx] + dx * _sina[idx];
      pVarTP.x = centre_x + dx * _cosa[idx] - dz * _sina[idx];
    }
    pVarTP.color = fmod(pVarTP.color + idx * colorshift, 1.0);
  }
 
  @Override
  public String[] getParameterNames() {
    return paramNames;
  }
 
  @Override
  public Object[] getParameterValues() {
    return new Object[]{centre_x, centre_y, centre_z, plane, order, colorshift};
  }
 
  @Override
  public void setParameter(String pName, double pValue) {
    if (PARAM_CENTRE_X.equalsIgnoreCase(pName))
      centre_x = pValue;
    else if (PARAM_CENTRE_Y.equalsIgnoreCase(pName))
      centre_y = pValue;
    else if (PARAM_CENTRE_Z.equalsIgnoreCase(pName))
      centre_z = pValue;
    else if (PARAM_PLANE.equalsIgnoreCase(pName))
      plane = limitIntVal(Tools.FTOI(pValue), 0, 2);
    else if (PARAM_ORDER.equalsIgnoreCase(pName))
      order = limitIntVal(Tools.FTOI(pValue), 1, Integer.MAX_VALUE);
    else if (PARAM_COLORSHIFT.equalsIgnoreCase(pName))
      colorshift = pValue;
    else
      throw new IllegalArgumentException(pName);
  }
 
  @Override
  public String getName() {
    return "post_point_symmetry_wf";
  }
 
  @Override
  public int getPriority() {
    return 1;
  }
 
  private double _sina[], _cosa[];
 
  @Override
  public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) {
    _sina = new double[order];
    _cosa = new double[order];
    double da = M_2PI / (double) order;
    double angle = 0.0;
    for (int i = 0; i < order; i++) {
      _sina[i] = sin(angle);
      _cosa[i] = cos(angle);
      angle += da;
    }
  }
 
  @Override
  public VariationFuncType[] getVariationTypes() {
    return new VariationFuncType[]{VariationFuncType.VARTYPE_2D, VariationFuncType.VARTYPE_DC, VariationFuncType.VARTYPE_POST, VariationFuncType.VARTYPE_SUPPORTS_GPU};
  }
 
  @Override
  public String getGPUCode(FlameTransformationContext context) {
    return "int order = lroundf(__post_point_symmetry_wf_order);\n"
        + "if(order>36) order=36;\n"
        +"float _sina[36];\n"
        + "float _cosa[36];\n"
        + "    float da = (2.0f*PI) / (float) order;\n"
        + "    float angle = 0.0;\n"
        + "    for (int i = 0; i < order; i++) {\n"
        + "      _sina[i] = sinf(angle);\n"
        + "      _cosa[i] = cosf(angle);\n"
        + "      angle += da;\n"
        + "    }\n"
        + "    float dx = (__px - __post_point_symmetry_wf_centre_x) * __post_point_symmetry_wf;\n"
        + "    float dy = (__py - __post_point_symmetry_wf_centre_y) * __post_point_symmetry_wf;\n"
        + "    float dz = (__pz - __post_point_symmetry_wf_centre_z) * __post_point_symmetry_wf;\n"
        + "    int idx = lroundf(RANDFLOAT() * (order-1));\n"
        + "    if (__post_point_symmetry_wf_plane == 0) {\n"
        + "      __px = __post_point_symmetry_wf_centre_x + dx * _cosa[idx] + dy * _sina[idx];\n"
        + "      __py = __post_point_symmetry_wf_centre_y + dy * _cosa[idx] - dx * _sina[idx];\n"
        + "    } else if (__post_point_symmetry_wf_plane == 0) {\n"
        + "      __py = __post_point_symmetry_wf_centre_y + dy * _cosa[idx] + dz * _sina[idx];\n"
        + "      __pz = __post_point_symmetry_wf_centre_z + dz * _cosa[idx] - dy * _sina[idx];\n"
        + "    } else if (__post_point_symmetry_wf_plane == 0) {\n"
        + "      __pz = __post_point_symmetry_wf_centre_z + dz * _cosa[idx] + dx * _sina[idx];\n"
        + "      __px = __post_point_symmetry_wf_centre_x + dx * _cosa[idx] - dz * _sina[idx];\n"
        + "    }\n"
        + "    __pal = fmodf(__pal + idx * __post_point_symmetry_wf_colorshift, 1.0);\n";
  }
}
 

Comments