Skip to content

Commit

Permalink
Smooth Quad Distortion (relates to #4288)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vamoss committed Nov 16, 2020
1 parent a561af7 commit 75b8afd
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 19 deletions.
50 changes: 45 additions & 5 deletions src/core/p5.Renderer2D.js
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,18 @@ p5.Renderer2D.prototype.point = function(x, y) {
this._setFill(f);
};

p5.Renderer2D.prototype.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) {
p5.Renderer2D.prototype.quad = function(
x1,
y1,
x2,
y2,
x3,
y3,
x4,
y4,
detailX,
detailY
) {
const ctx = this.drawingContext;
const doFill = this._doFill,
doStroke = this._doStroke;
Expand All @@ -595,12 +606,41 @@ p5.Renderer2D.prototype.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) {
return this;
}
}

if (typeof detailX === 'undefined') {
detailX = 2;
}
if (typeof detailY === 'undefined') {
detailY = 2;
}

ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.lineTo(x4, y4);

let xRes = 1.0 / (detailX - 1);
let yRes = 1.0 / (detailY - 1);
for (let y = 0; y < detailY; y++) {
for (let x = 0; x < detailX; x++) {
let pctx = x * xRes;
let pcty = y * yRes;

let linePt0x = (1 - pcty) * x1 + pcty * x4;
let linePt0y = (1 - pcty) * y1 + pcty * y4;
let linePt1x = (1 - pcty) * x2 + pcty * x3;
let linePt1y = (1 - pcty) * y2 + pcty * y3;

let ptx = (1 - pctx) * linePt0x + pctx * linePt1x;
let pty = (1 - pctx) * linePt0y + pctx * linePt1y;

if (x === 0 && y === 0) {
ctx.moveTo(ptx, pty);
} else {
ctx.lineTo(ptx, pty);
}
}
}

ctx.closePath();

if (doFill) {
ctx.fill();
}
Expand Down
9 changes: 7 additions & 2 deletions src/core/shape/2d_primitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ p5.prototype.point = function(...args) {
* @param {Number} y3 the y-coordinate of the third point
* @param {Number} x4 the x-coordinate of the fourth point
* @param {Number} y4 the y-coordinate of the fourth point
* @param {Integer} [detailX] number of segments in the x-direction
* @param {Integer} [detailY] number of segments in the y-direction
* @chainable
* @example
* <div>
Expand All @@ -513,21 +515,24 @@ p5.prototype.point = function(...args) {
* @param {Number} x4
* @param {Number} y4
* @param {Number} z4 the z-coordinate of the fourth point
* @param {Integer} [detailX]
* @param {Integer} [detailY]
* @chainable
*/
p5.prototype.quad = function(...args) {
p5._validateParameters('quad', args);

if (this._renderer._doStroke || this._renderer._doFill) {
if (this._renderer.isP3D && args.length !== 12) {
if (this._renderer.isP3D && args.length <= 12) {
// if 3D and we weren't passed 12 args, assume Z is 0
// prettier-ignore
this._renderer.quad.call(
this._renderer,
args[0], args[1], 0,
args[2], args[3], 0,
args[4], args[5], 0,
args[6], args[7], 0);
args[6], args[7], 0,
args[8], args[9]);
} else {
this._renderer.quad(...args);
//accessibile outputs
Expand Down
60 changes: 48 additions & 12 deletions src/webgl/3d_primitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -1233,24 +1233,60 @@ p5.RendererGL.prototype.rect = function(args) {
};

// prettier-ignore
p5.RendererGL.prototype.quad = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) {
p5.RendererGL.prototype.quad = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, detailX, detailY) {
if (typeof detailX === 'undefined') {
detailX = 2;
}
if (typeof detailY === 'undefined') {
detailY = 2;
}

const gId =
`quad|${x1}|${y1}|${z1}|${x2}|${y2}|${z2}|${x3}|${y3}|${z3}|${x4}|${y4}|${z4}`;
`quad|${x1}|${y1}|${z1}|${x2}|${y2}|${z2}|${x3}|${y3}|${z3}|${x4}|${y4}|${z4}|${detailX}|${detailY}`;

if (!this.geometryInHash(gId)) {
const _quad = function() {
this.vertices.push(new p5.Vector(x1, y1, z1));
this.vertices.push(new p5.Vector(x2, y2, z2));
this.vertices.push(new p5.Vector(x3, y3, z3));
this.vertices.push(new p5.Vector(x4, y4, z4));
this.uvs.push(0, 0, 1, 0, 1, 1, 0, 1);
this.strokeIndices = [[0, 1], [1, 2], [2, 3], [3, 0]];
};
const quadGeom = new p5.Geometry(2, 2, _quad);
const quadGeom = new p5.Geometry(detailX, detailY, function() {
//algorithm adapted from c++ to js
//https://stackoverflow.com/questions/16989181/whats-the-correct-way-to-draw-a-distorted-plane-in-opengl/16993202#16993202
let xRes = 1.0 / (this.detailX - 1);
let yRes = 1.0 / (this.detailY - 1);
for (let y = 0; y < this.detailY; y++) {
for (let x = 0; x < this.detailX; x++) {
let pctx = x * xRes;
let pcty = y * yRes;

let linePt0x = (1 - pcty) * x1 + pcty * x4;
let linePt0y = (1 - pcty) * y1 + pcty * y4;
let linePt0z = (1 - pcty) * z1 + pcty * z4;
let linePt1x = (1 - pcty) * x2 + pcty * x3;
let linePt1y = (1 - pcty) * y2 + pcty * y3;
let linePt1z = (1 - pcty) * z2 + pcty * z3;

let ptx = (1 - pctx) * linePt0x + pctx * linePt1x;
let pty = (1 - pctx) * linePt0y + pctx * linePt1y;
let ptz = (1 - pctx) * linePt0z + pctx * linePt1z;

this.vertices.push(new p5.Vector(ptx, pty, ptz));
this.uvs.push([pctx, pcty]);
}
}
});

quadGeom.faces = [];
for(let y = 0; y < detailY-1; y++){
for(let x = 0; x < detailX-1; x++){
let pt0 = x + y * detailX;
let pt1 = (x + 1) + y * detailX;
let pt2 = (x + 1) + (y + 1) * detailX;
let pt3 = x + (y + 1) * detailX;
quadGeom.faces.push([pt0, pt1, pt2]);
quadGeom.faces.push([pt0, pt2, pt3]);
}
}
quadGeom
.computeNormals()
._makeTriangleEdges()
._edgesToVertices();
quadGeom.faces = [[0, 1, 2], [2, 3, 0]];
this.createBuffers(gId, quadGeom);
}
this.drawBuffers(gId);
Expand Down

0 comments on commit 75b8afd

Please sign in to comment.