rsidwell

cracklep.java

Mar 20th, 2017
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.20 KB | None | 0 0
  1. /*
  2. JWildfire - an image and animation processor written in Java
  3. Copyright (C) 1995-2011 Andreas Maschke
  4.  
  5. This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
  6. General Public License as published by the Free Software Foundation; either version 2.1 of the
  7. License, or (at your option) any later version.
  8.  
  9. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
  10. even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12.  
  13. You should have received a copy of the GNU Lesser General Public License along with this software;
  14. if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  15. 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  16. */
  17.  
  18. // Port of Hexes and Crackle plugin by slobo777, see http://slobo777.deviantart.com/art/Apo-Plugins-Hexes-And-Crackle-99243824
  19. // All credits for this wonderful plugin to him!
  20.  
  21. // This version has a "preset" variable that sets the other variables to make common patterns.
  22. // Values are taken from the Built-in script Crackle_Styles_Chooser_Rev01_by_MH, originally from
  23. // Ian Anderson and Anu Wilde.
  24.  
  25. // "Hexes" variation breaks plane into hexagonal cells and applies same
  26. // power, scaling, rotation.
  27.  
  28. package org.jwildfire.create.tina.variation;
  29.  
  30. import static org.jwildfire.base.mathlib.MathLib.M_PI;
  31. import static org.jwildfire.base.mathlib.MathLib.cos;
  32. import static org.jwildfire.base.mathlib.MathLib.fabs;
  33. import static org.jwildfire.base.mathlib.MathLib.floor;
  34. import static org.jwildfire.base.mathlib.MathLib.pow;
  35. import static org.jwildfire.base.mathlib.MathLib.sin;
  36. import static org.jwildfire.create.tina.variation.NoiseTools.simplexNoise3D;
  37. import static org.jwildfire.create.tina.variation.VoronoiTools.VORONOI_MAXPOINTS;
  38. import static org.jwildfire.create.tina.variation.VoronoiTools._x_;
  39. import static org.jwildfire.create.tina.variation.VoronoiTools._y_;
  40. import static org.jwildfire.create.tina.variation.VoronoiTools._z_;
  41. import static org.jwildfire.create.tina.variation.VoronoiTools.closest;
  42. import static org.jwildfire.create.tina.variation.VoronoiTools.voronoi;
  43.  
  44. import org.jwildfire.base.Tools;
  45. import org.jwildfire.create.tina.base.Layer;
  46. import org.jwildfire.create.tina.base.XForm;
  47. import org.jwildfire.create.tina.base.XYZPoint;
  48.  
  49. public class CracklePFunc extends VariationFunc {
  50. private static final long serialVersionUID = 1L;
  51.  
  52. public static final String VAR_NAME = "cracklep";
  53.  
  54. private static final String PARAM_PRESET = "preset";
  55. public static final String PARAM_CELLSIZE = "cellsize";
  56. public static final String PARAM_POWER = "power";
  57. public static final String PARAM_DISTORT = "distort";
  58. public static final String PARAM_SCALE = "scale";
  59. private static final String PARAM_Z = "z";
  60.  
  61. protected static final String[] paramNames = { PARAM_PRESET, PARAM_CELLSIZE, PARAM_POWER, PARAM_DISTORT, PARAM_SCALE, PARAM_Z };
  62.  
  63. private int preset = 0;
  64. private double cellsize = 1.0;
  65. private double power = 0.2;
  66. private double distort = 0.0;
  67. private double scale = 1.0;
  68. private double z = 0.0;
  69.  
  70. @Override
  71. public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) {
  72. double DXo, DYo, L, R, s, trgL;
  73. double U[] = new double[2];
  74. int XCv, YCv;
  75.  
  76. // An infinite number of invisible cells? No thanks!
  77. if (0.0 == cellsize) {
  78. return;
  79. }
  80.  
  81. // Scaling factor
  82. s = cellsize / 2.0;
  83.  
  84. // For a blur effect, base everything starting on a circle radius 1.0
  85. // (as opposed to reading the values from FTx and FTy)
  86. double blurr = (pContext.random() + pContext.random()) / 2.0 + (pContext.random() - 0.5) / 4.0;
  87.  
  88. double theta = 2 * M_PI * pContext.random();
  89.  
  90. U[_x_] = blurr * sin(theta);
  91. U[_y_] = blurr * cos(theta);
  92.  
  93. // Use integer values as Voronoi grid co-ordinates
  94. XCv = (int) floor(U[_x_] / s);
  95. YCv = (int) floor(U[_y_] / s);
  96.  
  97. // Get a set of 9 square centre points, based around the one above
  98. int di, dj;
  99. int i = 0;
  100. for (di = -1; di < 2; di++) {
  101. for (dj = -1; dj < 2; dj++) {
  102. cached_position(C, XCv + di, YCv + dj, z, s, distort, P[i]);
  103. i++;
  104. }
  105. }
  106.  
  107. int q = closest(P, 9, U);
  108.  
  109. int offset[][] = new int[][] { { -1, -1 }, { -1, 0 }, { -1, 1 },
  110. { 0, -1 }, { 0, 0 }, { 0, 1 },
  111. { 1, -1 }, { 1, 0 }, { 1, 1 } };
  112.  
  113. // Remake list starting from chosen square, ensure it is completely surrounded (total 9 points)
  114.  
  115. // First adjust centres according to which one was found to be closest
  116. XCv += offset[q][_x_];
  117. YCv += offset[q][_y_];
  118.  
  119. // Get a new set of 9 square centre points, based around the definite closest point
  120. i = 0;
  121. for (di = -1; di < 2; di++) {
  122. for (dj = -1; dj < 2; dj++) {
  123. cached_position(C, XCv + di, YCv + dj, z, s, distort, P[i]);
  124. i++;
  125. }
  126. }
  127.  
  128. L = voronoi(P, 9, 4, U); // index 4 is centre cell
  129.  
  130. // Delta vector from centre
  131. DXo = U[_x_] - P[4][_x_];
  132. DYo = U[_y_] - P[4][_y_];
  133.  
  134. /////////////////////////////////////////////////////////////////
  135. // Apply "interesting bit" to cell's DXo and DYo co-ordinates
  136.  
  137. // trgL is the new value of L
  138. trgL = pow(L + 1e-100, power) * scale; // ( 0.9 )
  139.  
  140. R = trgL / (L + 1e-100);
  141.  
  142. DXo *= R;
  143. DYo *= R;
  144.  
  145. // Add cell centre co-ordinates back in
  146. DXo += P[4][_x_];
  147. DYo += P[4][_y_];
  148. // Finally add values in
  149. applyCellCalculation(pVarTP, pAmount, DXo, DYo, L);
  150. }
  151.  
  152. protected void applyCellCalculation(XYZPoint pVarTP, double pAmount, double DXo, double DYo, double L) {
  153. pVarTP.x += pAmount * DXo;
  154. pVarTP.y += pAmount * DYo;
  155. }
  156.  
  157. @Override
  158. public String[] getParameterNames() {
  159. return paramNames;
  160. }
  161.  
  162. @Override
  163. public Object[] getParameterValues() {
  164. return new Object[] { preset, cellsize, power, distort, scale, z };
  165. }
  166.  
  167. @Override
  168. public void setParameter(String pName, double pValue) {
  169. if (PARAM_PRESET.equalsIgnoreCase(pName)) {
  170. preset = Tools.FTOI(pValue);
  171. switch (preset) {
  172. case 0:
  173. cellsize = 1.0; power = 0.2; distort = 0.0; scale = 1.00; z=0.0;
  174. break;
  175. case 1:
  176. cellsize = 0.5; power = 0.5; distort = 1.0; scale = 0.95; z=10.0;
  177. break;
  178. case 2:
  179. cellsize = 0.5; power = 0.01; distort = 0.5; scale = 1.0; z=0.0;
  180. break;
  181. case 3:
  182. cellsize = 0.05; power = 0.9; distort = 0.9; scale = 0.5; z=0.0;
  183. break;
  184. case 4:
  185. cellsize = 0.5; power = 1.0; distort = 1.0; scale = 0.93; z=10.0;
  186. break;
  187. case 5:
  188. cellsize = 1.0; power = 1.0; distort = 0.0; scale = 0.9; z=0.0;
  189. break;
  190. case 6:
  191. cellsize = 0.8; power = 0.5; distort = 0.5; scale = 0.8; z=0.5;
  192. break;
  193. case 7:
  194. cellsize = 0.2; power = 0.01; distort = 0.0; scale = 0.4; z=2.0;
  195. break;
  196. case 8:
  197. cellsize = 1.0; power = 0.5; distort = 0.25; scale = 0.5; z=0.0;
  198. break;
  199. case 9:
  200. cellsize = 0.6; power = 0.75; distort = 1.0; scale = 0.25; z=0.75;
  201. break;
  202. case 10:
  203. cellsize = 0.5; power = 25.0; distort = 0.0; scale = 9.0; z=6.0;
  204. break;
  205. case 11:
  206. cellsize = 0.2; power = 1.0; distort = 0.0; scale = 0.4; z=0.0;
  207. break;
  208. case 12:
  209. cellsize = 1.5; power = 0.01; distort = 0.0; scale = 0.4; z=0.0;
  210. break;
  211. case 13:
  212. cellsize = 8.0; power = 0.01; distort = 0.0; scale = 0.4; z=0.0;
  213. break;
  214. case 14:
  215. cellsize = 0.2; power = 0.05; distort = 1.0; scale = 5.0; z=0.0;
  216. break;
  217. case 15:
  218. cellsize = 0.07; power = 0.05; distort = 0.5; scale = 9.0; z=6.0;
  219. break;
  220. case 16:
  221. cellsize = 0.2; power = 0.1; distort = 0.0; scale = 1.5; z=2.0;
  222. break;
  223. case 17:
  224. cellsize = 0.297494; power = 0.662265; distort = 0.0708866; scale = 0.228156; z=0.0;
  225. break;
  226. case 18:
  227. cellsize = 0.205939; power = 1.0; distort = 0.0; scale = 0.6298; z=0.35;
  228. break;
  229. case 19:
  230. cellsize = 0.5; power = 0.001; distort = 1.0; scale = 2.0; z=0.0;
  231. break;
  232. case 20:
  233. cellsize = 0.5; power = 0.0005; distort = 0.748; scale = 1.465; z=6.0;
  234. break;
  235. }
  236. }
  237. else if (PARAM_CELLSIZE.equalsIgnoreCase(pName))
  238. cellsize = pValue;
  239. else if (PARAM_POWER.equalsIgnoreCase(pName))
  240. power = pValue;
  241. else if (PARAM_DISTORT.equalsIgnoreCase(pName))
  242. distort = pValue;
  243. else if (PARAM_SCALE.equalsIgnoreCase(pName))
  244. scale = pValue;
  245. else if (PARAM_Z.equalsIgnoreCase(pName))
  246. z = pValue;
  247. else
  248. throw new IllegalArgumentException(pName);
  249. }
  250.  
  251. @Override
  252. public String getName() {
  253. return VAR_NAME;
  254. }
  255.  
  256. //These set cache size for cell centres, they take a lot of processing, so it's handy to
  257. //keep values between calls
  258. private final static int CACHE_NUM = 10;
  259. private final static int CACHE_WIDTH = 21;
  260.  
  261. // P is a working list of points
  262. private double P[][] = new double[VORONOI_MAXPOINTS][2];
  263. // C is a cache of pre-calculated centres
  264. private double C[][][] = new double[CACHE_WIDTH][CACHE_WIDTH][2];
  265.  
  266. //Waffle's cells are based on a simple square grid which is distorted using a noise function
  267.  
  268. //position() calculates cell centre for cell (x, y), given plane slice z, scale factor s, distortion d
  269. // and stores in supplied array
  270. private void position(int x, int y, double z, double s, double d, double V[]) {
  271. double E[] = new double[3];
  272. double F[] = new double[3];
  273.  
  274. // Values here are arbitrary, chosen simply to be far enough apart so they do not correlate
  275. E[_x_] = x * 2.5;
  276. E[_y_] = y * 2.5;
  277. E[_z_] = z * 2.5;
  278. // Cross-over between x and y is intentional
  279. F[_x_] = y * 2.5 + 30.2;
  280. F[_y_] = x * 2.5 - 12.1;
  281. F[_z_] = z * 2.5 + 19.8;
  282.  
  283. V[_x_] = (x + d * simplexNoise3D(E)) * s;
  284. V[_y_] = (y + d * simplexNoise3D(F)) * s;
  285. }
  286.  
  287. //cached_position gives centre co-ordinates either from cache, or calculated from scratch if needed
  288. private void cached_position(double Cache[][][], int x, int y, double z, double s, double d, double V[]) {
  289. if (fabs(x) <= CACHE_NUM && fabs(y) <= CACHE_NUM) {
  290. V[_x_] = Cache[x + CACHE_NUM][y + CACHE_NUM][_x_];
  291. V[_y_] = Cache[x + CACHE_NUM][y + CACHE_NUM][_y_];
  292. }
  293. else {
  294. position(x, y, z, s, d, V);
  295. }
  296. }
  297.  
  298. @Override
  299. public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) {
  300. // Pre-calculate cache of grid centres, to save time later . . .
  301. for (int x = -CACHE_NUM; x <= CACHE_NUM; x++) {
  302. for (int y = -CACHE_NUM; y <= CACHE_NUM; y++) {
  303. position(x, y, z, cellsize / 2.0, distort, C[x + CACHE_NUM][y + CACHE_NUM]);
  304. }
  305. }
  306. }
  307.  
  308. }
Add Comment
Please, Sign In to add comment