rendered paste bodyIndex: source/blender/blenkernel/BKE_texture.h
===================================================================
--- source/blender/blenkernel/BKE_texture.h (revision 13811)
+++ source/blender/blenkernel/BKE_texture.h (working copy)
@@ -57,6 +57,7 @@
struct ColorBand *add_colorband(int rangetype);
int do_colorband(struct ColorBand *coba, float in, float out[4]);
+void tiles_precalc(struct Tex *tex);
void default_tex(struct Tex *tex);
struct Tex *add_texture(char *name);
void default_mtex(struct MTex *mtex);
@@ -78,3 +79,5 @@
#endif
+
+
Index: source/blender/blenkernel/intern/texture.c
===================================================================
--- source/blender/blenkernel/intern/texture.c (revision 13811)
+++ source/blender/blenkernel/intern/texture.c (working copy)
@@ -403,6 +403,138 @@
/* ------------------------------------------------------------------------- */
+void tiles_precalc(Tex *tex)
+{
+ /* Compute a set of random widths for the tiles. The array tex->precalc->pat[] will
+ * accumulate the gap and tile widths in each cell starting at 0.
+ */
+ Tex *t = (Tex *)tex;
+ float maxwidth = t->width + t->widthvar * t->width;
+ float minwidth = t->width - t->widthvar * t->width;
+ float maxheight = t->height + t->heightvar * t->height;
+ float minheight = t->height - t->heightvar * t->height;
+ float maxbump = t->bump + t->bumpvar * t->bump;
+ float minbump = t->bump - t->bumpvar * t->bump;
+
+ float w, h, b, r, sum;
+ float h1, s1, v1, h2, s2, v2;
+ float mh, ms, mv;
+ short i, j;
+
+ RNG *rng = rng_new(tex->seed);
+
+ /* Handle negative dimensions */
+ if (minwidth < 0) minwidth = 0;
+ if (minheight < 0) minheight = 0;
+
+ /* Handle bump limits */
+ if (minbump < 0) minbump = 0;
+ if (maxbump > 1) maxbump = 1;
+
+ /* Calculate ranges for width, height and bump */
+ w = maxwidth - minwidth;
+ h = maxheight - minheight;
+ b = maxbump - minbump;
+
+ /* Initialize min/max values */
+ t->precalc.minw = MAX2(minwidth, maxwidth);
+ t->precalc.maxw = 0;
+ t->precalc.minh = MAX2(minheight, maxheight);
+ t->precalc.maxh = 0;
+
+ /* Compute random numbers between minwidth and maxwidth. Keep a running total
+ * of the width of the pattern. All the width's will then be scaled by this
+ * to bring into the [0, 1] range; otherwise, the pattern won't be seamless
+ * for the 2D->3D texture mapping functions.
+ */
+ t->precalc.hpat[0] = 0;
+ sum = 0;
+ for (i = 1; i <= t->hcount; i++) {
+ r = rng_getFloat(rng);
+ r = minwidth + w * r;
+ t->precalc.hpat[i] = t->hgap + t->precalc.hpat[i - 1] + r;
+ sum += t->hgap + r;
+
+ t->precalc.minw = MIN2(t->precalc.minw, r);
+ t->precalc.maxw = MAX2(t->precalc.maxw, r);
+ }
+ if (tex->seamless) {
+ sum = 1.0/sum;
+ for (i = 1; i <= t->hcount; i++) {
+ t->precalc.hpat[i] *= sum;
+ }
+ t->precalc.minw *= sum;
+ t->precalc.maxw *= sum;
+ t->precalc.hgap = t->hgap * sum;
+ }
+ else {
+ t->precalc.hgap = t->hgap;
+ }
+
+ /* Compute random numbers between minheight and maxheight. Keep a running total
+ * of the height of the pattern. All the height's will then be scaled by this
+ * to bring into the [0, 1] range; otherwise, the pattern won't be seamless
+ * for the 2D->3D texture mapping functions.
+ */
+ t->precalc.vpat[0] = 0;
+ sum = 0;
+ for (i = 1; i <= t->vcount; i++) {
+ r = rng_getFloat(rng);
+ r = minheight + h * r;
+ t->precalc.vpat[i] = t->vgap + t->precalc.vpat[i - 1] + r;
+ sum += t->vgap + r;
+
+ t->precalc.minh = MIN2(t->precalc.minh, r);
+ t->precalc.maxh = MAX2(t->precalc.maxh, r);
+ }
+ if (tex->seamless) {
+ sum = 1.0/sum;
+ for (i = 1; i <= t->vcount; i++) {
+ t->precalc.vpat[i] *= sum;
+ }
+ t->precalc.minh *= sum;
+ t->precalc.maxh *= sum;
+ t->precalc.vgap = t->vgap * sum;
+ }
+ else {
+ t->precalc.vgap = t->vgap;
+ }
+
+ /* Compute random numbers between minbump and maxbump */
+ for (i = 0; i < t->hcount; i++) {
+ for (j = 0; j < t->vcount; j++) {
+ r = rng_getFloat(rng);
+ t->precalc.bpat[i][j] = minbump + b * r;
+ }
+ }
+ for (i = 0; i < 16; i++) {
+ r = rng_getFloat(rng);
+ t->precalc.rpat[i] = minbump + b * r;
+ }
+
+ /* Compute random colours using the base colour [colr1, colg1, colb1] and the
+ * percentage variation in hue, saturation and value.
+ */
+ rgb_to_hsv(t->colr1, t->colg1, t->colb1, &h1, &s1, &v1);
+ mh = 0.5 * t->fhue;
+ ms = 0.5 * t->fsat;
+ mv = 0.5 * t->fval;
+ for (i = 0; i < t->hcount; i++) {
+ for (j = 0; j < t->vcount; j++) {
+ r = rng_getFloat(rng);
+ h2 = h1 + r * t->fhue - mh;
+ s2 = s1 + r * t->fsat - ms;
+ v2 = v1 + r * t->fval - mv;
+ if (h2 > 1.0) h2 -= 1.0; else if (h2 < 0.0) h2 += 1.0;
+ if (s2 > 1.0) s2 -= 1.0; else if (s2 < 0.0) s2 += 1.0;
+ if (v2 > 1.0) v2 -= 1.0; else if (v2 < 0.0) v2 += 1.0;
+ hsv_to_rgb(h2, s2, v2, &t->precalc.r[i][j], &t->precalc.g[i][j], &t->precalc.b[i][j]);
+ }
+ }
+
+ rng_free(rng);
+}
+
void default_tex(Tex *tex)
{
PluginTex *pit;
@@ -448,6 +580,39 @@
tex->vn_mexp = 2.5;
tex->vn_distm = 0;
tex->vn_coltype = 0;
+ /* tiles */
+ tex->scale = 1;
+ tex->hcount = 3;
+ tex->width = 0.2;
+ tex->widthvar = 0;
+ tex->vcount = 3;
+ tex->height = 0.1;
+ tex->heightvar = 0;
+ tex->hgap = 0.01;
+ tex->vgap = 0.01;
+ tex->shift = 0.1;
+ tex->bevel = 0.2;
+ tex->corner = TEX_CORNER_STRAIGHT;
+ tex->hcorner = 0;
+ tex->vcorner = 0;
+ tex->seed = 0;
+ tex->alternate = 1;
+ tex->curve = 0;
+ tex->smooth = 0;
+ tex->strength = 1;
+ tex->pattern = 0;
+ tex->bevoption = 0;
+ tex->colr1 = 1;
+ tex->colg1 = 1;
+ tex->colb1 = 1;
+ tex->colr2 = 0;
+ tex->colg2 = 0;
+ tex->colb2 = 0;
+ tex->bump = 1;
+ tex->bumpvar = 0;
+ tex->seamless = 1;
+ tex->bevelshading = TEX_BEVEL_DEFAULT;
+ tiles_precalc(tex);
if (tex->env) {
tex->env->stype=ENV_STATIC;
Index: source/blender/blenloader/intern/readfile.c
===================================================================
--- source/blender/blenloader/intern/readfile.c (revision 13811)
+++ source/blender/blenloader/intern/readfile.c (working copy)
@@ -5904,7 +5904,7 @@
}
}
}
- }
+ }
}
@@ -6976,7 +6976,7 @@
}
}
}
-
+
for(ma=main->mat.first; ma; ma= ma->id.next) {
if(ma->samp_gloss_mir == 0) {
ma->gloss_mir = ma->gloss_tra= 1.0;
@@ -7081,7 +7081,6 @@
sce->r.bg_stamp[3] = 0.25; /* make sure the background has full alpha */
}
}
-
if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 6)) {
Scene *sce;
@@ -7394,6 +7393,48 @@
if(ma->mtex[a] && ma->mtex[a]->tex)
ma->mtex[a]->normapspace = MTEX_NSPACE_TANGENT;
}
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 8)) {
+ Tex *tex;
+
+ /* Initialize Tiles texture */
+ for(tex= main->tex.first; tex; tex= tex->id.next) {
+ tex->scale = 1;
+ tex->hcount = 3;
+ tex->width = 0.2;
+ tex->widthvar = 0;
+ tex->vcount = 3;
+ tex->height = 0.1;
+ tex->heightvar = 0;
+ tex->hgap = 0.01;
+ tex->vgap = 0.01;
+ tex->shift = 0.1;
+ tex->bevel = 0.2;
+ tex->corner = TEX_CORNER_STRAIGHT;
+ tex->hcorner = 0;
+ tex->vcorner = 0;
+ tex->seed = 0;
+ tex->alternate = 1;
+ tex->curve = 0;
+ tex->smooth = 0;
+ tex->strength = 1;
+ tex->pattern = 0;
+ tex->bevoption = 0;
+ tex->colr1 = 1;
+ tex->colg1 = 1;
+ tex->colb1 = 1;
+ tex->colr2 = 0;
+ tex->colg2 = 0;
+ tex->colb2 = 0;
+ tex->fhue = 0;
+ tex->fsat = 0;
+ tex->fval = 0;
+ tex->bump = 1;
+ tex->bumpvar = 0;
+ tex->seamless = 1;
+ tex->bevelshading = TEX_BEVEL_DEFAULT;
+ tiles_precalc(tex);
+ }
+ }
if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 10)) {
Object *ob;
@@ -7503,6 +7544,7 @@
if (image->flag & IMA_OLDFLAG) image->flag &= ~IMA_OLDFLAG;
}
}
+
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
Index: source/blender/makesdna/DNA_texture_types.h
===================================================================
--- source/blender/makesdna/DNA_texture_types.h (revision 13811)
+++ source/blender/makesdna/DNA_texture_types.h (working copy)
@@ -130,6 +130,21 @@
short recalc, lastsize;
} EnvMap;
+/* --------------------------------------- Tiles Specific ---------------------------------------------- */
+typedef struct TexPreCalc {
+ float hpat[16]; /* Stores horizontal tile pattern */
+ float vpat[16]; /* Stores vertical tile pattern */
+ float bpat[16][16]; /* Stores the bump pattern */
+ float minw, minh; /* Store overall min of width and height value */
+ float maxw, maxh; /* Store overall max of width and height value */
+ float r[16][16]; /* Store colour pattern */
+ float g[16][16];
+ float b[16][16];
+ float rpat[16]; /* Stores the random numbers for anything else */
+ float hgap, vgap; /* Stores gap values scaled by overall size of pattern */
+} TexPreCalc;
+/* --------------------------------------- Tiles Specific ---------------------------------------------- */
+
typedef struct Tex {
ID id;
@@ -154,7 +169,19 @@
short imaflag, flag;
short type, stype;
-
+
+ short hcount, vcount, smooth;
+ short corner, pattern, bevoption;
+ float scale;
+ float width, widthvar, height, heightvar, bump, bumpvar;
+ float curve;
+ float hgap, vgap, shift, bevel, strength;
+ float colr1, colg1, colb1, colr2, colg2, colb2, fhue, fsat, fval;
+ float hcorner, vcorner;
+ unsigned int seed, alternate;
+ short seamless, bevelshading;
+ struct TexPreCalc precalc;
+
float cropxmin, cropymin, cropxmax, cropymax;
short xrepeat, yrepeat;
short extend;
@@ -211,6 +238,7 @@
#define TEX_MUSGRAVE 11
#define TEX_VORONOI 12
#define TEX_DISTNOISE 13
+#define TEX_TILES 14
/* musgrave stype */
#define TEX_MFRACTAL 0
@@ -310,6 +338,36 @@
#define TEX_HALO 5
#define TEX_RAD 6
+/* tex->stype in texture.c - corner types */
+#define TEX_CORNER_ROUND 0
+#define TEX_CORNER_ROUND_INV 1
+#define TEX_CORNER_ELLIPSE 2
+#define TEX_CORNER_ELLIPSE_INV 3
+#define TEX_CORNER_STRAIGHT 4
+
+#define TEX_TILES_NONE 0
+#define TEX_TILES_INTERLOCK1 1
+#define TEX_TILES_HEX 2
+#define TEX_TILES_HERRINGBONE1 3
+#define TEX_TILES_HERRINGBONE2 4
+#define TEX_TILES_HERRINGBONE3 5
+#define TEX_TILES_WEAVE 6
+#define TEX_TILES_INTERLOCK2 7
+#define TEX_TILES_INTERLOCK3 8
+#define TEX_TILES_INTERLOCK4 9
+#define TEX_TILES_CROSS1 10
+#define TEX_TILES_CROSS2 11
+#define TEX_TILES_STAR1 12
+
+#define TEX_BEVEL_DEFAULTMIN 0
+#define TEX_BEVEL_UNIFORMMIN 1
+#define TEX_BEVEL_UNIFORMMAX 2
+
+#define TEX_BEVEL_DEFAULT 0
+#define TEX_BEVEL_PATTERN 1 /* Used for predefined pattern so they can do what they want */
+#define TEX_BEVEL_HGRADIENT 2
+#define TEX_BEVEL_VGRADIENT 3
+
/* tex->stype in texture.c - stucci types */
#define TEX_PLASTIC 0
#define TEX_WALLIN 1
@@ -388,3 +446,11 @@
#endif
+
+
+
+
+
+
+
+
Index: source/blender/render/intern/include/texture.h
===================================================================
--- source/blender/render/intern/include/texture.h (revision 13811)
+++ source/blender/render/intern/include/texture.h (working copy)
@@ -49,6 +49,7 @@
struct HaloRen;
struct ShadeInput;
struct TexResult;
+struct TexPreCalc;
struct Tex;
struct Image;
struct ImBuf;
@@ -72,3 +73,11 @@
#endif /* TEXTURE_EXT_H */
+
+
+
+
+
+
+
+
Index: source/blender/render/intern/source/texture.c
===================================================================
--- source/blender/render/intern/source/texture.c (revision 13811)
+++ source/blender/render/intern/source/texture.c (working copy)
@@ -5,7 +5,7 @@
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ * as published by the Free Software Foundation; either version 2iles
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@@ -28,6 +28,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef WIN32
+#define _USE_MATH_DEFINES
+#endif
#include <math.h>
#include "MTC_matrixops.h"
@@ -74,9 +77,8 @@
extern struct Render R;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+#define M_PI_OVER_180 0.0174532925199
-
-
/* note; this is called WITH RENDER IS NULL in src/drawview.c for animated
background image, option should move to kernel */
void init_render_texture(Render *re, Tex *tex)
@@ -691,9 +693,2154 @@
}
+/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
+/* Determines which side of the line a point is. Assume +ve for left of vector pointing from pa to pb. */
+#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
+
+/* Determines if a point p0 is inside a triangle (p1, p2, p3). */
+#define POINT_IN_TRI(p0,p1,p2,p3) ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0))
+
+/* Signed distance of point (x, y) from line Ax + By + C = 0. */
+#define DIST_POINT_TO_LINE(A, B, C, x, y) (((A) * (x) + (B) * (y) + (C)) / sqrt((A) * (A) + (B) * (B)))
+
+/* Given signed distance d from a line and bevel width b, compute a linear gradient for the positive
+ * side of the line. Points on the negative side will have intensity 0 and points beyond distance
+ * b will have intensity 1.
+ */
+#define LINE_BEVEL(d, b) d = (d < 0) ? 0 : ((d <= b) && (b > 0)) ? (d) / (b) : 1
+
+/* Determines if a point (x, y) is inside, outside or on a circle with center (cx, cy) and radius r. */
+#define POINT_IN_CIRCLE(x, y, cx, cy, r) (((x) - (cx)) * ((x) - (cx)) + ((y) - (cy)) * ((y) - (cy)) < (r) * (r))
+#define POINT_ON_CIRCLE(x, y, cx, cy, r) (((x) - (cx)) * ((x) - (cx)) + ((y) - (cy)) * ((y) - (cy)) == (r) * (r))
+#define POINT_NOT_IN_CIRCLE(x, y, cx, cy, r) (((x) - (cx)) * ((x) - (cx)) + ((y) - (cy)) * ((y) - (cy)) > (r) * (r))
+/* Determines if a point (x, y) is inside, outside or on an ellipse with center (cx, cy) and radii rx, ry. */
+#define POINT_IN_ELLIPSE(x, y, cx, cy, rx, ry) (((x) - (cx)) * ((x) - (cx)) / ((rx) * (rx)) + ((y) - (cy)) * ((y) - (cy)) / ((ry) * (ry)) < 1)
+#define POINT_ON_ELLIPSE(x, y, cx, cy, rx, ry) (((x) - (cx)) * ((x) - (cx)) / ((rx) * (rx)) + ((y) - (cy)) * ((y) - (cy)) / ((ry) * (ry)) == 1)
+#define POINT_NOT_IN_ELLIPSE(x, y, cx, cy, rx, ry) (((x) - (cx)) * ((x) - (cx)) / ((rx) * (rx)) + ((y) - (cy)) * ((y) - (cy)) / ((ry) * (ry)) > 1)
+
+/* Used to identify how neighbouring tiles are used to compute bump and colour */
+#define TILE_CURRENT 0
+#define TILE_ABOVE 1
+#define TILE_BELOW 2
+#define TILE_LEFT 3
+#define TILE_RIGHT 4
+#define TILE_RIGHT_ABOVE 5
+#define TILE_RIGHT_BELOW 6
+#define TILE_LEFT_ABOVE 7
+#define TILE_LEFT_BELOW 8
+
+static float mod(float a, float b)
+{
+ /* Calculate a mod b for floating point numbers.
+ * NOTE: a can be negative however I'm not sure what behaviour this function
+ * has if b is negative
+ *
+ * NOTE: Copied from plugin brick.c by Unicorn. The original code was in Public
+ * Domain and is supplied with the Blender Texture Plugins repository.
+ */
+ int n = (int)(a / b);
+ a -= n * b;
+ if (a < 0) a += b;
+ return a;
+}
+
+static float smoothstep(float x, float a, float b)
+{
+ /* Calculate a step function as follows:
+ * y = 0 for x < 0
+ * y = -2x^2 + 3x^3 for 0 <= x <= 1
+ * y = 1 for x > 1
+ *
+ * Since we're using an interval of [a, b] instead of [0, 1]
+ * we have to transform x with (x - a) / (b - a).
+ */
+ float e;
+
+ if (a == b)
+ {
+ return (x < a) ? 0 : 1;
+ }
+
+ if (x < a) return 0;
+ if (x > b) return 1;
+
+ e = (x - a) / (b - a);
+ return e * e * (3 - 2 * e);
+}
+
+static int point_in_concave_polygon(float x, float y, float *vx, float *vy, short n)
+{
+ int i, j, c = 0;
+ for (i = 0, j = n-1; i < n; j = i++) {
+ if ((((vy[i]<=y) && (y<vy[j])) ||
+ ((vy[j]<=y) && (y<vy[i]))) &&
+ (x < (vx[j] - vx[i]) * (y - vy[i]) / (vy[j] - vy[i]) + vx[i]))
+ c = !c;
+ }
+ return c;
+}
+
+static float tiles_bevel_dim(Tex *tex, float w, float h)
+{
+ /* Determine the dimension of the tiles used to compute the bevel */
+ float s;
+ switch (tex->bevoption)
+ {
+ case TEX_BEVEL_UNIFORMMIN:
+ s = MIN2(tex->precalc.minw, tex->precalc.minh);
+ break;
+ case TEX_BEVEL_UNIFORMMAX:
+ s = MIN2(tex->precalc.maxw, tex->precalc.maxh);
+ break;
+ default:
+ s = MIN2(w, h);
+ break;
+ }
+ return s;
+}
+
+static float tiles_rect_func(float x, float y, float w, float h, float b, short bs)
+{
+ /* Calculate signed distance from the 4 sides of the rectangle bounded by:
+ * x = 0, y = 0, x = w, y = h.
+ * The sign indicates whether point is inside, on or outside the rectangle
+ * aiding us in applying gradients based on sidedness.
+ *
+ * NOTE: This is optimized version of tiles_poly_func()
+ */
+ float dx1 = x;
+ float dy1 = y;
+ float dx2 = w - x;
+ float dy2 = h - y;
+ float v = 0;
+
+ /* Find minimum distance to point from the 4 sides */
+ float dmin;
+
+ if ((x < 0) || (x > w) || (y < 0) || (y > h)) return 0;
+
+ switch (bs)
+ {
+ case TEX_BEVEL_HGRADIENT:
+ dmin = MIN2(dx1, dx2);
+ break;
+ case TEX_BEVEL_VGRADIENT:
+ dmin = MIN2(dy1, dy2);
+ break;
+ default:
+ dmin = MIN4(dx1, dx2, dy1, dy2);
+ break;
+ }
+
+ if (dmin > b) {
+ v = 1;
+ }
+ else if ((dmin >= 0) && (b > 0)) {
+ v = dmin / b;
+ }
+
+ return v;
+}
+
+static float tiles_rect_func2(float x, float y, float w, float h, float b, float sx, float sy, short bs)
+{
+ /* Calculate signed distance from the 8 lines:
+ * x = 0, y = 0, x = w, y = h,
+ * sy * x + sx * y - sx * sy = 0,
+ * sy * x - sx * y + sx * (h - sy) = 0,
+ * -sy * x + sx * y + sy * (w - sx) = 0,
+ * -sy * x - sx * y + sy * (w - sx) + sx * h = 0
+ *
+ * The sign indicates whether point is inside, on or outside the rectangle
+ * aiding us in applying gradients based on sidedness.
+ *
+ * NOTE: This is optimized version of tiles_poly_func()
+ */
+ float v = tiles_rect_func(x, y, w, h, b, bs);
+ float d1 = DIST_POINT_TO_LINE(sy, sx, -sx * sy, x, y);
+ float d2 = DIST_POINT_TO_LINE(sy, -sx, sx * (h - sy), x, y);
+ float d3 = DIST_POINT_TO_LINE(-sy, sx, sy * (w - sx), x, y);
+ float d4 = DIST_POINT_TO_LINE(-sy, -sx, sy * (w - sx) + sx * h, x, y);
+ float d;
+
+ switch (bs) {
+ case TEX_BEVEL_HGRADIENT:
+ case TEX_BEVEL_VGRADIENT:
+ if ((d1 < 0) || (d2 < 0) || (d3 < 0) || (d4 < 0)) d = 0;
+ else d = v;
+ break;
+ default:
+ LINE_BEVEL(d1, b);
+ LINE_BEVEL(d2, b);
+ LINE_BEVEL(d3, b);
+ LINE_BEVEL(d4, b);
+
+ d = MIN4(d1, d2, d3, d4);
+ break;
+ }
+
+ return MIN2(v, d);
+}
+
+static float tiles_poly_func(float x, float y, float *vx, float *vy, short n, float b, short bs)
+{
+ /* Do a linear gradient for an n-sided polygon from 0 for outer edge to 1
+ * for a distance b from outer edge inside the polygon. Any point beyond
+ * distance b inside the polygon gets intensity 1.
+ *
+ * NOTE: Specify polygon vertices counter-clockwise and n >= 3.
+ */
+ int i, i1;
+ float p[2], p1[2], p2[2];
+ float m, d, d1, dx;
+ float xmin, xmax, ymin, ymax, w, h;
+
+ /* Determine if p lies in the polygon */
+ p[0] = x;
+ p[1] = y;
+
+ switch (bs) {
+ case TEX_BEVEL_HGRADIENT:
+ case TEX_BEVEL_VGRADIENT:
+ xmin = vx[0];
+ ymin = vy[0];
+ xmax = xmin;
+ ymax = ymin;
+ for (i = 0; i < n; i++)
+ {
+ /* If point lies outside boundary just return 0. */
+ i1 = (i + 1) % n;
+ p1[0] = vx[i];
+ p1[1] = vy[i];
+ p2[0] = vx[i1];
+ p2[1] = vy[i1];
+ if (SIDE_OF_LINE(p1, p2, p) < 0) {
+ return 0;
+ }
+
+ xmin = MIN2(xmin, vx[i]);
+ ymin = MIN2(ymin, vy[i]);
+ xmax = MAX2(xmax, vx[i]);
+ ymax = MAX2(ymax, vy[i]);
+ }
+
+ w = xmax - xmin;
+ h = ymax - ymin;
+ d = tiles_rect_func(x - xmin, y - ymin, w, h, b, bs);
+ break;
+
+ default:
+ for (i = 0; i < n; i++)
+ {
+ /* If point lies outside boundary just return 0. */
+ i1 = (i + 1) % n;
+ p1[0] = vx[i];
+ p1[1] = vy[i];
+ p2[0] = vx[i1];
+ p2[1] = vy[i1];
+ if (SIDE_OF_LINE(p1, p2, p) < 0) {
+ return 0;
+ }
+
+ /* Compute distance to the line containing current side */
+ dx = p1[0] - p2[0];
+ if (fabs(dx) > 0) {
+ m = (p1[1] - p2[1]) / dx;
+ d1 = fabs(DIST_POINT_TO_LINE(m, -1, p1[1] - p1[0] * m, x, y));
+ }
+ else
+ {
+ d1 = fabs(x - p1[0]);
+ }
+
+ /* Take minimum distance so far */
+ d = (i == 0) ? d1 : MIN2(d, d1);
+ }
+
+ LINE_BEVEL(d, b);
+ break;
+ }
+ return d;
+}
+
+static float tiles_concave_poly_helper(float x, float y, float *vx, float *vy, int i, int n, float b)
+{
+ int j = i - 1;
+ int k = i + 1;
+ float l;
+ float v1[2], v2[2], v1p[2], v2p[2], vh[2];
+ float p1[2], p2[2], p3[2], p4[2], p[2];
+ float d1, dx, m;
+
+ /* Determine points on either side of point i */
+ if (j < 0) j = n - 1;
+ if (k >= n) k = 0;
+
+ /* Contruct vectors from i to neighbouring points j and k */
+ v1[0] = vx[j] - vx[i]; v1[1] = vy[j] - vy[i];
+ v2[0] = vx[k] - vx[i]; v2[1] = vy[k] - vy[i];
+
+ /* Scale to length b */
+ l = b / sqrt(v1[0] * v1[0] + v1[1] * v1[1]);
+ v1[0] *= l;
+ v1[1] *= l;
+
+ l = b / sqrt(v2[0] * v2[0] + v2[1] * v2[1]);
+ v2[0] *= l;
+ v2[1] *= l;
+
+ /* Calculate perpendicular vectors (whose length will be b).
+ * Note the order of signs, we're trying to get vectors that lie inside
+ * the convex polygon.
+ */
+ v1p[0] = v1[1]; v1p[1] = -v1[0];
+ v2p[0] = -v2[1]; v2p[1] = v2[0];
+
+ /* Add the 2 vectors to get a vector that is halfway between v1p and v2p.
+ * It is the opposite vector of v1 and v2's angle bisector.
+ */
+ vh[0] = v1p[0] + v2p[0];
+ vh[1] = v1p[1] + v2p[1];
+
+ /* p1, p2, p3, p4 define the quad in which points require beveling. */
+ p[0] = x; p[1] = y;
+ p1[0] = vx[i]; p1[1] = vy[i];
+ p2[0] = p1[0] + v2p[0]; p2[1] = p1[1] + v2p[1];
+ p3[0] = p1[0] + vh[0]; p3[1] = p1[1] + vh[1];
+ p4[0] = p1[0] + v1p[0]; p4[1] = p1[1] + v1p[1];
+
+ /* Depending on which side of the vector vh the point falls, apply a bevel with
+ * corresponding side of the polygon.
+ */
+ d1 = 1;
+ if (POINT_IN_TRI(p, p1, p2, p3)) {
+ dx = vx[i] - vx[k];
+ if (fabs(dx) > 0) {
+ m = (vy[i] - vy[k]) / dx;
+ d1 = fabs(DIST_POINT_TO_LINE(m, -1, vy[i] - vx[i] * m, x, y));
+ }
+ else {
+ d1 = fabs(x - vx[i]);
+ }
+ }
+ else if (POINT_IN_TRI(p, p1, p3, p4)) {
+ dx = vx[j] - vx[i];
+ if (fabs(dx) > 0) {
+ m = (vy[j] - vy[i]) / dx;
+ d1 = fabs(DIST_POINT_TO_LINE(m, -1, vy[j] - vx[j] * m, x, y));
+ }
+ else {
+ d1 = fabs(x - vx[j]);
+ }
+ }
+
+ return d1;
+}
+
+static float tiles_concave_poly_func(float x, float y, float *vx, float *vy, short n, float b, short bs)
+{
+ /* Handles both convex, concave and overlapping polygons */
+ int i, j, c = 0, set = 0;
+ float d = 0, d1, dx, m;
+ float doti, dotj;
+ float xmin, xmax, ymin, ymax, w, h;
+
+ switch (bs) {
+ case TEX_BEVEL_HGRADIENT:
+ case TEX_BEVEL_VGRADIENT:
+ xmin = vx[0];
+ ymin = vy[0];
+ xmax = xmin;
+ ymax = ymin;
+ for (i = 0, j = n-1; i < n; j = i++) {
+ if ((((vy[i] <= y) && (y < vy[j])) ||
+ ((vy[j] <= y) && (y < vy[i]))) &&
+ (x < (vx[j] - vx[i]) * (y - vy[i]) / (vy[j] - vy[i]) + vx[i]))
+ {
+ c = !c;
+ }
+
+ xmin = MIN2(xmin, vx[i]);
+ ymin = MIN2(ymin, vy[i]);
+ xmax = MAX2(xmax, vx[i]);
+ ymax = MAX2(ymax, vy[i]);
+ }
+ if (c) {
+ w = xmax - xmin;
+ h = ymax - ymin;
+ d = tiles_rect_func(x - xmin, y - ymin, w, h, b, bs);
+ }
+ else {
+ d = 0;
+ }
+ break;
+
+ default:
+ for (i = 0, j = n-1; i < n; j = i++) {
+ if ((((vy[i] <= y) && (y < vy[j])) ||
+ ((vy[j] <= y) && (y < vy[i]))) &&
+ (x < (vx[j] - vx[i]) * (y - vy[i]) / (vy[j] - vy[i]) + vx[i]))
+ {
+ c = !c;
+ }
+
+ /* Check if angles formed at points on the segment are obtuse to determine if
+ * the point falls between perpendicular lines at segment endpoints.
+ */
+ doti = (vx[j] - vx[i]) * (x - vx[i]) + (vy[j] - vy[i]) * (y - vy[i]);
+ dotj = (vx[i] - vx[j]) * (x - vx[j]) + (vy[i] - vy[j]) * (y - vy[j]);
+
+ if ((doti >= 0) && (dotj >= 0)) {
+ /* Compute distance to the line containing current side */
+ dx = vx[j] - vx[i];
+ if (fabs(dx) > 0) {
+ m = (vy[j] - vy[i]) / dx;
+ d1 = fabs(DIST_POINT_TO_LINE(m, -1, vy[j] - vx[j] * m, x, y));
+ }
+ else {
+ d1 = fabs(x - vx[j]);
+ }
+
+ /* Take minimum distance so far */
+ d = set ? MIN2(d, d1) : d1;
+ set = 1;
+ }
+ else if (doti < 0) {
+ d1 = tiles_concave_poly_helper(x, y, vx, vy, i, n, b);
+ d = set ? MIN2(d, d1) : d1;
+ set = 1;
+ }
+ else {
+ d1 = tiles_concave_poly_helper(x, y, vx, vy, j, n, b);
+ d = set ? MIN2(d, d1) : d1;
+ set = 1;
+ }
+ }
+ if (c) {
+ LINE_BEVEL(d, b);
+ }
+ else {
+ d = 0;
+ }
+ break;
+ }
+ return d;
+}
+
+static float tiles_circle_func1(float x, float y, float cx, float cy, float b, float r)
+{
+ /* Calculate signed distance from the circle bounded by:
+ * (x - cx)^2 + (y - cy)^2 = r^2
+ * The sign indicates whether point is inside, on or outside the circle
+ * aiding us in applying gradients based on sidedness.
+ *
+ * For points that lie within a distance of r - b from the center the intensity is 1.
+ * For points at distance of r - b to r, the intensity is linear from 1 to 0.
+ * For all other points the intensity is 0.
+ */
+ float dx = (x - cx);
+ float dy = (y - cy);
+ float d = r - sqrt(dx * dx + dy * dy);
+
+ float v = 0;
+ if (d > b) {
+ v = 1;
+ }
+ else if ((d >= 0) && (b > 0)) {
+ v = d / b;
+ }
+
+ return v;
+}
+
+static float tiles_circle_func2(float x, float y, float cx, float cy, float b, float r)
+{
+ /* Calculate signed distance from the circle bounded by:
+ * (x - cx)^2 + (y - cy)^2 = r^2
+ * The sign indicates whether point is inside, on or outside the circle
+ * aiding us in applying gradients based on sidedness.
+ *
+ * For points that lie within a distance of r - b from the center the intensity is 0.
+ * For points at distance of r - b to r, the intensity is linear from 0 to 1.
+ * For all other points the intensity is 1.
+ */
+ float dx = (x - cx);
+ float dy = (y - cy);
+ float d = sqrt(dx * dx + dy * dy) - r;
+
+ float v = 0;
+ if (d > b) {
+ v = 1;
+ }
+ else if ((d >= 0) && (b > 0)) {
+ v = d / b;
+ }
+
+ return v;
+}
+
+static float tiles_roundrect_func(float x, float y, float w, float h, float b, float r, short flip, short bs)
+{
+ /* First compute the intensity inside the rectangle bounded by (0, 0) and (w, h). */
+ float v = tiles_rect_func(x, y, w, h, b, bs);
+ float t = v;
+ float hw = w * 0.5;
+ float hh = h * 0.5;
+
+ if (flip) {
+ switch (bs) {
+ case TEX_BEVEL_HGRADIENT:
+ case TEX_BEVEL_VGRADIENT:
+ /* For points that lie inside the four corners determine if they fall inside the circle
+ * centered at the corners use black.
+ */
+ if ((x >= 0) && (x <= hw)) {
+ if ((y >= 0) && (y <= hh)) {
+ if (POINT_IN_CIRCLE(x, y, 0, 0, r)) t = 0;
+ }
+ else if ((y > hh) && (y <= h)) {
+ if (POINT_IN_CIRCLE(x, y, 0, h, r)) t = 0;
+ }
+ }
+ else if ((x > hw) && (x <= w)) {
+ if ((y >= 0) && (y <= hh)) {
+ if (POINT_IN_CIRCLE(x, y, w, 0, r)) t = 0;
+ }
+ else if ((y > hh) && (y <= h)) {
+ if (POINT_IN_CIRCLE(x, y, w, h, r)) t = 0;
+ }
+ }
+ break;
+ default:
+ /* For points that lie inside the four corners determine if they fall inside the circle
+ * centered at the corners and apply a linear gradient. This does the inverted circular
+ * shape.
+ */
+ if ((x >= 0) && (x <= hw)) {
+ if ((y >= 0) && (y <= hh)) {
+ t = tiles_circle_func2(x, y, 0, 0, b, r);
+ }
+ else if ((y > hh) && (y <= h)) {
+ t = tiles_circle_func2(x, y, 0, h, b, r);
+ }
+ }
+ else if ((x > hw) && (x <= w)) {
+ if ((y >= 0) && (y <= hh)) {
+ t = tiles_circle_func2(x, y, w, 0, b, r);
+ }
+ else if ((y > hh) && (y <= h)) {
+ t = tiles_circle_func2(x, y, w, h, b, r);
+ }
+ }
+ break;
+ }
+ }
+ else {
+ switch (bs) {
+ case TEX_BEVEL_HGRADIENT:
+ case TEX_BEVEL_VGRADIENT:
+ /* For points that lie inside the four corners determine if they fall outside the circle
+ * centered at the offset by the radius use black.
+ */
+ if ((x >= 0) && (x <= r)) {
+ if ((y >= 0) && (y <= r)) {
+ if (POINT_NOT_IN_CIRCLE(x, y, r, r, r)) t = 0;
+ }
+ else if ((y >= h - r) && (y <= h)) {
+ if (POINT_NOT_IN_CIRCLE(x, y, r, h - r, r)) t = 0;
+ }
+ }
+ else if ((x >= w - r) && (x <= w)) {
+ if ((y >= 0) && (y <= r)) {
+ if (POINT_NOT_IN_CIRCLE(x, y, w - r, r, r)) t = 0;
+ }
+ else if ((y >= h - r) && (y <= h)) {
+ if (POINT_NOT_IN_CIRCLE(x, y, w - r, h - r, r)) t = 0;
+ }
+ }
+ break;
+ default:
+ /* For points that lie inside the four corners determine if they fall inside the circle
+ * centered at the offset by the radius and apply a linear gradient.
+ */
+ if ((x >= 0) && (x <= r)) {
+ if ((y >= 0) && (y <= r)) {
+ t = tiles_circle_func1(x, y, r, r, b, r);
+ }
+ else if ((y >= h - r) && (y <= h)) {
+ t = tiles_circle_func1(x, y, r, h - r, b, r);
+ }
+ }
+ else if ((x >= w - r) && (x <= w)) {
+ if ((y >= 0) && (y <= r)) {
+ t = tiles_circle_func1(x, y, w - r, r, b, r);
+ }
+ else if ((y >= h - r) && (y <= h)) {
+ t = tiles_circle_func1(x, y, w - r, h - r, b, r);
+ }
+ }
+ break;
+ }
+ }
+ return MIN2(t, v);
+}
+
+static float tiles_ellipse_func1(float x, float y, float cx, float cy, float b, float rx, float ry)
+{
+ /* Calculate signed distance from the ellipse bounded by:
+ * [(x - cx) / rx]^2 + [(y - cy) / ry]^2 = 1
+ * The sign indicates whether point is inside, on or outside the ellipse
+ * aiding us in applying gradients based on sidedness.
+ *
+ * For points inside the ellipse from the center to distance b from the curve, intensity is 1.
+ * For points starting at distance b from the curve to the curve, the intensity is linear from 1 to 0.
+ * For all other points the intensity is 0.
+ */
+ float v, c, x1, y1, d, f, r2;
+
+ /* Shift origin to (0, 0) */
+ x -= cx;
+ y -= cy;
+
+ /* Compute the point (x1, y1) on the ellipse that forms a line through
+ * (0, 0) and (x, y).
+ */
+ f = sqrt(x * x * ry * ry + y * y * rx * rx);
+ r2 = rx * ry;
+ c = r2 / f;
+ x1 = x * c;
+ y1 = y * c;
+
+ /* Compute distance between the given point and computed point */
+ d = sqrt((x - x1)*(x - x1) + (y - y1)*(y - y1));
+
+ v = 0;
+
+ /* Test signed distance to see if point is inside or outside the ellipse */
+ if (f <= r2) {
+ /* Apply linear gradient */
+ if (d > b) {
+ v = 1;
+ }
+ else if (b > 0) {
+ v = d / b;
+ }
+ }
+
+ return v;
+}
+
+static float tiles_ellipse_func2(float x, float y, float cx, float cy, float b, float rx, float ry)
+{
+ /* Calculate signed distance from the ellipse bounded by:
+ * [(x - cx) / rx]^2 + [(y - cy) / ry]^2 = 1
+ * The sign indicates whether point is inside, on or outside the ellipse
+ * aiding us in applying gradients based on sidedness.
+ *
+ * For points inside the ellipse from the center to distance b from the curve, intensity is 0.
+ * For points starting at distance b from the curve to the curve, the intensity is linear from 0 to 1.
+ * For all other points the intensity is 1.
+ */
+ float v, c, x1, y1, d, f, r2;
+
+ /* Shift origin to (0, 0) */
+ x -= cx;
+ y -= cy;
+
+ /* Compute the point (x1, y1) on the ellipse that forms a line through
+ * (0, 0) and (x, y).
+ */
+ f = sqrt(x * x * ry * ry + y * y * rx * rx);
+ r2 = rx * ry;
+ c = r2 / f;
+ x1 = x * c;
+ y1 = y * c;
+
+ /* Compute distance between the given point and computed point */
+ d = sqrt((x - x1)*(x - x1) + (y - y1)*(y - y1));
+
+ v = 0;
+
+ /* Test signed distance to see if point is inside or outside the ellipse */
+ if (f >= r2) {
+ /* Apply linear gradient */
+ if (d > b) {
+ v = 1;
+ }
+ else if (b > 0) {
+ v = d / b;
+ }
+ }
+
+ return v;
+}
+
+static float tiles_ellipserect_func(float x, float y, float w, float h, float b, float rx, float ry, short flip, short bs)
+{
+ /* First compute the intensity inside the rectangle bounded by (0, 0) and (w, h). */
+ float v = tiles_rect_func(x, y, w, h, b, bs);
+ float t = v;
+ float hw = w * 0.5;
+ float hh = h * 0.5;
+
+ if (flip) {
+ switch (bs) {
+ case TEX_BEVEL_HGRADIENT:
+ case TEX_BEVEL_VGRADIENT:
+ /* For points that lie inside the four corners determine if they fall inside the ellipse
+ * centered at the corners use black.
+ */
+ if ((x >= 0) && (x <= hw)) {
+ if ((y >= 0) && (y <= hh)) {
+ if (POINT_IN_ELLIPSE(x, y, 0, 0, rx, ry)) t = 0;
+ }
+ else if ((y > hh) && (y <= h)) {
+ if (POINT_IN_ELLIPSE(x, y, 0, h, rx, ry)) t = 0;
+ }
+ }
+ else if ((x > hw) && (x <= w)) {
+ if ((y >= 0) && (y <= hh)) {
+ if (POINT_IN_ELLIPSE(x, y, w, 0, rx, ry)) t = 0;
+ }
+ else if ((y > hh) && (y <= h)) {
+ if (POINT_IN_ELLIPSE(x, y, w, h, rx, ry)) t = 0;
+ }
+ }
+ break;
+
+ default:
+ /* For points that lie inside the four corners determine if they fall inside the ellipse
+ * centered at the corners and apply a linear gradient. This does the inverted circular
+ * shape.
+ */
+ if ((x >= 0) && (x <= hw)) {
+ if ((y >= 0) && (y <= hh)) {
+ t = tiles_ellipse_func2(x, y, 0, 0, b, rx, ry);
+ }
+ else if ((y > hh) && (y <= h)) {
+ t = tiles_ellipse_func2(x, y, 0, h, b, rx, ry);
+ }
+ }
+ else if ((x > hw) && (x <= w)) {
+ if ((y >= 0) && (y <= hh)) {
+ t = tiles_ellipse_func2(x, y, w, 0, b, rx, ry);
+ }
+ else if ((y > hh) && (y <= h)) {
+ t = tiles_ellipse_func2(x, y, w, h, b, rx, ry);
+ }
+ }
+ break;
+ }
+ }
+ else {
+ switch (bs) {
+ case TEX_BEVEL_HGRADIENT:
+ case TEX_BEVEL_VGRADIENT:
+ /* For points that lie inside the four corners determine if they fall outside the ellipse
+ * centered at the offset by the radius use black.
+ */
+ if ((x >= 0) && (x <= rx)) {
+ if ((y >= 0) && (y <= ry)) {
+ if (POINT_NOT_IN_ELLIPSE(x, y, rx, ry, rx, ry)) t = 0;
+ }
+ else if ((y >= h - ry) && (y <= h)) {
+ if (POINT_NOT_IN_ELLIPSE(x, y, rx, h - ry, rx, ry)) t = 0;
+ }
+ }
+ else if ((x >= w - rx) && (x <= w)) {
+ if ((y >= 0) && (y <= ry)) {
+ if (POINT_NOT_IN_ELLIPSE(x, y, w - rx, ry, rx, ry)) t = 0;
+ }
+ else if ((y >= h - ry) && (y <= h)) {
+ if (POINT_NOT_IN_ELLIPSE(x, y, w - rx, h - ry, rx, ry)) t = 0;
+ }
+ }
+ break;
+ default:
+ /* For points that lie inside the four corners determine if they fall inside the ellipse
+ * centered at the offset (rx, ry) and apply a linear gradient.
+ */
+ if ((x >= 0) && (x <= rx)) {
+ if ((y >= 0) && (y <= ry)) {
+ t = tiles_ellipse_func1(x, y, rx, ry, b, rx, ry);
+ }
+ else if ((y >= h - ry) && (y <= h)) {
+ t = tiles_ellipse_func1(x, y, rx, h - ry, b, rx, ry);
+ }
+ }
+ else if ((x >= w - rx) && (x <= w)) {
+ if ((y >= 0) && (y <= ry)) {
+ t = tiles_ellipse_func1(x, y, w - rx, ry, b, rx, ry);
+ }
+ else if ((y >= h - ry) && (y <= h)) {
+ t = tiles_ellipse_func1(x, y, w - rx, h - ry, b, rx, ry);
+ }
+ }
+ break;
+ }
+ }
+ return MIN2(t, v);
+}
+
+/* Note: bs will override tex->bevelshading. To avoid that pass in tex->bevelshading for this param */
+static float tiles_recthelper_int(Tex *tex, float x, float y, float w, float h, float dim, float b, short bs)
+{
+ float rx, ry, intens;
+
+ switch (tex->corner) {
+ case TEX_CORNER_ROUND:
+ if (tex->hcorner == tex->vcorner) {
+ rx = tex->hcorner * dim;
+ intens = tiles_roundrect_func(x, y, w, h, b, rx, 0, bs);
+ }
+ else {
+ rx = tex->hcorner * dim;
+ ry = tex->vcorner * dim;
+ intens = tiles_ellipserect_func(x, y, w, h, b, rx, ry, 0, bs);
+ }
+ break;
+ case TEX_CORNER_ROUND_INV:
+ if (tex->hcorner == tex->vcorner) {
+ rx = tex->hcorner * dim;
+ intens = tiles_roundrect_func(x, y, w, h, b, rx, 1, bs);
+ }
+ else {
+ rx = tex->hcorner * dim;
+ ry = tex->vcorner * dim;
+ intens = tiles_ellipserect_func(x, y, w, h, b, rx, ry, 1, bs);
+ }
+ break;
+ case TEX_CORNER_ELLIPSE:
+ rx = tex->hcorner * w;
+ ry = tex->vcorner * h;
+ intens = tiles_ellipserect_func(x, y, w, h, b, rx, ry, 0, bs);
+ break;
+ case TEX_CORNER_ELLIPSE_INV:
+ rx = tex->hcorner * w;
+ ry = tex->vcorner * h;
+ intens = tiles_ellipserect_func(x, y, w, h, b, rx, ry, 1, bs);
+ break;
+ case TEX_CORNER_STRAIGHT:
+ rx = tex->hcorner * w;
+ ry = tex->vcorner * h;
+ intens = tiles_rect_func2(x, y, w, h, b, rx, ry, bs);
+ break;
+ default:
+ intens = tiles_rect_func(x, y, w, h, b, bs);
+ break;
+ }
+
+ return intens;
+}
+
+static void tiles_default_col(Tex *tex, float intens, short htileid, short vtileid, float *col)
+{
+ float intens1 = 1.0 - intens;
+ col[0] = tex->precalc.r[htileid][vtileid] * intens + tex->colr2 * intens1;
+ col[1] = tex->precalc.g[htileid][vtileid] * intens + tex->colg2 * intens1;
+ col[2] = tex->precalc.b[htileid][vtileid] * intens + tex->colb2 * intens1;
+}
+
+static void tiles_neighbour_col(Tex *tex, float *intens, short htileid, short vtileid, short id, short i, float *col)
+{
+ float intens1 = 1.0 - (*intens);
+ float s;
+ short htileidl, htileidr, vtileida, vtileidb;
+
+ /* Compute indices of neighbouring tiles */
+ htileidr = (htileid + 1) % tex->hcount; /* Right */
+ htileidl = (htileid - 1 + tex->hcount) % tex->hcount; /* Left */
+ vtileida = (vtileid + 1) % tex->vcount; /* Above */
+ vtileidb = (vtileid - 1 + tex->vcount) % tex->vcount; /* Below */
+
+ /* Default colour of current tile */
+ col[0] = tex->precalc.r[htileid][vtileid];
+ col[1] = tex->precalc.g[htileid][vtileid];
+ col[2] = tex->precalc.b[htileid][vtileid];
+ s = tex->precalc.bpat[htileid][vtileid];
+
+ /* Add colours of neighbouring tiles and do uniform average */
+ switch (id) {
+ case TILE_BELOW:
+ col[0] += tex->precalc.r[htileid][vtileidb];
+ col[1] += tex->precalc.g[htileid][vtileidb];
+ col[2] += tex->precalc.b[htileid][vtileidb];
+ col[0] *= 0.5;
+ col[1] *= 0.5;
+ col[2] *= 0.5;
+
+ s += tex->precalc.bpat[htileid][vtileidb];
+ s *= 0.5;
+
+ break;
+ case TILE_ABOVE:
+ col[0] += tex->precalc.r[htileid][vtileida];
+ col[1] += tex->precalc.g[htileid][vtileida];
+ col[2] += tex->precalc.b[htileid][vtileida];
+ col[0] *= 0.5;
+ col[1] *= 0.5;
+ col[2] *= 0.5;
+
+ s += tex->precalc.bpat[htileid][vtileida];
+ s *= 0.5;
+
+ break;
+ case TILE_LEFT:
+ col[0] += tex->precalc.r[htileidl][vtileid];
+ col[1] += tex->precalc.g[htileidl][vtileid];
+ col[2] += tex->precalc.b[htileidl][vtileid];
+ col[0] *= 0.5;
+ col[1] *= 0.5;
+ col[2] *= 0.5;
+
+ s += tex->precalc.bpat[htileidl][vtileid];
+ s *= 0.5;
+
+ break;
+ case TILE_RIGHT:
+ col[0] += tex->precalc.r[htileidr][vtileid];
+ col[1] += tex->precalc.g[htileidr][vtileid];
+ col[2] += tex->precalc.b[htileidr][vtileid];
+ col[0] *= 0.5;
+ col[1] *= 0.5;
+ col[2] *= 0.5;
+
+ s += tex->precalc.bpat[htileidr][vtileid];
+ s *= 0.5;
+
+ break;
+ case TILE_LEFT_BELOW:
+ col[0] += tex->precalc.r[htileidl][vtileid] + tex->precalc.r[htileidl][vtileidb] + tex->precalc.r[htileid][vtileidb];
+ col[1] += tex->precalc.g[htileidl][vtileid] + tex->precalc.g[htileid][vtileidb] + tex->precalc.g[htileidl][vtileidb];
+ col[2] += tex->precalc.b[htileidl][vtileid] + tex->precalc.b[htileidl][vtileidb] + tex->precalc.b[htileid][vtileidb];
+ col[0] *= 0.25;
+ col[1] *= 0.25;
+ col[2] *= 0.25;
+
+ s += tex->precalc.bpat[htileidl][vtileid] + tex->precalc.bpat[htileidl][vtileidb] + tex->precalc.bpat[htileid][vtileidb];
+ s *= 0.25;
+
+ break;
+ case TILE_LEFT_ABOVE:
+ col[0] += tex->precalc.r[htileidl][vtileid] + tex->precalc.r[htileidl][vtileida] + tex->precalc.r[htileid][vtileida];
+ col[1] += tex->precalc.g[htileidl][vtileid] + tex->precalc.g[htileid][vtileida] + tex->precalc.g[htileidl][vtileida];
+ col[2] += tex->precalc.b[htileidl][vtileid] + tex->precalc.b[htileidl][vtileida] + tex->precalc.b[htileid][vtileida];
+ col[0] *= 0.25;
+ col[1] *= 0.25;
+ col[2] *= 0.25;
+
+ s += tex->precalc.bpat[htileidl][vtileid] + tex->precalc.bpat[htileidl][vtileida] + tex->precalc.bpat[htileid][vtileida];
+ s *= 0.25;
+
+ break;
+ case TILE_RIGHT_BELOW:
+ col[0] += tex->precalc.r[htileidr][vtileid] + tex->precalc.r[htileidr][vtileidb] + tex->precalc.r[htileid][vtileidb];
+ col[1] += tex->precalc.g[htileidr][vtileid] + tex->precalc.g[htileid][vtileidb] + tex->precalc.g[htileidr][vtileidb];
+ col[2] += tex->precalc.b[htileidr][vtileid] + tex->precalc.b[htileidr][vtileidb] + tex->precalc.b[htileid][vtileidb];
+ col[0] *= 0.25;
+ col[1] *= 0.25;
+ col[2] *= 0.25;
+
+ s += tex->precalc.bpat[htileidr][vtileid] + tex->precalc.bpat[htileidr][vtileidb] + tex->precalc.bpat[htileid][vtileidb];
+ s *= 0.25;
+
+ break;
+ case TILE_RIGHT_ABOVE:
+ col[0] += tex->precalc.r[htileidr][vtileid] + tex->precalc.r[htileidr][vtileida] + tex->precalc.r[htileid][vtileida];
+ col[1] += tex->precalc.g[htileidr][vtileid] + tex->precalc.g[htileid][vtileida] + tex->precalc.g[htileidr][vtileida];
+ col[2] += tex->precalc.b[htileidr][vtileid] + tex->precalc.b[htileidr][vtileida] + tex->precalc.b[htileid][vtileida];
+ col[0] *= 0.25;
+ col[1] *= 0.25;
+ col[2] *= 0.25;
+
+ s += tex->precalc.bpat[htileidr][vtileid] + tex->precalc.bpat[htileidr][vtileida] + tex->precalc.bpat[htileid][vtileida];
+ s *= 0.25;
+
+ break;
+ }
+ *intens *= s;
+
+ /* Additional random scaling */
+ if (i >= 0) *intens *= tex->precalc.rpat[i];
+
+ /* Linearly interpolate the 2 colours */
+ col[0] = col[0] * (*intens) + tex->colr2 * intens1;
+ col[1] = col[1] * (*intens) + tex->colg2 * intens1;
+ col[2] = col[2] * (*intens) + tex->colb2 * intens1;
+}
+
+static float tiles_bevel_func(Tex *tex, float intens)
+{
+ float icubic1, icubic2, i;
+
+ /* Apply bevel strength and center the result in [0, 1] */
+ intens *= tex->strength;
+ intens += (1.0 - tex->strength) * 0.5;
+
+ /* Map the intensity x to the 2 functions: x^3, 1+(x-1)^3. */
+ icubic1 = intens * intens * intens;
+ icubic2 = intens - 1.0;
+ icubic2 *= icubic2 * icubic2;
+ icubic2 += 1.0;
+
+ if (tex->curve <= 0) {
+ /* Do a linear blend between 1 + (x - 1)^3 and x functions */
+ i = tex->curve + 1;
+ intens = (1 - i) * icubic2 + i * intens;
+ }
+ else {
+ /* Do a linear blend between x and xi^3 functions */
+ i = tex->curve;
+ intens = (1 - i) * intens + i * icubic1;
+ }
+
+ /* Smooth out the result using a cubic step function */
+ if (tex->smooth) {
+ intens = smoothstep(intens, 0, 1);
+ }
+
+ return intens;
+}
+
+static float tiles_default_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, float *col)
+{
+ /* This handles the default tiling with different corner styles */
+ float intens;
+ float w, h, dim;
+
+ /* Compute tile dimensions */
+ w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ /* Bevel */
+ dim = tiles_bevel_dim(tex, w, h);
+
+ /* Compute intensity. */
+ intens = tiles_recthelper_int(tex, x, y, w, h, dim, dim * tex->bevel, tex->bevelshading);
+ intens *= tex->precalc.bpat[htileid][vtileid];
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_default_col(tex, intens, htileid, vtileid, col);
+
+ return intens;
+}
+
+static float tiles_cross1_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, float *col)
+{
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float dim = tiles_bevel_dim(tex, w, h);
+ float b = dim * tex->bevel;
+ float intens = 0;
+ short id = TILE_CURRENT;
+ short bs = tex->bevelshading;
+ float vx[12], vy[12];
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ vx[0] = w * 0.25; vy[0] = 0;
+ vx[1] = w * 0.75; vy[1] = 0;
+ vx[2] = w * 0.75; vy[2] = h * 0.25;
+ vx[3] = w; vy[3] = h * 0.25;
+ vx[4] = w; vy[4] = h * 0.75;
+ vx[5] = w * 0.75; vy[5] = h * 0.75;
+ vx[6] = w * 0.75; vy[6] = h;
+ vx[7] = w * 0.25; vy[7] = h;
+ vx[8] = w * 0.25; vy[8] = h * 0.75;
+ vx[9] = 0; vy[9] = h * 0.75;
+ vx[10]= 0; vy[10]= h * 0.25;
+ vx[11]= w * 0.25; vy[11]= h * 0.25;
+
+ intens = tiles_concave_poly_func(x, y, vx, vy, 12, b, bs);
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, -1, col);
+
+ return intens;
+}
+
+static float tiles_cross2_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, float *col)
+{
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float dim = tiles_bevel_dim(tex, w, h);
+ float b = dim * tex->bevel;
+ float intens = 0;
+ short id = TILE_CURRENT;
+ short bs = tex->bevelshading;
+ float vx[12], vy[12];
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ vx[0] = w * 0.15; vy[0] = 0;
+ vx[1] = w * 0.85; vy[1] = 0;
+ vx[2] = w * 0.75; vy[2] = h * 0.25;
+ vx[3] = w; vy[3] = h * 0.15;
+ vx[4] = w; vy[4] = h * 0.85;
+ vx[5] = w * 0.75; vy[5] = h * 0.75;
+ vx[6] = w * 0.85; vy[6] = h;
+ vx[7] = w * 0.15; vy[7] = h;
+ vx[8] = w * 0.25; vy[8] = h * 0.75;
+ vx[9] = 0; vy[9] = h * 0.85;
+ vx[10]= 0; vy[10]= h * 0.15;
+ vx[11]= w * 0.25; vy[11]= h * 0.25;
+
+ intens = tiles_concave_poly_func(x, y, vx, vy, 12, b, bs);
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, -1, col);
+
+ return intens;
+}
+
+static float tiles_hex_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, float *col)
+{
+ /* The tight honeycomb pattern is generated using tiles that are not shifted every
+ * row. So assuming, the rows are not being shifted, we can do a "lollipop" shape
+ * with a hexagon which will stretch from one rectangular cell to another but will
+ * remain seamless as long as tex->hgap = tex->vgap = 0.
+ * _______
+ * / \
+ * / \_______
+ * \ /
+ * \_______/
+ *
+ * Now note that points that fall above and below the "stick" AND points that fall
+ * to the left of the hexagon have to be tested inside a hexagon that is in the neighbouring
+ * tile. A total of 5 hexagon's need to tested for inclusion of given point.
+ */
+ float c = 1.0 / 6.0;
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float d = w * c;
+ float r = h * 0.5;
+ float b = tiles_bevel_dim(tex, 4 * d, h) * tex->bevel; /* Hex part is 4*d wide */
+ float wl, wr, dl, dr;
+ float ha, hb, ra, rb;
+ short htidl, htidr, vtida, vtidb;
+ float intens = 0;
+ float intens2;
+ short id = TILE_CURRENT; /* Determines how to use color and bump info from neighbouring tiles */
+ float vx[6], vy[6];
+ short bs = tex->bevelshading;
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ /* Width of tile to right */
+ htidr = (htileid + 1) % tex->hcount;
+ wr = tex->precalc.hpat[htidr + 1] - tex->precalc.hpat[htidr] - tex->precalc.hgap;
+ dr = wr * c;
+ /* Width of tile to left */
+ htidl = (htileid - 1 + tex->hcount) % tex->hcount;
+ wl = tex->precalc.hpat[htidl + 1] - tex->precalc.hpat[htidl] - tex->precalc.hgap;
+ dl = wl * c;
+ /* Height of tile above */
+ vtida = (vtileid + 1) % tex->vcount;
+ ha = tex->precalc.vpat[vtida + 1] - tex->precalc.vpat[vtida] - tex->precalc.vgap;
+ ra = ha * 0.5;
+ /* Height of tile below */
+ vtidb = (vtileid - 1 + tex->vcount) % tex->vcount;
+ hb = tex->precalc.vpat[vtidb + 1] - tex->precalc.vpat[vtidb] - tex->precalc.vgap;
+ rb = hb * 0.5;
+
+ /* Handle hexagon in current tile */
+ vx[0] = d; vy[0] = 0;
+ vx[1] = 3 * d; vy[1] = 0;
+ vx[2] = 4 * d; vy[2] = r;
+ vx[3] = 3 * d; vy[3] = h;
+ vx[4] = d; vy[4] = h;
+ vx[5] = 0; vy[5] = r;
+ intens = tiles_poly_func(x, y, vx, vy, 6, b, bs);
+
+ /* Handle sections that overlap with other tiles. Note that we do a MAX of current
+ * intens value with the next tile in question. This cleans up the code and seems
+ * to fix up any artifacts in the bevels.
+ */
+ if ((x >= 3 * d) && (x <= w)) {
+ /* Take the width of the next tile to the right into consideration */
+ if ((y >= 0) && (y <= r)) {
+ /* Take the height of the next tile below into consideration */
+ b = tiles_bevel_dim(tex, 3 * d + dr, r + rb) * tex->bevel;
+ vx[0] = 4 * d; vy[0] = -rb;
+ vx[1] = w; vy[1] = -rb;
+ vx[2] = w + dr; vy[2] = 0;
+ vx[3] = w; vy[3] = r;
+ vx[4] = 4 * d; vy[4] = r;
+ vx[5] = 3 * d; vy[5] = 0;
+ intens2 = tiles_poly_func(x, y, vx, vy, 6, b, bs);
+ if (intens2 > intens) {
+ intens = intens2;
+ id = TILE_RIGHT_BELOW;
+ }
+ }
+ else if ((y > r) && (y <= h)) {
+ /* Take the height of the next tile above into consideration */
+ b = tiles_bevel_dim(tex, 3 * d + dr, r + ra) * tex->bevel;
+ vx[0] = 4 * d; vy[0] = r;
+ vx[1] = w; vy[1] = r;
+ vx[2] = w + dr; vy[2] = h;
+ vx[3] = w; vy[3] = h + ra;
+ vx[4] = 4 * d; vy[4] = h + ra;
+ vx[5] = 3 * d; vy[5] = h;
+ intens2 = tiles_poly_func(x, y, vx, vy, 6, b, bs);
+ if (intens2 > intens) {
+ intens = intens2;
+ id = TILE_RIGHT_ABOVE;
+ }
+ }
+ }
+ else if ((x >= 0) && (x <= d)) {
+ /* Take the width of the next tile to the left into consideration */
+ if ((y >= 0) && (y <= r)) {
+ /* Take the height of the next tile below into consideration */
+ b = tiles_bevel_dim(tex, 3 * dl + d, r + rb) * tex->bevel;
+ vx[0] = d; vy[0] = 0;
+ vx[1] = 0; vy[1] = r;
+ vx[2] = -2 * dl; vy[2] = r;
+ vx[3] = -3 * dl; vy[3] = 0;
+ vx[4] = -2 * dl; vy[4] = -rb;
+ vx[5] = 0; vy[5] = -rb;
+ intens2 = tiles_poly_func(x, y, vx, vy, 6, b, bs);
+ if (intens2 > intens) {
+ intens = intens2;
+ id = TILE_LEFT_BELOW;
+ }
+ }
+ else if ((y > r) && (y <= h)) {
+ /* Take the height of the next tile above into consideration */
+ b = tiles_bevel_dim(tex, 3 * dl + d, r + ra) * tex->bevel;
+ vx[0] = d; vy[0] = h;
+ vx[1] = 0; vy[1] = h + ra;
+ vx[2] = -2 * dl; vy[2] = h + ra;
+ vx[3] = -3 * dl; vy[3] = h;
+ vx[4] = -2 * dl; vy[4] = r;
+ vx[5] = 0; vy[5] = r;
+ intens2 = tiles_poly_func(x, y, vx, vy, 6, b, bs);
+ if (intens2 > intens) {
+ intens = intens2;
+ id = TILE_LEFT_ABOVE;
+ }
+ }
+ }
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, -1, col);
+
+ return intens;
+}
+
+static float tiles_herringbone_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, short n, float *col)
+{
+ /* Creates a nx1 seamless pattern for herringbone tiling where n >= 2. */
+
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float w1 = 0.5 * w;
+ float h1 = 0.5 * h;
+ float half_over_n = 0.5 / (float)n;
+ float xstep = w * half_over_n;
+ float ystep = h * half_over_n;
+ float dim, b;
+ short loop = 1;
+ float xi, yi;
+ float intens = 0;
+ short i = -1; /* Used to determine sections that cross seams */
+ short id = TILE_CURRENT;
+ short bs;
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ while (loop) {
+ if ((x < 0) || (x > w) || (y < 0) || (y > h)) break;
+
+ /* Handle horizontal bars */
+ dim = tiles_bevel_dim(tex, w1, ystep);
+ if (tex->bevelshading == TEX_BEVEL_PATTERN) {
+ bs = (tex->corner == TEX_CORNER_STRAIGHT) ? TEX_BEVEL_VGRADIENT : TEX_BEVEL_HGRADIENT;
+ b = w1 * tex->bevel;
+ }
+ else {
+ bs = tex->bevelshading;
+ b = dim * tex->bevel;
+ }
+
+ yi = 0;
+ i = 0;
+ if (tex->bevoption != TEX_BEVEL_DEFAULTMIN) dim *= half_over_n;
+ for (xi = 0; xi < w + xstep; xi += xstep)
+ {
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, w1, ystep, dim, b, bs);
+ if (intens > 0) {
+ if (i > n) id = TILE_RIGHT;
+ i = i % 16;
+ break;
+ }
+ yi += ystep;
+ i++;
+ }
+ if (intens > 0) break;
+
+ /* Handle the seamless sections of horizontal bars */
+ yi = h - (n - 1) * ystep;
+ i = n + 1;
+ for (xi = (1 - n) * xstep; xi < 0; xi += xstep)
+ {
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, w1, ystep, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_LEFT;
+ i = i % 16;
+ break;
+ }
+ yi += ystep;
+ i++;
+ }
+ if (intens > 0) break;
+
+ /* Handle vertical bars */
+ dim = tiles_bevel_dim(tex, xstep, h1);
+ if (tex->bevelshading == TEX_BEVEL_PATTERN) {
+ bs = (tex->corner == TEX_CORNER_STRAIGHT) ? TEX_BEVEL_HGRADIENT : TEX_BEVEL_VGRADIENT;
+ b = h1 * tex->bevel;
+ }
+ else {
+ bs = tex->bevelshading;
+ b = dim * tex->bevel;
+ }
+
+ xi = 0;
+ i = 0;
+ if (tex->bevoption != TEX_BEVEL_DEFAULTMIN) dim *= half_over_n;
+ for (yi = ystep; yi < h + ystep; yi += ystep)
+ {
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, xstep, h1, dim, b, bs);
+ if (intens > 0) {
+ if (i >= n) id = TILE_ABOVE;
+ i = 15 - i % 16;
+ break;
+ }
+ xi += xstep;
+ i++;
+ }
+ if (intens > 0) break;
+
+ /* Handle the seamless sections of vertical bars */
+ xi = w1;
+ i = n;
+ for (yi = (1 - n) * ystep; yi < ystep; yi += ystep)
+ {
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, xstep, h1, dim, b, bs);
+ if (intens > 0) {
+ if (i < 2*n-1) id = TILE_BELOW;
+ i = 15 - i % 16;
+ break;
+ }
+ xi += xstep;
+ i++;
+ }
+ if (intens > 0) break;
+
+ /* Important: End loop */
+ loop = 0;
+ i = -1;
+ }
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, i, col);
+
+ return intens;
+}
+
+static float tiles_interlock1_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, float *col)
+{
+ /* Generate a pattern as follows:
+ * _______
+ * | |
+ * |_______|
+ * | | |
+ * |___|___|
+ * The pattern rotates 90 degrees and after 4 tile repitions it repeats.
+ * If tex->hcount is not a multiple of 4, the repitions will stop before
+ * multiple of 360 degrees is reached.
+ */
+
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float w2 = 0.5 * w;
+ float h2 = 0.5 * h;
+ float dim = tiles_bevel_dim(tex, w2, h2);
+ float b = dim * tex->bevel;
+ float intens = 0;
+ short i = htileid % 4;
+ short id;
+ short bs = tex->bevelshading;
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ if (i == 0) {
+ if (y >= h2) {
+ intens = tiles_recthelper_int(tex, x, y - h2, w, h2, dim, b, bs);
+ id = TILE_ABOVE;
+ }
+ else if (x <= w2) {
+ intens = tiles_recthelper_int(tex, x, y, w2, h2, dim, b, bs);
+ id = TILE_LEFT;
+ }
+ else {
+ intens = tiles_recthelper_int(tex, x - w2, y, w2, h2, dim, b, bs);
+ id = TILE_RIGHT;
+ }
+ }
+ else if (i == 1) {
+ if (x >= w2) {
+ intens = tiles_recthelper_int(tex, x - w2, y, w2, h, dim, b, bs);
+ id = TILE_LEFT;
+ }
+ else if (y <= h2) {
+ intens = tiles_recthelper_int(tex, x, y, w2, h2, dim, b, bs);
+ id = TILE_RIGHT;
+ }
+ else {
+ intens = tiles_recthelper_int(tex, x, y - h2, w2, h2, dim, b, bs);
+ id = TILE_ABOVE;
+ }
+ }
+ else if (i == 2) {
+ if (y <= h2) {
+ intens = tiles_recthelper_int(tex, x, y, w, h2, dim, b, bs);
+ id = TILE_BELOW;
+ }
+ else if (x <= w2) {
+ intens = tiles_recthelper_int(tex, x, y - h2, w2, h2, dim, b, bs);
+ id = TILE_LEFT;
+ }
+ else {
+ intens = tiles_recthelper_int(tex, x - w2, y - h2, w2, h2, dim, b, bs);
+ id = TILE_RIGHT;
+ }
+ }
+ else {
+ if (x <= w2) {
+ intens = tiles_recthelper_int(tex, x, y, w2, h, dim, b, bs);
+ id = TILE_RIGHT;
+ }
+ else if (y <= h2) {
+ intens = tiles_recthelper_int(tex, x - w2, y, w2, h2, dim, b, bs);
+ id = TILE_BELOW;
+ }
+ else {
+ intens = tiles_recthelper_int(tex, x - w2, y - h2, w2, h2, dim, b, bs);
+ id = TILE_ABOVE;
+ }
+ }
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, -1, col);
+
+ return intens;
+}
+
+static float tiles_interlock2_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, short n, float *col)
+{
+ /* Generate a pattern of n blocks as follows:
+ * ___ ___ ___ ___
+ * | | | | |
+ * | | | | | ....
+ * | | | | |
+ * |___|___|___|___|
+ * The pattern rotates 90 degrees and after 2 tile repitions it repeats.
+ * If tex->hcount is not a multiple of 2, the repitions will stop before
+ * multiple of 180 degrees is reached.
+ */
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float factor = 1.0 / (float)n;
+ float w2 = factor * w;
+ float h2 = factor * h;
+ float dim, b;
+ float intens = 0;
+ short i = htileid % 2;
+ short id = TILE_CURRENT;
+ short k;
+ short r = 0;
+ short bs = tex->bevelshading;
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ if (i == 0) {
+ /* I don't understand why the following doesn't work:
+ * intens = tiles_recthelper_int(tex, x, y - floor(y / h2) * h2, w, h2, dim, tex->bevelshading);
+ * Hence the looped version.
+ */
+ if (bs == TEX_BEVEL_PATTERN) bs = TEX_BEVEL_VGRADIENT;
+ dim = tiles_bevel_dim(tex, w, h2);
+ b = dim * tex->bevel;
+ for (k = 0; k < n; k++) {
+ if (y <= (k + 1) * h2) {
+ intens = tiles_recthelper_int(tex, x, y - k * h2, w, h2, dim, b, bs);
+ r = k;
+ break;
+ }
+ }
+ }
+ else {
+ if (bs == TEX_BEVEL_PATTERN) bs = TEX_BEVEL_HGRADIENT;
+ dim = tiles_bevel_dim(tex, w2, h);
+ b = dim * tex->bevel;
+ for (k = 0; k < n; k++) {
+ if (x <= (k + 1) * w2) {
+ intens = tiles_recthelper_int(tex, x - k * w2, y, w2, h, dim, b, bs);
+ r = k;
+ break;
+ }
+ }
+ }
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, r % 16, col);
+
+ return intens;
+}
+
+static float tiles_interlock3_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, float *col)
+{
+ /* Assuming, the rows are not being shifted, we can do the following pattern
+ * which will stretch from one rectangular cell to another but will
+ * remain seamless as long as tex->hgap = tex->vgap = 0.
+ * |__|
+ * __/ \__
+ * __| |__
+ * \____/
+ * | |
+ *
+ * The figure above is ugly but it generates regular octagons interlocked with squares and
+ * the edge length of squares and octagons will be equal.
+ */
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float intens = 0;
+ short id = TILE_CURRENT;
+ short bs = tex->bevelshading;
+ float s1 = 0; /* Don't ask how I came up with these numbers :) */
+ float s2 = 0.14645;
+ float s3 = 0.35356;
+ float s4 = 0.64644;
+ float s5 = 0.85355;
+ float s6 = 1;
+ float s = s4 - s3; /* Edge length of octagons and squares */
+ float sh = s * 0.5;
+ float sr = s * M_SQRT1_2;
+ float wl, wr, dl, dr;
+ float ha, hb, ra, rb;
+ short htidl, htidr, vtida, vtidb;
+ float vx[8], vy[8];
+ float b;
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ if ((x >= 0) && (x <= w) && (y >= 0) && (y <= h))
+ {
+ /* Width of tile to right */
+ htidr = (htileid + 1) % tex->hcount;
+ wr = tex->precalc.hpat[htidr + 1] - tex->precalc.hpat[htidr] - tex->precalc.hgap;
+ /* Width of tile to left */
+ htidl = (htileid - 1 + tex->hcount) % tex->hcount;
+ wl = tex->precalc.hpat[htidl + 1] - tex->precalc.hpat[htidl] - tex->precalc.hgap;
+ /* Height of tile above */
+ vtida = (vtileid + 1) % tex->vcount;
+ ha = tex->precalc.vpat[vtida + 1] - tex->precalc.vpat[vtida] - tex->precalc.vgap;
+ /* Height of tile below */
+ vtidb = (vtileid - 1 + tex->vcount) % tex->vcount;
+ hb = tex->precalc.vpat[vtidb + 1] - tex->precalc.vpat[vtidb] - tex->precalc.vgap;
+
+ /* NOTE: All polygons are defined counter-clockwise */
+
+ /* Central octagon */
+ vx[0] = s3 * w; vy[0] = s2 * h;
+ vx[1] = s4 * w; vy[1] = s2 * h;
+ vx[2] = s5 * w; vy[2] = s3 * h;
+ vx[3] = s5 * w; vy[3] = s4 * h;
+ vx[4] = s4 * w; vy[4] = s5 * h;
+ vx[5] = s3 * w; vy[5] = s5 * h;
+ vx[6] = s2 * w; vy[6] = s4 * h;
+ vx[7] = s2 * w; vy[7] = s3 * h;
+ b = tiles_bevel_dim(tex, vx[2] - vx[6], vy[4] - vy[0]) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 8, b, bs);
+
+ /* Squares (rectangles if random widths/heights) */
+ if (intens <= 0) {
+ /* Bottom */
+ vx[0] = s4 * w; vy[0] = s2 * h;
+ vx[1] = s3 * w; vy[1] = vy[0];
+ vx[2] = vx[1]; vy[2] = vy[1] - sh * (h + hb);
+ vx[3] = vx[0]; vy[3] = vy[2];
+ b = tiles_bevel_dim(tex, s, sh * (h + hb)) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 4, b, bs);
+ id = TILE_BELOW;
+ }
+ if (intens <= 0) {
+ /* Top */
+ vx[0] = s3 * w; vy[0] = s5 * h;
+ vx[1] = s4 * w; vy[1] = vy[0];
+ vx[2] = vx[1]; vy[2] = vy[1] + sh * (h + ha);
+ vx[3] = vx[0]; vy[3] = vy[2];
+ b = tiles_bevel_dim(tex, s, sh * (h + ha)) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 4, b, bs);
+ id = TILE_ABOVE;
+ }
+ if (intens <= 0) {
+ /* Left */
+ vx[0] = s2 * w; vy[0] = s3 * h;
+ vx[1] = vx[0]; vy[1] = s4 * h;
+ vx[2] = vx[1] - sh * (w + wl); vy[2] = vy[1];
+ vx[3] = vx[2]; vy[3] = vy[0];
+ b = tiles_bevel_dim(tex, s, sh * (w + wl)) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 4, b, bs);
+ id = TILE_LEFT;
+ }
+ if (intens <= 0) {
+ /* Right */
+ vx[0] = s5 * w; vy[0] = s3 * h;
+ vx[1] = vx[0] + sh * (w + wr); vy[1] = vy[0];
+ vx[2] = vx[1]; vy[2] = s4 * h;
+ vx[3] = vx[0]; vy[3] = vy[2];
+ b = tiles_bevel_dim(tex, s, sh * (w + wr)) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 4, b, bs);
+ id = TILE_RIGHT;
+ }
+
+ /* More octagons */
+ if (intens <= 0) {
+ /* Bottom Left */
+ vx[0] = s3 * w; vy[0] = s2 * h;
+ vx[1] = s2 * w; vy[1] = s3 * h;
+ vx[2] = vx[1] - sh * (w + wl); vy[2] = vy[1];
+ vx[3] = vx[2] - sr * wl; vy[3] = vy[0];
+ vx[4] = vx[3]; vy[4] = vy[3] - sh * (h + hb);
+ vx[5] = vx[2]; vy[5] = vy[4] - sr * hb;
+ vx[6] = vx[1]; vy[6] = vy[5];
+ vx[7] = vx[0]; vy[7] = vy[4];
+
+ b = tiles_bevel_dim(tex, vx[0] - vx[4], vy[1] - vy[5]) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 8, b, bs);
+ id = TILE_LEFT_BELOW;
+ }
+ if (intens <= 0) {
+ /* Bottom Right */
+ vx[0] = s5 * w; vy[0] = s3 * h;
+ vx[1] = s4 * w; vy[1] = s2 * h;
+ vx[2] = vx[1]; vy[2] = vy[1] - sh * (h + hb);
+ vx[3] = vx[0]; vy[3] = vy[4] - sr * hb;
+ vx[4] = vx[3] + sh * (w + wr); vy[4] = vy[3];
+ vx[5] = vx[4] + sr * wr; vy[5] = vy[2];
+ vx[6] = vx[5]; vy[6] = vy[1];
+ vx[7] = vx[4]; vy[7] = vy[0];
+
+ b = tiles_bevel_dim(tex, vx[5] - vx[1], vy[0] - vy[4]) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 8, b, bs);
+ id = TILE_RIGHT_BELOW;
+ }
+ if (intens <= 0) {
+ /* Top Left */
+ vx[0] = s2 * w; vy[0] = s4 * h;
+ vx[1] = s3 * w; vy[1] = s5 * h;
+ vx[2] = vx[1]; vy[2] = vy[1] + sh * (h + ha);
+ vx[3] = vx[0]; vy[3] = vy[2] + sr * ha;
+ vx[4] = vx[3] - sh * (w + wl); vy[4] = vy[3];
+ vx[5] = vx[4] - sr * wl; vy[5] = vy[2];
+ vx[6] = vx[5]; vy[6] = vy[1];
+ vx[7] = vx[4]; vy[7] = vy[0];
+
+ b = tiles_bevel_dim(tex, vx[1] - vx[5], vy[4] - vy[0]) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 8, b, bs);
+ id = TILE_LEFT_ABOVE;
+ }
+ if (intens <= 0) {
+ /* Top Right */
+ vx[0] = s4 * w; vy[0] = s5 * h;
+ vx[1] = s5 * w; vy[1] = s4 * h;
+ vx[2] = vx[1] + sh * (w + wr); vy[2] = vy[1];
+ vx[3] = vx[2] + sr * wr; vy[3] = vy[0];
+ vx[4] = vx[3]; vy[4] = vy[3] + sh * (h + ha);
+ vx[5] = vx[2]; vy[5] = vy[4] + sr * ha;
+ vx[6] = vx[1]; vy[6] = vy[5];
+ vx[7] = vx[0]; vy[7] = vy[4];
+
+ b = tiles_bevel_dim(tex, vx[4] - vx[0], vy[5] - vy[1]) * tex->bevel;
+ intens = tiles_poly_func(x, y, vx, vy, 8, b, bs);
+ id = TILE_RIGHT_ABOVE;
+ }
+ }
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, -1, col);
+
+ return intens;
+}
+
+static float tiles_star1_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, float *col)
+{
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float w2 = 0.5 * w;
+ float h2 = 0.5 * h;
+ float dim = tiles_bevel_dim(tex, w, h);
+ float b = dim * tex->bevel;
+ float intens = 0;
+ short id = TILE_CURRENT;
+ short bs = tex->bevelshading;
+ float vx[10], vy[10];
+ int j;
+ float step = 0.2 * M_PI;
+ float theta = 0;
+ float r1, r2;
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ if (htileid % 2) theta += step;
+ for (j = 0; j < 10; j++, theta += step) {
+ r1 = w2;
+ r2 = h2;
+ if (j % 2) {
+ r1 *= 0.5;
+ r2 *= 0.5;
+ }
+
+ vx[j] = w2 + r1 * cos(theta);
+ vy[j] = h2 + r2 * sin(theta);
+ }
+ intens = tiles_concave_poly_func(x, y, vx, vy, 10, b, bs);
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, -1, col);
+
+ return intens;
+}
+
+static float tiles_weave_int(Tex *tex, float x, float y, float z, short htileid, short vtileid, float *col)
+{
+ float w = tex->precalc.hpat[htileid + 1] - tex->precalc.hpat[htileid] - tex->precalc.hgap;
+ float h = tex->precalc.vpat[vtileid + 1] - tex->precalc.vpat[vtileid] - tex->precalc.vgap;
+ float dim, b;
+ float intens = 0;
+ short htidl, htidr, vtida, vtidb;
+ float wr, wl, ha, hb;
+ float xi, yi, wi, hi;
+ short loop = 1;
+ short id = TILE_CURRENT;
+ short bs;
+
+ /* Width of tile to right */
+ htidr = (htileid + 1) % tex->hcount;
+ wr = tex->precalc.hpat[htidr + 1] - tex->precalc.hpat[htidr] - tex->precalc.hgap;
+ /* Width of tile to left */
+ htidl = (htileid - 1 + tex->hcount) % tex->hcount;
+ wl = tex->precalc.hpat[htidl + 1] - tex->precalc.hpat[htidl] - tex->precalc.hgap;
+ /* Height of tile above */
+ vtida = (vtileid + 1) % tex->vcount;
+ ha = tex->precalc.vpat[vtida + 1] - tex->precalc.vpat[vtida] - tex->precalc.vgap;
+ /* Height of tile below */
+ vtidb = (vtileid - 1 + tex->vcount) % tex->vcount;
+ hb = tex->precalc.vpat[vtidb + 1] - tex->precalc.vpat[vtidb] - tex->precalc.vgap;
+
+ /* Offset by half-gap */
+ x -= tex->precalc.hgap * 0.5;
+ y -= tex->precalc.vgap * 0.5;
+
+ while (loop) {
+ if ((x < 0) || (x > w) || (y < 0) || (y > h)) break;
+
+ /* Horizontal Tiles */
+
+ /* Compute dimension for bevel and shading */
+ if (tex->bevelshading == TEX_BEVEL_PATTERN) {
+ bs = (tex->corner == TEX_CORNER_STRAIGHT) ? TEX_BEVEL_VGRADIENT : TEX_BEVEL_HGRADIENT;
+ dim = tiles_bevel_dim(tex, w, MIN2(wl, wr));
+ }
+ else {
+ bs = tex->bevelshading;
+ dim = tiles_bevel_dim(tex, MIN3(w, wl, wr), MIN3(h, ha, hb));
+ }
+ b = dim * tex->bevel;
+ dim *= 0.25;
+
+ /* Bottom Center */
+ xi = 0.125 * w;
+ yi = -0.125 * hb;
+ wi = 0.75 * w;
+ hi = 0.125 * (h + hb);
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_BELOW;
+ break;
+ }
+
+ /* Top Center */
+ xi = 0.125 * w;
+ yi = 0.875 * h;
+ hi = 0.125 * (h + ha);
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_ABOVE;
+ break;
+ }
+
+ /* Middle Left */
+ xi = -0.375 * wl;
+ yi = 0.375 * h;
+ wi = 0.375 * (w + wl);
+ hi = 0.25 * h;
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_LEFT;
+ break;
+ }
+
+ /* Middle Right */
+ xi = 0.625 * w;
+ yi = 0.375 * h;
+ wi = 0.375 * (w + wr);
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_RIGHT;
+ break;
+ }
+
+
+ /* Vertical Tiles */
+
+ /* Compute dimension for bevel and shading */
+ if (tex->bevelshading == TEX_BEVEL_PATTERN) {
+ bs = (tex->corner == TEX_CORNER_STRAIGHT) ? TEX_BEVEL_HGRADIENT : TEX_BEVEL_VGRADIENT;
+ dim = tiles_bevel_dim(tex, h, MIN2(ha, hb));
+ }
+ else {
+ bs = tex->bevelshading;
+ dim = tiles_bevel_dim(tex, MIN3(w, wl, wr), MIN3(h, ha, hb));
+ }
+ b = dim * tex->bevel;
+ dim *= 0.25;
+
+ /* Center */
+ xi = 0.375 * w;
+ yi = 0.125 * h;
+ wi = 0.25 * w;
+ hi = 0.75 * h;
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_CURRENT;
+ break;
+ }
+
+ /* Bottom Left */
+ xi = -0.125 * wl;
+ yi = -0.375 * hb;
+ wi = 0.125 * (w + wl);
+ hi = 0.375 * (h + hb);
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_LEFT_BELOW;
+ break;
+ }
+
+ /* Bottom Right */
+ xi = 0.875 * w;
+ yi = -0.375 * hb;
+ wi = 0.125 * (w + wr);
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_RIGHT_BELOW;
+ break;
+ }
+
+ /* Top Left */
+ xi = -0.125 * wl;
+ yi = 0.625 * h;
+ wi = 0.125 * (w + wl);
+ hi = 0.375 * (h + ha);
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_LEFT_ABOVE;
+ break;
+ }
+
+ /* Top Right */
+ xi = 0.875 * w;
+ yi = 0.625 * h;
+ wi = 0.125 * (w + wr);
+ intens = tiles_recthelper_int(tex, x - xi, y - yi, wi, hi, dim, b, bs);
+ if (intens > 0) {
+ id = TILE_RIGHT_ABOVE;
+ break;
+ }
+
+ loop = 0;
+ }
+
+ /* Bevel function */
+ intens = tiles_bevel_func(tex, intens);
+
+ /* Compute colour */
+ tiles_neighbour_col(tex, &intens, htileid, vtileid, id, -1, col);
+
+ return intens;
+}
+
+static float tiles_turb_seamless(Tex * tex, float x, float y, float z, float w, float h, float d)
+{
+ /* F_tile(x,y,z) = (
+ (w - x) * (h - y) * (d - z) * F(x, y , z ) +
+ (w - x) * (h - y) * ( z) * F(x, y , z - d) +
+ (w - x) * ( y) * (d - z) * F(x, y - h, z ) +
+ (w - x) * ( y) * ( z) * F(x, y - h, z - d) +
+ ( x) * (h - y) * (d - z) * F(x - w, y , z ) +
+ ( x) * (h - y) * ( z) * F(x - w, y , z - d) +
+ ( x) * ( y) * (d - z) * F(x - w, y - h, z ) +
+ ( x) * ( y) * ( z) * F(x - w, y - h, z - d)
+ ) / whd
+
+ The function tiles every w units in x-direction, h units in y-direction and d units in z-direction.
+ */
+ int hard = (tex->noisetype!=TEX_NOISESOFT);
+ float wx = w - x;
+ float hy = h - y;
+ float dz = d - z;
+
+ return
+ (
+ wx * hy * dz * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, hard, tex->noisebasis) +
+ wx * hy * z * BLI_gTurbulence(tex->noisesize, x, y, -dz, tex->noisedepth, hard, tex->noisebasis) +
+ wx * y * dz * BLI_gTurbulence(tex->noisesize, x, -hy, z, tex->noisedepth, hard, tex->noisebasis) +
+ wx * y * z * BLI_gTurbulence(tex->noisesize, x, -hy, -dz, tex->noisedepth, hard, tex->noisebasis) +
+ x * hy * dz * BLI_gTurbulence(tex->noisesize, -wx, y, z, tex->noisedepth, hard, tex->noisebasis) +
+ x * hy * z * BLI_gTurbulence(tex->noisesize, -wx, y, -dz, tex->noisedepth, hard, tex->noisebasis) +
+ x * y * dz * BLI_gTurbulence(tex->noisesize, -wx, -hy, z, tex->noisedepth, hard, tex->noisebasis) +
+ x * y * z * BLI_gTurbulence(tex->noisesize, -wx, -hy, -dz, tex->noisedepth, hard, tex->noisebasis)
+ ) / (w * h * d);
+}
+static void tiles_transform(Tex *tex, float *x, float *y, float *z)
+{
+ float angle, sinval, cosval, scale;
+ float x1, y1;
+
+ /* Move origin to (0.5, 0.5) */
+ *x -= 0.5;
+ *y -= 0.5;
+ *z -= 0.5;
+
+ /* Apply texture coordinate scale */
+ scale = 1.0 / tex->scale;
+ *x *= scale;
+ *y *= scale;
+ *z *= scale;
+
+ /* Move origin back to (0, 0) */
+ *x += 0.5;
+ *y += 0.5;
+ *z += 0.5;
+}
+
+static void tiles_calc(Tex *tex, float *x, float *y, float *z, short *htileid, short *vtileid)
+{
+ /* Given points (x, y, z) determines where in the tile pattern, tex->precalc.hpat[],
+ * the point belongs. It returns the index of the tile in htileid, vtileid and x, y, z
+ * will contain the relative offset for the tile.
+ * NOTE: currently z is ignored as this is a 2D texture.
+ */
+ float wtot = tex->precalc.hpat[tex->hcount] - tex->precalc.hpat[0]; /* Width of tile pattern */
+ float htot = tex->precalc.vpat[tex->vcount] - tex->precalc.vpat[0]; /* Height of tile pattern */
+ float y1;
+ short i;
+ int row;
+
+ /* Center the pattern */
+ *x += (wtot * 0.5);
+ *y += (htot * 0.5);
+
+ y1 = *y;
+
+ /* Compute relative y offset for current tile */
+ *y = mod(*y, htot);
+
+ /* Determine vertical start of the tile */
+ for (i = 0; i < tex->vcount; i++) {
+ if (*y <= tex->precalc.vpat[i + 1]) {
+ break;
+ }
+ }
+ *y -= tex->precalc.vpat[i];
+ *vtileid = i;
+
+ /* Calculate row number */
+ row = (int)floor(y1 / htot) * tex->vcount + i;
+
+ /* Shift rows */
+ if ( tex->alternate > 0 ) {
+ *x += (mod(row, tex->alternate) * tex->shift);
+ }
+ else {
+ /* Shift every row */
+ *x += (row * tex->shift);
+ }
+
+ /* Compute relative x offset for current tile */
+ *x = mod(*x, wtot);
+
+ /* Determine horizontal start of the tile */
+ for (i = 0; i < tex->hcount; i++) {
+ if (*x <= tex->precalc.hpat[i + 1]) {
+ break;
+ }
+ }
+ *x -= tex->precalc.hpat[i];
+ *htileid = i;
+}
+static float tiles_int(Tex *tex, float x, float y, float z, float *col)
+{
+ short htileid, vtileid;
+ float intens;
+
+ /* Compute coordinates in "tile-space"; i.e. relative to the tile containing
+ * the texture coordinates.
+ */
+ tiles_transform(tex, &x, &y, &z);
+ tiles_calc(tex, &x, &y, &z, &htileid, &vtileid);
+
+ /* Handle predefined patterns and default tiling function */
+ switch (tex->pattern) {
+ case TEX_TILES_CROSS1:
+ intens = tiles_cross1_int(tex, x, y, z, htileid, vtileid, col);
+ break;
+ case TEX_TILES_CROSS2:
+ intens = tiles_cross2_int(tex, x, y, z, htileid, vtileid, col);
+ break;
+ case TEX_TILES_HERRINGBONE1:
+ intens = tiles_herringbone_int(tex, x, y, z, htileid, vtileid, 2, col);
+ break;
+ case TEX_TILES_HERRINGBONE2:
+ intens = tiles_herringbone_int(tex, x, y, z, htileid, vtileid, 4, col);
+ break;
+ case TEX_TILES_HERRINGBONE3:
+ intens = tiles_herringbone_int(tex, x, y, z, htileid, vtileid, 5, col);
+ break;
+ case TEX_TILES_HEX:
+ intens = tiles_hex_int(tex, x, y, z, htileid, vtileid, col);
+ break;
+ case TEX_TILES_INTERLOCK1:
+ intens = tiles_interlock1_int(tex, x, y, z, htileid, vtileid, col);
+ break;
+ case TEX_TILES_INTERLOCK2:
+ intens = tiles_interlock2_int(tex, x, y, z, htileid, vtileid, 2, col);
+ break;
+ case TEX_TILES_INTERLOCK3:
+ intens = tiles_interlock2_int(tex, x, y, z, htileid, vtileid, 4, col);
+ break;
+ case TEX_TILES_INTERLOCK4:
+ intens = tiles_interlock3_int(tex, x, y, z, htileid, vtileid, col);
+ break;
+ case TEX_TILES_STAR1:
+ intens = tiles_star1_int(tex, x, y, z, htileid, vtileid, col);
+ break;
+ case TEX_TILES_WEAVE:
+ intens = tiles_weave_int(tex, x, y, z, htileid, vtileid, col);
+ break;
+ default:
+ intens = tiles_default_int(tex, x, y, z, htileid, vtileid, col);
+ break;
+ }
+
+ /* Clamp to [0, 1] range. The clamping prevents artifacts around the border
+ * in case negative numbers are generated by the tile functions.
+ */
+ CLAMP(intens, 0, 1);
+ CLAMP(col[0], 0, 1);
+ CLAMP(col[1], 0, 1);
+ CLAMP(col[2], 0, 1);
+
+ return intens;
+}
+
+static int tiles(Tex *tex, float *texvec, TexResult *texres)
+{
+ int rv = TEX_INT;
+ float col[3];
+
+ texres->tin = tiles_int(tex, texvec[0], texvec[1], texvec[2], col);
+
+ texres->tr = col[0];
+ texres->tg = col[1];
+ texres->tb = col[2];
+ texres->ta = 1.0;
+ rv |= TEX_RGB;
+
+ if (texres->nor!=NULL) {
+ /* calculate bumpnormal */
+ texres->nor[0] = tiles_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2], col);
+ texres->nor[1] = tiles_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2], col);
+ texres->nor[2] = tiles_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla, col);
+
+ tex_normal_derivate(tex, texres);
+ rv |= TEX_NOR;
+ }
+
+ BRICONTRGB;
+
+ BRICONT;
+
+ return rv;
+}
+
+/* ------------------------------------------------------------------------- */
+
static int texnoise(Tex *tex, TexResult *texres)
{
float div=3.0;
@@ -1194,6 +3341,9 @@
retval= mg_distNoiseTex(tex, tmpvec, texres);
break;
+ case TEX_TILES:
+ retval = tiles(tex, texvec, texres);
+ break;
}
if (tex->flag & TEX_COLORBAND) {
@@ -1221,7 +3371,7 @@
}
/* Image requires 2d mapping conversion */
- if(tex->type==TEX_IMAGE) {
+ if(tex->type==TEX_IMAGE || tex->type==TEX_TILES) {
MTex mtex;
float texvec_l[3], dxt_l[3], dyt_l[3];
@@ -1560,7 +3710,7 @@
co= tempvec;
}
- if(tex->type==TEX_IMAGE) {
+ if(tex->type==TEX_IMAGE || tex->type==TEX_TILES) {
/* new: first swap coords, then map, then trans/scale */
@@ -2028,7 +4178,7 @@
}
- if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
+ if(mtex->tex->type==TEX_IMAGE || mtex->tex->type==TEX_TILES) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres);
@@ -2199,7 +4349,7 @@
else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
/* texture */
- if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
+ if(mtex->tex->type==TEX_IMAGE || mtex->tex->type==TEX_TILES) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres);
@@ -2378,7 +4528,7 @@
}
/* texture */
- if(tex->type==TEX_IMAGE) {
+ if(tex->type==TEX_IMAGE || tex->type==TEX_TILES) {
do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
}
@@ -2463,7 +4613,7 @@
else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
/* texture */
- if(tex->type==TEX_IMAGE) {
+ if(tex->type==TEX_IMAGE || tex->type==TEX_TILES) {
do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
}
Index: source/blender/src/butspace.c
===================================================================
--- source/blender/src/butspace.c (revision 13811)
+++ source/blender/src/butspace.c (working copy)
@@ -95,7 +95,7 @@
char texstr[20][12]= {"None" , "Clouds" , "Wood", "Marble", "Magic" , "Blend",
"Stucci", "Noise" , "Image", "Plugin", "EnvMap" , "Musgrave",
- "Voronoi", "DistNoise", "", "", "", "", "", ""};
+ "Voronoi", "DistNoise", "Tiles", "", "", "", "", ""};
/* ---------------------------------------------------------------------- */
void test_idbutton_cb(void *namev, void *arg2)
Index: source/blender/src/buttons_shading.c
===================================================================
--- source/blender/src/buttons_shading.c (revision 13811)
+++ source/blender/src/buttons_shading.c (working copy)
@@ -728,7 +728,182 @@
uiDefButF(block, NUMSLI, B_TEXPRV, "W4: ", 10, 10, 150, 19, &tex->vn_w4, -2.0, 2.0, 10, 0, "Sets feature weight 4");
}
+static void texture_tiles_precalc(void *tex, void *unused)
+{
+ tiles_precalc((Tex *)tex);
+}
+static void texture_tiles_pattern(void *tex, void *unused)
+{
+ Tex *t = (Tex *)tex;
+ /* Setup parameters for preset patterns. */
+ switch (t->pattern)
+ {
+ case TEX_TILES_HEX:
+ case TEX_TILES_HERRINGBONE1:
+ case TEX_TILES_HERRINGBONE2:
+ case TEX_TILES_HERRINGBONE3:
+ case TEX_TILES_INTERLOCK4:
+ t->hgap = 0;
+ t->vgap = 0;
+ t->alternate = 1;
+ t->bevelshading = TEX_BEVEL_DEFAULT;
+ break;
+ case TEX_TILES_WEAVE:
+ t->hgap = 0;
+ t->vgap = 0;
+ t->alternate = 1;
+ t->bevelshading = TEX_BEVEL_PATTERN;
+ break;
+ case TEX_TILES_INTERLOCK1:
+ case TEX_TILES_INTERLOCK2:
+ case TEX_TILES_INTERLOCK3:
+ case TEX_TILES_CROSS1:
+ case TEX_TILES_CROSS2:
+ case TEX_TILES_STAR1:
+ t->bevelshading = TEX_BEVEL_DEFAULT;
+ break;
+ }
+
+ texture_tiles_precalc(tex, unused);
+}
+static char* tiles_corner_menu()
+{
+ static char nbmenu[256];
+ sprintf(nbmenu, "Corner Style %%t|Round Inverted %%x%d|Round %%x%d|Ellipse Inverted %%x%d|Ellipse %%x%d|Straight %%x%d", TEX_CORNER_ROUND_INV, TEX_CORNER_ROUND, TEX_CORNER_ELLIPSE_INV, TEX_CORNER_ELLIPSE, TEX_CORNER_STRAIGHT);
+ return nbmenu;
+}
+static char* tiles_pattern_menu()
+{
+ static char nbmenu[256];
+ sprintf(nbmenu, "Pattern %%t|No Pattern %%x%d|Weave %%x%d|Star 1 %%x%d|Interlock 4 %%x%d|Interlock 3 %%x%d|Interlock 2 %%x%d|Interlock 1 %%x%d|Honeycomb %%x%d|Herringbone 3 %%x%d|Herringbone 2 %%x%d|Herringbone 1 %%x%d|Cross 2 %%x%d|Cross 1 %%x%d", TEX_TILES_NONE, TEX_TILES_WEAVE, TEX_TILES_STAR1, TEX_TILES_INTERLOCK4, TEX_TILES_INTERLOCK3, TEX_TILES_INTERLOCK2, TEX_TILES_INTERLOCK1, TEX_TILES_HEX, TEX_TILES_HERRINGBONE3, TEX_TILES_HERRINGBONE2, TEX_TILES_HERRINGBONE1, TEX_TILES_CROSS2, TEX_TILES_CROSS1);
+ return nbmenu;
+}
+static char* tiles_bevopt_menu()
+{
+ static char nbmenu[256];
+ sprintf(nbmenu, "Bevel Option %%t|Non-uniform %%x%d|Uniform Min %%x%d|Uniform Max %%x%d", TEX_BEVEL_DEFAULTMIN, TEX_BEVEL_UNIFORMMIN, TEX_BEVEL_UNIFORMMAX);
+ return nbmenu;
+}
+static char* tiles_bevel_menu()
+{
+ static char nbmenu[256];
+ sprintf(nbmenu, "Bevel Shading %%t|Default Shading %%x%d|H Gradient %%x%d|V Gradient %%x%d|Pattern %%x%d", TEX_BEVEL_DEFAULT, TEX_BEVEL_HGRADIENT, TEX_BEVEL_VGRADIENT, TEX_BEVEL_PATTERN);
+ return nbmenu;
+}
+static void texture_panel_tiles(Tex *tex)
+{
+ uiBut *bt;
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "texture_panel_tiles", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Tiles Basic", "Texture", 640, 0, 318, 204)==0) return;
+
+ uiSetButLock(tex->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButS(block, MENU, B_TEXPRV, tiles_pattern_menu(), 10, 180, 130, 19, &tex->pattern, 0, 0, 0, 0, "Predefined pattern");
+ uiButSetFunc(bt, texture_tiles_pattern, tex, NULL);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Scale:", 140, 180, 130, 19, &tex->scale, 0.0001, 10, 10, 0, "Scaling");
+ bt = uiDefButS(block, TOG, B_TEXPRV, "Seamless", 270, 180, 120, 19, &tex->seamless, 0, 1, 0, 0, "Make texture seamless");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButS(block, NUMSLI, B_TEXPRV, "Rows:", 50, 156, 150, 19, &tex->hcount, 1, 15, 10, 0, "Number of horizontal random tiles");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButS(block, NUMSLI, B_TEXPRV, "Cols:", 200, 156, 150, 19, &tex->vcount, 1, 15, 10, 0, "Number of vertical random tiles");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Width:", 50, 132, 150, 19, &tex->width, 0.01, 10, 10, 0, "Average tile width");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Variation:", 200, 132, 150, 19, &tex->widthvar, 0, 1, 10, 0, "Variation in tile width");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Height:", 50, 108, 150, 19, &tex->height, 0.01, 10, 10, 0, "Average tile height");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Variation:", 200, 108, 150, 19, &tex->heightvar, 0, 1, 10, 0, "Variation in tile height");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Bump:", 50, 84, 150, 19, &tex->bump, 0, 1, 10, 0, "Average bump height");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Variation:", 200, 84, 150, 19, &tex->bumpvar, 0, 1, 10, 0, "Variation in bump height");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "H Gap:", 50, 60, 150, 19, &tex->hgap, 0, 10, 10, 0, "Horizontal gap");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "V Gap:", 200, 60, 150, 19, &tex->vgap, 0, 10, 10, 0, "Vertical gap");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Shift:", 50, 36, 150, 19, &tex->shift, -10, 10, 10, 0, "Tile shift amount");
+ bt = uiDefButI(block, NUM, B_TEXPRV, "Alternate:", 200, 36, 150, 19, &tex->alternate, 0, 0x8000, 0, 0, "Number of tiles after which shifting starts again");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButI(block, NUM, B_TEXPRV, "Seed:", 50, 12, 150, 19, &tex->seed, 0, 0x80000000, 10, 0, "Seed for random number generator");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButF(block, NUM, B_NOP, "Nabla:", 200, 12, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal");
+ uiBlockEndAlign(block);
+}
+static void texture_panel_tiles_advanced(Tex *tex)
+{
+ uiBut *bt;
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "texture_panel_tiles_advanced", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Tiles Basic", "Texture");
+ if(uiNewPanel(curarea, block, "Tiles Advanced", "Texture", 1280, 0, 318, 204)==0) return;
+
+ uiSetButLock(tex->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Bevel:", 50, 180, 150, 19, &tex->bevel, 0, 0.5, 10, 0, "Tile bevel factor");
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Profile:",200, 180, 150, 19, &tex->curve, -1, 1, 10, 0, "Adjust the bevel profile");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "Strength:", 50, 156, 150, 19, &tex->strength, 0, 1, 10, 0, "Strength of bevel");
+ bt = uiDefButS(block, TOG, B_TEXPRV, "Smooth", 200, 156, 150, 19, &tex->smooth, 0, 1, 0, 0, "Smooth the bevel profile");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButS(block, MENU, B_TEXPRV, tiles_bevopt_menu(), 50, 132, 150, 19, &tex->bevoption, 0, 0, 0, 0, "Controls uniformity of bevel across tiles");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButS(block, MENU, B_TEXPRV, tiles_bevel_menu(), 200, 132, 150, 19, &tex->bevelshading, 0, 0, 0, 0, "Bevel shading options");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "H Corner:", 50, 108, 150, 19, &tex->hcorner, 0, 0.5, 10, 0, "Tile corner horizontal factor");
+ bt = uiDefButF(block, NUM, B_TEXPRV, "V Corner:", 200, 108, 150, 19, &tex->vcorner, 0, 0.5, 10, 0, "Tile corner vertical factor");
+ bt = uiDefButS(block, MENU, B_TEXPRV, tiles_corner_menu(), 200, 84, 150, 19, &tex->corner, 0, 0, 0, 0, "Tile corner type");
+ uiBlockEndAlign(block);
+
+ bt = uiDefBut(block, LABEL, 0, "Base Color", 50, 60, 100, 19, 0, 0.0, 0.0, 0, 0, "");
+ bt = uiDefButF(block, COL, B_TEXPRV, "", 150, 60, 19, 19, &tex->colr1, 0, 0, 0, 0, "Base color for brick");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+
+ bt = uiDefBut(block, LABEL, 0, "Gap Color", 50, 36, 100, 19, 0, 0.0, 0.0, 0, 0, "");
+ bt = uiDefButF(block, COL, B_TEXPRV, "", 150, 36, 19, 19, &tex->colr2, 0, 0, 0, 0, "Gap color");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+
+ bt = uiDefButF(block, NUM, B_TEXPRV, "H Variation:", 200, 60, 150, 19, &tex->fhue, 0, 1, 10, 0, "Hue variation");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "S Variation:", 200, 36, 150, 19, &tex->fsat, 0, 1, 10, 0, "Saturation variation");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+ bt = uiDefButF(block, NUM, B_TEXPRV, "V Variation:", 200, 12, 150, 19, &tex->fval, 0, 1, 10, 0, "Value variation");
+ uiButSetFunc(bt, texture_tiles_precalc, tex, NULL);
+}
+
static char *layer_menu(RenderResult *rr, short *curlay)
{
RenderLayer *rl;
@@ -1541,7 +1716,22 @@
uiDefButF(block, NUMSLI, B_TEXPRV, "Contr", 160,10,150,20, &tex->contrast, 0.01, 5.0, 0, 0, "Changes the contrast of the color or intensity of a texture");
}
-
+static void texture_type_select(void *tex, void *unused)
+{
+ Tex *t = (Tex *)tex;
+ if (t->type == TEX_TILES) {
+ /* We have to do this because do_2d_mapping() will mess up the texture mapping
+ * for Tiles texture
+ */
+ t->extend = TEX_REPEAT;
+ t->cropxmin = 0.0;
+ t->cropxmax = 1.0;
+ t->cropymin = 0.0;
+ t->cropymax = 1.0;
+ t->xrepeat = 1.0;
+ t->yrepeat = 1.0;
+ }
+}
static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *la, bNode *node, Brush *br, SculptData *sd)
{
MTex *mt=NULL;
@@ -1635,16 +1825,17 @@
if(id) {
char textypes[512];
Tex *tex= (Tex *)id;
+ uiBut *bt;
uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
/* newnoise: all texture types as menu, not enough room for more buttons.
* Can widen panel, but looks ugly when other panels overlap it */
- sprintf(textypes, "Texture Type %%t|None %%x%d|Image %%x%d|EnvMap %%x%d|Clouds %%x%d|Marble %%x%d|Stucci %%x%d|Wood %%x%d|Magic %%x%d|Blend %%x%d|Noise %%x%d|Plugin %%x%d|Musgrave %%x%d|Voronoi %%x%d|DistortedNoise %%x%d", 0, TEX_IMAGE, TEX_ENVMAP, TEX_CLOUDS, TEX_MARBLE, TEX_STUCCI, TEX_WOOD, TEX_MAGIC, TEX_BLEND, TEX_NOISE, TEX_PLUGIN, TEX_MUSGRAVE, TEX_VORONOI, TEX_DISTNOISE);
+ sprintf(textypes, "Texture Type %%t|None %%x%d|Image %%x%d|EnvMap %%x%d|Clouds %%x%d|Marble %%x%d|Stucci %%x%d|Wood %%x%d|Magic %%x%d|Blend %%x%d|Noise %%x%d|Plugin %%x%d|Musgrave %%x%d|Voronoi %%x%d|DistortedNoise %%x%d|Tiles %%x%d", 0, TEX_IMAGE, TEX_ENVMAP, TEX_CLOUDS, TEX_MARBLE, TEX_STUCCI, TEX_WOOD, TEX_MAGIC, TEX_BLEND, TEX_NOISE, TEX_PLUGIN, TEX_MUSGRAVE, TEX_VORONOI, TEX_DISTNOISE, TEX_TILES);
uiDefBut(block, LABEL, 0, "Texture Type", 160, 150, 140, 20, 0, 0.0, 0.0, 0, 0, "");
- uiDefButS(block, MENU, B_TEXTYPE, textypes, 160, 125, 140, 25, &tex->type, 0,0,0,0, "Select texture type");
-
+ bt = uiDefButS(block, MENU, B_TEXTYPE, textypes, 160, 125, 140, 25, &tex->type, 0,0,0,0, "Select texture type");
+ uiButSetFunc(bt, texture_type_select, tex, NULL);
}
else {
// label to avoid centering
@@ -4386,6 +4577,10 @@
case TEX_VORONOI:
texture_panel_voronoi(tex);
break;
+ case TEX_TILES:
+ texture_panel_tiles(tex);
+ texture_panel_tiles_advanced(tex);
+ break;
}
}
}