Permalink
Browse files

Flatten brush !

  • Loading branch information...
trethaller committed Sep 1, 2013
1 parent 88a2ce5 commit a8784ec3617f8109cc1fee668ea9c53d841639c4
Showing with 236 additions and 75 deletions.
  1. +22 −4 out/js/teztura-core.js
  2. +96 −37 out/js/teztura.js
  3. +2 −2 src/app.coffee
  4. +15 −5 src/core/core.coffee
  5. +4 −0 src/core/vec.coffee
  6. +3 −3 src/document-view.coffee
  7. +94 −24 src/tools.coffee
View
@@ -34,9 +34,19 @@ Layer = (function() {
};
Layer.prototype.getNormalAt = function(pos) {
- var fb, p;
+ var fb, norm, p, px, py, sx1, sx2, sy1, sy2, xvec, yvec;
p = pos.round();
- return fb = this.data.fbuffer;
+ fb = this.data.fbuffer;
+ px = Math.round(pos.x);
+ py = Math.round(pos.y);
+ sx1 = fb[py * this.width + ((px - 1) % this.width)];
+ sx2 = fb[py * this.width + ((px + 1) % this.width)];
+ sy1 = fb[((py + 1) % this.height) * this.width + px];
+ sy2 = fb[((py - 1) % this.height) * this.width + px];
+ xvec = new Vec3(2, 0, sx2 - sx1);
+ yvec = new Vec3(0, 2, sy1 - sy2);
+ norm = xvec.cross(yvec).normalized();
+ return norm;
};
Layer.prototype.getCopy = function(rect) {
@@ -118,8 +128,8 @@ genBrushFunc = function(opts) {
var blendExp, brushExp, str;
blendExp = opts.blendExp.replace(/{dst}/g, "dstData[dsti]").replace(/{src}/g, "_tmp");
brushExp = opts.brushExp.replace(/{out}/g, "_tmp");
- str = "(function (rect, dstFb, " + opts.args + ") { var invw = 2.0 / (rect.width - 1); var invh = 2.0 / (rect.height - 1); var offx = -(rect.x % 1.0) * invw - 1.0; var offy = -(rect.y % 1.0) * invh - 1.0; var fbw = dstFb.width; var fbh = dstFb.height; var dstData = dstFb.getBuffer();";
- str += opts.tiling ? " var minx = Math.floor(rect.x) + fbw; var miny = Math.floor(rect.y) + fbh; var sw = Math.round(rect.width); var sh = Math.round(rect.height); for(var sy=0; sy<sh; ++sy) { var y = sy * invh + offy; for(var sx=0; sx<sw; ++sx) { var x = sx * invw + offx; var dsti = ((sy + miny) % fbh) * fbw + ((sx + minx) % fbw); var _tmp = 0.0; " + brushExp + "; " + blendExp + "; } }" : " var minx = Math.floor(Math.max(0, -rect.x)); var miny = Math.floor(Math.max(0, -rect.y)); var sw = Math.round(Math.min(rect.width, fbw - rect.x)); var sh = Math.round(Math.min(rect.height, fbh - rect.y)); for(var sy=miny; sy<sh; ++sy) { var dsti = (Math.floor(rect.y) + sy) * dstFb.width + Math.floor(rect.x) + minx; var y = sy * invh + offy; for(var sx=minx; sx<sw; ++sx) { var x = sx * invw + offx; var _tmp = 0.0; " + brushExp + "; " + blendExp + "; ++dsti; } }";
+ str = "(function (rect, layer, " + opts.args + ") { var invw = 2.0 / (rect.width - 1); var invh = 2.0 / (rect.height - 1); var offx = -(rect.x % 1.0) * invw - 1.0; var offy = -(rect.y % 1.0) * invh - 1.0; var fbw = layer.width; var fbh = layer.height; var dstData = layer.getBuffer();";
+ str += opts.tiling ? " var minx = Math.floor(rect.x) + fbw; var miny = Math.floor(rect.y) + fbh; var sw = Math.round(rect.width); var sh = Math.round(rect.height); for(var sy=0; sy<sh; ++sy) { var y = sy * invh + offy; for(var sx=0; sx<sw; ++sx) { var x = sx * invw + offx; var dsti = ((sy + miny) % fbh) * fbw + ((sx + minx) % fbw); var _tmp = 0.0; " + brushExp + "; " + blendExp + "; } }" : " var minx = Math.floor(Math.max(0, -rect.x)); var miny = Math.floor(Math.max(0, -rect.y)); var sw = Math.round(Math.min(rect.width, fbw - rect.x)); var sh = Math.round(Math.min(rect.height, fbh - rect.y)); for(var sy=miny; sy<sh; ++sy) { var dsti = (Math.floor(rect.y) + sy) * layer.width + Math.floor(rect.x) + minx; var y = sy * invh + offy; for(var sx=minx; sx<sw; ++sx) { var x = sx * invw + offx; var _tmp = 0.0; " + brushExp + "; " + blendExp + "; ++dsti; } }";
str += "});";
return eval(str);
};
@@ -262,6 +272,10 @@ Vec2 = (function() {
return new Vec2((this.x % w + w) % w, (this.y % h + h) % h);
};
+ Vec2.prototype.toString = function() {
+ return this.x + ", " + this.y;
+ };
+
return Vec2;
})();
@@ -305,6 +319,10 @@ Vec3 = (function() {
return this.x + v.x + this.y + v.y + this.z + v.z;
};
+ Vec3.prototype.toString = function() {
+ return this.x + ", " + this.y + ", " + this.z;
+ };
+
return Vec3;
})();
View
@@ -1,4 +1,4 @@
-var BlendModes, Commands, Document, DocumentView, Editor, Flatten, Picker, PropertyPanel, PropertyView, Renderers, RoundBrush, StepBrush, Tools, createCommandsButtons, createPalette, createRenderersButtons, createToolsButtons, editor, loadGradient, refresh, status, toolsProperties, _ref,
+var BlendModes, Commands, Document, DocumentView, Editor, FlattenBrush, Picker, PropertyPanel, PropertyView, Renderers, RoundBrush, StepBrush, Tools, createCommandsButtons, createPalette, createRenderersButtons, createToolsButtons, editor, loadGradient, refresh, status, toolsProperties, _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
@@ -272,7 +272,7 @@ $(window).keyup(function(e) {
$(document).ready(function() {
loadGradient('g1', 'img/gradient-1.png');
Renderers = [GammaRenderer, NormalRenderer, GradientRenderer];
- Tools = [RoundBrush, Picker];
+ Tools = [RoundBrush, Picker, FlattenBrush];
toolsProperties = new PropertyPanel('#tools > .properties');
editor = new Editor();
editor.createDoc(512, 512);
@@ -281,7 +281,7 @@ $(document).ready(function() {
createPalette($('#palette'));
createCommandsButtons($('#commands'));
editor.set('preset', {
- tools: [RoundBrush, Picker]
+ tools: [RoundBrush, FlattenBrush]
});
return editor.set('renderer', GammaRenderer);
});
@@ -363,13 +363,13 @@ DocumentView = (function() {
_this.drawing = true;
_this.actionDirtyRect = null;
coords = getCanvasCoords(e);
- editor.getToolObject().beginDraw(coords);
+ editor.getToolObject().beginDraw(doc.layer, coords);
doc.beginEdit();
_this.onDraw(coords, getPressure());
}
if (e.which === 2) {
_this.panning = true;
- local.panningStart = getCoords(e);
+ local.panningStart = getPenCoords(e);
return local.offsetStart = _this.offset.clone();
}
});
@@ -393,7 +393,7 @@ DocumentView = (function() {
_this.onDraw(getCanvasCoords(e), getPressure());
}
if (_this.panning) {
- curPos = getCoords(e);
+ curPos = getPenCoords(e);
o = local.offsetStart.add(curPos.sub(local.panningStart));
_this.offset = o;
return _this.rePaint();
@@ -618,8 +618,6 @@ PropertyPanel = (function() {
})();
StepBrush = (function() {
- var mod;
-
function StepBrush() {}
StepBrush.prototype.drawing = false;
@@ -641,10 +639,6 @@ StepBrush = (function() {
return rect.extend(pos);
};
- mod = function(val, size) {
- return (val % size + size) % size;
- };
-
StepBrush.prototype.move = function(pos, pressure) {};
StepBrush.prototype.draw = function(layer, pos, pressure) {
@@ -674,7 +668,7 @@ StepBrush = (function() {
return rect;
};
- StepBrush.prototype.beginDraw = function(pos) {
+ StepBrush.prototype.beginDraw = function(layer, pos) {
this.drawing = true;
this.accumulator = 0;
return this.nsteps = 0;
@@ -704,27 +698,7 @@ Picker = (function() {
properties: [],
createTool: function(env) {
return {
- beginDraw: function(pos) {},
- endDraw: function(pos) {},
- move: function() {},
- draw: function(layer, pos, intensity) {
- env.set('targetValue', layer.getAt(pos));
- return Rect.Empty;
- }
- };
- }
- };
-})();
-
-Flatten = (function() {
- return {
- description: {
- name: 'Flatten'
- },
- properties: [],
- createTool: function(env) {
- return {
- beginDraw: function(pos) {},
+ beginDraw: function(layer, pos) {},
endDraw: function(pos) {},
move: function() {},
draw: function(layer, pos, intensity) {
@@ -745,7 +719,7 @@ RoundBrush = (function() {
{
id: 'stepSize',
name: "Step size",
- defaultValue: 2,
+ defaultValue: 3,
range: [1, 10],
type: 'int'
}, {
@@ -756,7 +730,7 @@ RoundBrush = (function() {
}, {
id: 'size',
name: "Size",
- defaultValue: 8.0,
+ defaultValue: 30.0,
range: [1.0, 256.0],
type: 'int'
}, {
@@ -767,7 +741,7 @@ RoundBrush = (function() {
}, {
id: 'intensity',
name: "Intensity",
- defaultValue: 0.6,
+ defaultValue: 0.4,
range: [0.0, 1.0],
power: 2.0
}
@@ -804,6 +778,91 @@ RoundBrush = (function() {
return self;
})();
+FlattenBrush = (function() {
+ var createTool, description, properties, self;
+ description = {
+ name: 'Flatten'
+ };
+ properties = [
+ {
+ id: 'stepSize',
+ name: "Step size",
+ defaultValue: 2,
+ range: [1, 10],
+ type: 'int'
+ }, {
+ id: 'hardness',
+ name: "Hardness",
+ defaultValue: 0.2,
+ range: [0.0, 1.0]
+ }, {
+ id: 'size',
+ name: "Size",
+ defaultValue: 20.0,
+ range: [1.0, 256.0],
+ type: 'int'
+ }, {
+ id: 'intensity',
+ name: "Intensity",
+ defaultValue: 0.6,
+ range: [0.0, 1.0],
+ power: 2.0
+ }
+ ];
+ self = new Backbone.Model;
+ createTool = function(env) {
+ var func, hardness, hardnessPlus1, sb, size;
+ sb = new StepBrush();
+ sb.stepSize = self.get('stepSize');
+ sb.tiling = env.get('tiling');
+ size = self.get('size');
+ hardness = Math.pow(self.get('hardness'), 2.0) * 8.0;
+ hardnessPlus1 = hardness + 1.0;
+ func = genBrushFunc({
+ args: "intensity, h, normal, det",
+ tiling: env.get('tiling'),
+ brushExp: "var d = Math.min(1.0, Math.max(0.0, (Math.sqrt(x*x + y*y) * (h+1) - h))); {out} = Math.cos(d * Math.PI) * 0.5 + 0.5;",
+ blendExp: "var tar = (-normal.x * (rect.x + sx) - normal.y * (rect.y + sy) - det) / normal.z; {dst} = {dst} * (1 - intensity * {src}) + intensity * tar * {src};"
+ });
+ sb.drawStep = function(layer, pos, intensity, rect) {
+ var det, r;
+ r = new Rect(pos.x - size * 0.5, pos.y - size * 0.5, size, size);
+ det = -self.normal.x * self.origin.x - self.normal.y * self.origin.y - self.normal.z * self.origin.z;
+ func(r, layer, intensity * self.get('intensity'), hardness, self.normal, det);
+ return rect.extend(r.round());
+ };
+ return {
+ drawStep: function() {
+ return StepBrush.prototype.drawStep.apply(sb, arguments);
+ },
+ draw: function() {
+ return StepBrush.prototype.draw.apply(sb, arguments);
+ },
+ beginDraw: function(layer, pos) {
+ self.normal = layer.getNormalAt(pos);
+ self.origin = new Vec3(pos.x, pos.y, layer.getAt(pos));
+ return StepBrush.prototype.beginDraw.apply(sb, arguments);
+ /*
+ n = self.normal
+ o = self.origin
+ console.log n.toString(), o.toString()
+ */
+
+ },
+ endDraw: function() {
+ return StepBrush.prototype.endDraw.apply(sb, arguments);
+ }
+ };
+ };
+ self.properties = properties;
+ self.description = description;
+ self.createTool = createTool;
+ properties.forEach(function(p) {
+ return self.set(p.id, p.defaultValue);
+ });
+ return self;
+})();
+
/*
//@ sourceMappingURL=teztura.js.map
*/
View
@@ -211,7 +211,7 @@ $(document).ready ()->
#loadGradient('g2', 'img/gradient-2.png')
Renderers = [GammaRenderer, NormalRenderer, GradientRenderer]
- Tools = [RoundBrush, Picker]
+ Tools = [RoundBrush, Picker, FlattenBrush]
toolsProperties = new PropertyPanel '#tools > .properties'
editor = new Editor()
@@ -224,7 +224,7 @@ $(document).ready ()->
createCommandsButtons($('#commands'))
editor.set('preset', {
- tools: [RoundBrush, Picker]
+ tools: [RoundBrush, FlattenBrush]
})
editor.set('renderer', GammaRenderer)
View
@@ -22,6 +22,16 @@ class Layer
getNormalAt: (pos)->
p = pos.round()
fb = @data.fbuffer
+ px = Math.round(pos.x)
+ py = Math.round(pos.y)
+ sx1 = fb[ py * @width + ((px-1)%@width) ]
+ sx2 = fb[ py * @width + ((px+1)%@width) ]
+ sy1 = fb[ ((py+1) % @height) * @width + px ]
+ sy2 = fb[ ((py-1) % @height) * @width + px ]
+ xvec = new Vec3(2, 0, sx2 - sx1)
+ yvec = new Vec3(0, 2, sy1 - sy2)
+ norm = xvec.cross(yvec).normalized()
+ return norm
getCopy: (rect)->
srcData = @data.buffer
@@ -112,14 +122,14 @@ genBrushFunc = (opts)->
brushExp = opts.brushExp
.replace(/{out}/g, "_tmp")
- str = "(function (rect, dstFb, #{opts.args}) {
+ str = "(function (rect, layer, #{opts.args}) {
var invw = 2.0 / (rect.width - 1);
var invh = 2.0 / (rect.height - 1);
var offx = -(rect.x % 1.0) * invw - 1.0;
var offy = -(rect.y % 1.0) * invh - 1.0;
- var fbw = dstFb.width;
- var fbh = dstFb.height;
- var dstData = dstFb.getBuffer();"
+ var fbw = layer.width;
+ var fbh = layer.height;
+ var dstData = layer.getBuffer();"
str += if opts.tiling then "
var minx = Math.floor(rect.x) + fbw;
@@ -143,7 +153,7 @@ genBrushFunc = (opts)->
var sw = Math.round(Math.min(rect.width, fbw - rect.x));
var sh = Math.round(Math.min(rect.height, fbh - rect.y));
for(var sy=miny; sy<sh; ++sy) {
- var dsti = (Math.floor(rect.y) + sy) * dstFb.width + Math.floor(rect.x) + minx;
+ var dsti = (Math.floor(rect.y) + sy) * layer.width + Math.floor(rect.x) + minx;
var y = sy * invh + offy;
for(var sx=minx; sx<sw; ++sx) {
var x = sx * invw + offx;
View
@@ -27,6 +27,8 @@ class Vec2
return new Vec2(
(@x % w + w) % w,
(@y % h + h) % h)
+ toString: ->
+ return @x + ", " + @y
class Vec3
constructor: (@x, @y, @z) ->;
@@ -50,3 +52,5 @@ class Vec3
dot: (v)->
return @x+v.x + @y+v.y + @z+v.z
+ toString: ->
+ return @x + ", " + @y + ", " + @z
View
@@ -58,13 +58,13 @@ class DocumentView
@drawing = true
@actionDirtyRect = null
coords = getCanvasCoords(e)
- editor.getToolObject().beginDraw(coords)
+ editor.getToolObject().beginDraw(doc.layer, coords)
doc.beginEdit()
@onDraw(coords, getPressure())
if e.which is 2
@panning = true
- local.panningStart = getCoords(e)
+ local.panningStart = getPenCoords(e)
local.offsetStart = @offset.clone()
$container.mouseup (e)=>
@@ -84,7 +84,7 @@ class DocumentView
@onDraw(getCanvasCoords(e), getPressure())
if @panning
- curPos = getCoords(e)
+ curPos = getPenCoords(e)
o = local.offsetStart.add(curPos.sub(local.panningStart))
@offset = o
@rePaint()
Oops, something went wrong.

0 comments on commit a8784ec

Please sign in to comment.