Index: source/blender/render/intern/source/texture.c =================================================================== --- source/blender/render/intern/source/texture.c (revision 10896) +++ source/blender/render/intern/source/texture.c (working copy) @@ -73,9 +73,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) @@ -690,9 +689,574 @@ } +/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +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; +} + +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); +} + +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 w = fabs(t->maxwidth - t->minwidth); + float rw; + short i; + RNG *rng = rng_new(tex->seed); + + t->precalc.pat[0] = 0; + for (i = 1; i < t->count + 1; i++) { + rw = (float)rng_getFloat(rng); + rw = t->minwidth + w * rw; + t->precalc.pat[i] = t->hgap + t->precalc.pat[i - 1] + rw; + } + + rng_free(rng); +} + +static void tiles_calc(Tex *tex, float *x, float *y, float *z, short *tileid) +{ + /* Given points (x, y, z) determines where in the tile pattern, tex->precalc.pat[], + * the point belongs. It returns the index of the tile in tileid and x, y, z + * will contain the relative offset for the tile. + * NOTE: currently z is ignored as this is a 2D texture. + */ + short len = tex->count + 1; + float wtot = tex->precalc.pat[len - 1] - tex->precalc.pat[0]; /* Width of tile pattern */ + float htot = tex->vgap + tex->height; + short i; + int q; + + /* Center the pattern */ + *x += ((wtot - tex->hgap) * 0.5); + *y += (tex->height * 0.5); + + /* Shift rows */ + q = (int)floor(*y / htot); + if ( tex->alternate > 0 ) { + *x += ((q % tex->alternate) * tex->shift); + } + else { + /* Shift every row */ + *x += (q * tex->shift); + } + + /* Compute relative offset for current tile */ + *x = mod(*x, wtot); + *y = mod(*y, htot); + + /* Determine start of the tile */ + for (i = 0; i < len; i++) { + if (*x <= tex->precalc.pat[i + 1]) { + break; + } + } + + *x -= tex->precalc.pat[i]; + *tileid = i; +} + +/* 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 + +static float tiles_rect_func(float x, float y, float w, float h, float b) +{ + /* 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. + */ + float dx1 = x; + float dy1 = y; + float dx2 = w - x; + float dy2 = h - y; + + /* Find minimum distance to point from the 4 sides */ + float dmin = MIN4(dx1, dx2, dy1, dy2); + + float v = 0; + 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) +{ + /* 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. + */ + float v = tiles_rect_func(x, y, w, h, b); + float hw = w * 0.5; + float hh = h * 0.5; + 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); + + LINE_BEVEL(d1, b); + LINE_BEVEL(d2, b); + LINE_BEVEL(d3, b); + LINE_BEVEL(d4, b); + + float d = MIN4(d1, d2, d3, d4); + + return MIN2(v, 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) +{ + /* First compute the intensity inside the rectangle bounded by (0, 0) and (w, h). */ + float v = tiles_rect_func(x, y, w, h, b); + float t = v; + float hw = w * 0.5; + float hh = h * 0.5; + + if (flip) { + /* 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); + } + } + v = MIN2(t, v); + } + else { + /* 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)) { + v = tiles_circle_func1(x, y, r, r, b, r); + } + else if ((y >= h - r) && (y <= h)) { + v = tiles_circle_func1(x, y, r, h - r, b, r); + } + } + else if ((x >= w - r) && (x <= w)) { + if ((y >= 0) && (y <= r)) { + v = tiles_circle_func1(x, y, w - r, r, b, r); + } + else if ((y >= h - r) && (y <= h)) { + v = tiles_circle_func1(x, y, w - r, h - r, b, r); + } + } + } + + return 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) +{ + /* First compute the intensity inside the rectangle bounded by (0, 0) and (w, h). */ + float v = tiles_rect_func(x, y, w, h, b); + float t = v; + float hw = w * 0.5; + float hh = h * 0.5; + + if (flip) { + /* 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); + } + } + v = MIN2(t, v); + } + else { + /* 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); + v = MIN2(v, t); + } + else if ((y >= h - ry) && (y <= h)) { + t = tiles_ellipse_func1(x, y, rx, h - ry, b, rx, ry); + v = MIN2(v, t); + } + } + else if ((x >= w - rx) && (x <= w)) { + if ((y >= 0) && (y <= ry)) { + t = tiles_ellipse_func1(x, y, w - rx, ry, b, rx, ry); + v = MIN2(v, t); + } + else if ((y >= h - ry) && (y <= h)) { + t = tiles_ellipse_func1(x, y, w - rx, h - ry, b, rx, ry); + v = MIN2(v, t); + } + } + } + + return v; +} + +static float tiles_int(Tex *tex, float x, float y, float z) +{ + short tileid; + float w, h, b, rx, ry, s; + float intens, icubic1, icubic2, i; + float angle, sinval, cosval, x1, y1, scale; + + /* Apply texture coordinates rotation. */ + angle = tex->rotate * M_PI_OVER_180; + sinval = sin(angle); + cosval = cos(angle); + x1 = x * cosval - y * sinval; + y1 = y * cosval + x * sinval; + + /* Apply texture coordinates skew */ + x = x1 + y1 * tex->vskew; + y = y1 + x1 * tex->hskew; + + /* Apply texture coordinate scale */ + scale = 1.0 / tex->scale; + x *= scale; + y *= scale; + z *= scale; + + /* Compute coordinates in "tile-space"; i.e. relative to the tile containing + * the texture coordinates. + */ + tiles_calc(tex, &x, &y, &z, &tileid); + + /* Compute tile dimensions */ + w = tex->precalc.pat[tileid + 1] - tex->precalc.pat[tileid] - tex->hgap; + h = tex->height; + s = MIN2(w, h); + + /* Bevel and roundness are indicate a percentage factor of minimum + * tile dimension. + */ + b = tex->bevel * s; + + /* Compute intensity. */ + switch (tex->corner) { + case TEX_CORNER_ROUND1: + if (tex->hcorner == tex->vcorner) { + rx = tex->hcorner * s; + intens = tiles_roundrect_func(x, y, w, h, b, rx, 0); + } + else { + rx = tex->hcorner * s; + ry = tex->vcorner * s; + intens = tiles_ellipserect_func(x, y, w, h, b, rx, ry, 0); + } + break; + case TEX_CORNER_ROUND2: + if (tex->hcorner == tex->vcorner) { + rx = tex->hcorner * s; + intens = tiles_roundrect_func(x, y, w, h, b, rx, 1); + } + else { + rx = tex->hcorner * s; + ry = tex->vcorner * s; + intens = tiles_ellipserect_func(x, y, w, h, b, rx, ry, 1); + } + break; + case TEX_CORNER_ELLIPSE1: + rx = tex->hcorner * w; + ry = tex->vcorner * h; + intens = tiles_ellipserect_func(x, y, w, h, b, rx, ry, 0); + break; + case TEX_CORNER_ELLIPSE2: + rx = tex->hcorner * w; + ry = tex->vcorner * h; + intens = tiles_ellipserect_func(x, y, w, h, b, rx, ry, 1); + break; + case TEX_CORNER_STRAIGHT: + rx = tex->hcorner * w; + ry = tex->vcorner * h; + intens = tiles_rect_func2(x, y, w, h, b, rx, ry); + break; + default: + intens = tiles_rect_func(x, y, w, h, b); + 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); + + /* 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; + } + + /* Apply wave function */ + intens += tex->amp * sin(M_2_PI * intens * tex->freq); + + /* Smooth out the result using a cubic step function */ + if (tex->smooth) { + intens = smoothstep(intens, 0, 1); + } + + return intens; +} + +static int tiles(Tex *tex, float *texvec, TexResult *texres) +{ + int rv = TEX_INT; + + texres->tin = tiles_int(tex, texvec[0], texvec[1], texvec[2]); + + if (texres->nor!=NULL) { + /* calculate bumpnormal */ + texres->nor[0] = tiles_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]); + texres->nor[1] = tiles_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]); + texres->nor[2] = tiles_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla); + + tex_normal_derivate(tex, texres); + rv |= TEX_NOR; + } + + BRICONT; + + return rv; +} + +/* ------------------------------------------------------------------------- */ + static int texnoise(Tex *tex, TexResult *texres) { float div=3.0; @@ -1186,6 +1750,9 @@ retval= mg_distNoiseTex(tex, tmpvec, texres); break; + case TEX_TILES: + retval = tiles(tex, texvec, texres); + break; } if (tex->flag & TEX_COLORBAND) { Index: source/blender/render/intern/include/texture.h =================================================================== --- source/blender/render/intern/include/texture.h (revision 10896) +++ 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; Index: source/blender/blenkernel/BKE_blender.h =================================================================== --- source/blender/blenkernel/BKE_blender.h (revision 10896) +++ source/blender/blenkernel/BKE_blender.h (working copy) @@ -44,7 +44,7 @@ struct MemFile; #define BLENDER_VERSION 244 -#define BLENDER_SUBVERSION 2 +#define BLENDER_SUBVERSION 3 #define BLENDER_MINVERSION 240 #define BLENDER_MINSUBVERSION 0 Index: source/blender/blenkernel/intern/texture.c =================================================================== --- source/blender/blenkernel/intern/texture.c (revision 10896) +++ source/blender/blenkernel/intern/texture.c (working copy) @@ -440,6 +440,29 @@ tex->vn_mexp = 2.5; tex->vn_distm = 0; tex->vn_coltype = 0; + /* tiles */ + tex->scale = 1; + tex->count = 3; + tex->minwidth = 0.2; + tex->maxwidth = 0.3; + tex->height = 0.2; + tex->hgap = 0.05; + tex->vgap = 0.05; + tex->shift = 0.1; + tex->bevel = 0.2; + tex->corner = 0; + tex->hcorner = 0.25; + tex->vcorner = 0.25; + tex->rotate = 0; + tex->seed = 0; + tex->alternate = 2; + tex->hskew = 0; + tex->vskew = 0; + tex->curve = 0; + tex->smooth = 0; + tex->freq = 0; + tex->amp = 0; + tiles_precalc(tex); if (tex->env) { tex->env->stype=ENV_STATIC; Index: source/blender/makesdna/DNA_texture_types.h =================================================================== --- source/blender/makesdna/DNA_texture_types.h (revision 10896) +++ source/blender/makesdna/DNA_texture_types.h (working copy) @@ -127,6 +127,12 @@ short recalc, lastsize; } EnvMap; +/* --------------------------------------- Tiles Specific ---------------------------------------------- */ +typedef struct TexPreCalc { + float pat[16]; /* Stores tile pattern */ +} TexPreCalc; +/* --------------------------------------- Tiles Specific ---------------------------------------------- */ + typedef struct Tex { ID id; @@ -151,7 +157,18 @@ short imaflag, flag; short type, stype; - + + short count, smooth; + short corner, pad2; + float scale; + float minwidth, maxwidth, height; + float curve, freq, amp; + float hgap, vgap, shift, bevel; + float rotate, hskew, vskew; + float hcorner, vcorner; + unsigned int seed, alternate; + struct TexPreCalc precalc; + float cropxmin, cropymin, cropxmax, cropymax; short xrepeat, yrepeat; short extend; @@ -171,10 +188,10 @@ struct PluginTex *plugin; struct ColorBand *coba; struct EnvMap *env; - - } Tex; +void tiles_precalc(Tex *tex); + /* used for mapping node. note: rot is in degrees */ typedef struct TexMapping { @@ -208,6 +225,7 @@ #define TEX_MUSGRAVE 11 #define TEX_VORONOI 12 #define TEX_DISTNOISE 13 +#define TEX_TILES 14 /* musgrave stype */ #define TEX_MFRACTAL 0 @@ -301,6 +319,13 @@ #define TEX_HALO 5 #define TEX_RAD 6 +/* tex->stype in texture.c - corner types */ +#define TEX_CORNER_ROUND1 0 +#define TEX_CORNER_ROUND2 1 +#define TEX_CORNER_ELLIPSE1 2 +#define TEX_CORNER_ELLIPSE2 3 +#define TEX_CORNER_STRAIGHT 4 + /* wrap */ #define MTEX_FLAT 0 #define MTEX_CUBE 1 Index: source/blender/src/buttons_shading.c =================================================================== --- source/blender/src/buttons_shading.c (revision 10896) +++ source/blender/src/buttons_shading.c (working copy) @@ -717,7 +717,72 @@ 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 char* tiles_corner_menu() +{ + static char nbmenu[256]; + sprintf(nbmenu, "Corner Style %%t|Round 1 %%x%d|Round 2 %%x%d|Ellipse 1 %%x%d|Ellipse 2 %%x%d|Straight %%x%d", TEX_CORNER_ROUND1, TEX_CORNER_ROUND2, TEX_CORNER_ELLIPSE1, TEX_CORNER_ELLIPSE2, TEX_CORNER_STRAIGHT); + 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", "Texture", 640, 0, 318, 204)==0) return; + + uiSetButLock(tex->id.lib!=NULL, ERROR_LIBDATA_MESSAGE); + + bt = uiDefButF(block, NUM, B_TEXPRV, "Scale:", 10, 180, 100, 19, &tex->scale, 0.0001, 10, 10, 0, "Sets scaling"); + bt = uiDefButF(block, NUM, B_TEXPRV, "Min W:", 10, 156, 100, 19, &tex->minwidth, 0.01, 10, 10, 0, "Minimum tile width"); + uiButSetFunc(bt, texture_tiles_precalc, tex, NULL); + bt = uiDefButF(block, NUM, B_TEXPRV, "Bevel:", 10, 132, 100, 19, &tex->bevel, 0, 0.5, 10, 0, "Tile bevel factor"); + bt = uiDefButF(block, NUM, B_TEXPRV, "H Gap:", 10, 108, 100, 19, &tex->hgap, 0, 10, 10, 0, "Horizontal gap"); + uiButSetFunc(bt, texture_tiles_precalc, tex, NULL); + bt = uiDefButF(block, NUM, B_TEXPRV, "Shift:", 10, 84, 100, 19, &tex->shift, -10, 10, 10, 0, "Tile shift"); + bt = uiDefButF(block, NUM, B_TEXPRV, "H Shape:", 10, 60, 100, 19, &tex->hcorner, 0, 0.5, 10, 0, "Tile corner horizontal factor"); + bt = uiDefButF(block, NUM, B_TEXPRV, "Freq:", 10, 36, 100, 19, &tex->freq, 0, 100, 10, 0, "Frequency of wave function for bevel"); + + bt = uiDefButS(block, NUMSLI, B_TEXPRV, "Count:", 120, 180, 100, 19, &tex->count, 1, 15, 10, 0, "Number of random tiles"); + uiButSetFunc(bt, texture_tiles_precalc, tex, NULL); + bt = uiDefButF(block, NUM, B_TEXPRV, "Max W:", 120, 156, 100, 19, &tex->maxwidth, 0.01, 10, 10, 0, "Maximum tile width"); + uiButSetFunc(bt, texture_tiles_precalc, tex, NULL); + bt = uiDefButF(block, NUM, B_TEXPRV, "Curve:", 120, 132, 100, 19, &tex->curve, -1, 1, 10, 0, "Adjust the bevel profile"); + bt = uiDefButF(block, NUM, B_TEXPRV, "V Gap:", 120, 108, 100, 19, &tex->vgap, 0, 10, 10, 0, "Vertical gap"); + bt = uiDefButI(block, NUM, B_TEXPRV, "Alternate:", 120, 84, 100, 19, &tex->alternate, 0, 0x8000, 0, 0, "Number of tiles after which shifting starts again"); + bt = uiDefButF(block, NUM, B_TEXPRV, "V Shape:", 120, 60, 100, 19, &tex->vcorner, 0, 0.5, 10, 0, "Tile corner vertical factor"); + bt = uiDefButF(block, NUM, B_TEXPRV, "Amp:", 120, 36, 100, 19, &tex->amp, 0, 100, 10, 0, "Amplitude of wave function for bevel"); + + bt = uiDefButI(block, NUM, B_TEXPRV, "Seed:", 230, 180, 100, 19, &tex->seed, 0,0x80000000,10, 0, "Seed for random number generator"); + uiButSetFunc(bt, texture_tiles_precalc, tex, NULL); + bt = uiDefButF(block, NUM, B_TEXPRV, "Height:", 230, 156, 100, 19, &tex->height, 0.01, 10, 10, 0, "Tile height"); + bt = uiDefButS(block, TOG, B_TEXPRV, "Smooth", 230, 132, 100, 19, &tex->smooth, 0, 1, 0, 0, "Smooth the bevel profile"); + bt = uiDefButS(block, MENU, B_TEXPRV, tiles_corner_menu(),230, 60, 150, 19, &tex->corner, 0, 0, 0, 0, "Tile corner type"); + + bt = uiDefButF(block, NUM, B_NOP, "Nabla:", 160, 10, 150, 19, &tex->nabla, 0.001, 0.1, 1, 0, "Defines size of derivative offset used for calculating normal"); +} +static void texture_panel_tiles_transform(Tex *tex) +{ + uiBut *bt; + uiBlock *block; + + block= uiNewBlock(&curarea->uiblocks, "texture_panel_tiles_transform", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Tiles", "Texture"); + if(uiNewPanel(curarea, block, "Tile Transform", "Texture", 640, 0, 318, 204)==0) return; + + uiSetButLock(tex->id.lib!=NULL, ERROR_LIBDATA_MESSAGE); + + bt = uiDefButF(block, NUM, B_TEXPRV, "Rotate:", 10, 180, 100, 19, &tex->rotate, 0, 360, 100, 0, "Texture rotation in degrees"); + bt = uiDefButF(block, NUM, B_TEXPRV, "H Skew:", 10, 156, 100, 19, &tex->hskew, -100, 100, 10, 0, "Horizontal skew"); + bt = uiDefButF(block, NUM, B_TEXPRV, "V Skew:", 10, 132, 100, 19, &tex->vskew, -100, 100, 10, 0, "Vertical skew"); +} + static char *layer_menu(RenderResult *rr, short *curlay) { RenderLayer *rl; @@ -1617,7 +1682,7 @@ /* 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"); @@ -4043,6 +4108,10 @@ case TEX_VORONOI: texture_panel_voronoi(tex); break; + case TEX_TILES: + texture_panel_tiles(tex); + texture_panel_tiles_transform(tex); + break; } } } Index: source/blender/blenloader/intern/readfile.c =================================================================== --- source/blender/blenloader/intern/readfile.c (revision 10896) +++ source/blender/blenloader/intern/readfile.c (working copy) @@ -6490,6 +6490,35 @@ } } } + + if(main->versionfile != 244 || main->subversionfile < 3) { + /* Initialize Tiles texture */ + Tex *tex; + for(tex= main->tex.first; tex; tex= tex->id.next) { + tex->scale = 1; + tex->count = 3; + tex->minwidth = 0.2; + tex->maxwidth = 0.3; + tex->height = 0.2; + tex->hgap = 0.05; + tex->vgap = 0.05; + tex->shift = 0.1; + tex->bevel = 0.2; + tex->corner = 0; + tex->hcorner = 0.25; + tex->vcorner = 0.25; + tex->rotate = 0; + tex->seed = 0; + tex->hskew = 0; + tex->vskew = 0; + tex->curve = 0; + tex->smooth = 0; + tex->freq = 0; + tex->amp = 0; + tex->alternate = 2; + tiles_precalc(tex); + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */