166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// Copyright (c) 2013 The Chromium Authors. All rights reserved. 266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// Use of this source code is governed by a BSD-style license that can be 366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// found in the LICENSE file. 466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis'use strict'; 666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.gl_matrix'); 866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.exportTo('base', function() { 1066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var tmpVec2s = []; 1166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis for (var i = 0; i < 8; i++) 1266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis tmpVec2s[i] = vec2.create(); 1366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var tmpVec2a = vec4.create(); 1566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var tmpVec4a = vec4.create(); 1666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var tmpVec4b = vec4.create(); 1766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var tmpMat4 = mat4.create(); 1866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var tmpMat4b = mat4.create(); 1966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 2066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var p00 = vec2.createXY(0, 0); 2166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var p10 = vec2.createXY(1, 0); 2266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var p01 = vec2.createXY(0, 1); 2366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var p11 = vec2.createXY(1, 1); 2466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 2566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var lerpingVecA = vec2.create(); 2666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var lerpingVecB = vec2.create(); 2766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis function lerpVec2(out, a, b, amt) { 2866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.scale(lerpingVecA, a, amt); 2966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.scale(lerpingVecB, b, 1 - amt); 3066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.add(out, lerpingVecA, lerpingVecB); 3166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.normalize(out, out); 3266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return out; 3366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 3466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 3566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis /** 3666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @constructor 3766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */ 3866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis function Quad() { 3966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.p1 = vec2.create(); 4066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.p2 = vec2.create(); 4166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.p3 = vec2.create(); 4266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.p4 = vec2.create(); 4366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 4466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 4566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis Quad.FromXYWH = function(x, y, w, h) { 4666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var q = new Quad(); 4766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.set(q.p1, x, y); 4866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.set(q.p2, x + w, y); 4966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.set(q.p3, x + w, y + h); 5066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.set(q.p4, x, y + h); 5166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return q; 5266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 5366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 5466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis Quad.FromRect = function(r) { 5566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return new Quad.FromXYWH( 5666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis r.x, r.y, 5766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis r.width, r.height); 5866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 5966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 6066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis Quad.From4Vecs = function(p1, p2, p3, p4) { 6166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var q = new Quad(); 6266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.set(q.p1, p1[0], p1[1]); 6366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.set(q.p2, p2[0], p2[1]); 6466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.set(q.p3, p3[0], p3[1]); 6566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.set(q.p4, p4[0], p4[1]); 6666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return q; 6766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 6866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 6966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis Quad.From8Array = function(arr) { 7066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (arr.length != 8) 7166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis throw new Error('Array must be 8 long'); 7266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var q = new Quad(); 7366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis q.p1[0] = arr[0]; 7466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis q.p1[1] = arr[1]; 7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis q.p2[0] = arr[2]; 7666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis q.p2[1] = arr[3]; 7766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis q.p3[0] = arr[4]; 7866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis q.p3[1] = arr[5]; 7966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis q.p4[0] = arr[6]; 8066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis q.p4[1] = arr[7]; 8166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return q; 8266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }; 8366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 8466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis Quad.prototype = { 8566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vecInside: function(vec) { 8666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return vecInTriangle2(vec, this.p1, this.p2, this.p3) || 8766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vecInTriangle2(vec, this.p1, this.p3, this.p4); 8866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 8966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 9066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis boundingRect: function() { 9166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var x0 = Math.min(this.p1[0], this.p2[0], this.p3[0], this.p4[0]); 9266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var y0 = Math.min(this.p1[1], this.p2[1], this.p3[1], this.p4[1]); 9366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 9466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var x1 = Math.max(this.p1[0], this.p2[0], this.p3[0], this.p4[0]); 9566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var y1 = Math.max(this.p1[1], this.p2[1], this.p3[1], this.p4[1]); 9666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 9766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return new base.Rect.FromXYWH(x0, y0, x1 - x0, y1 - y0); 9866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 9966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 10066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis clone: function() { 10166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var q = new Quad(); 10266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.copy(q.p1, this.p1); 10366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.copy(q.p2, this.p2); 10466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.copy(q.p3, this.p3); 10566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.copy(q.p4, this.p4); 10666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return q; 10766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 10866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 10966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis scale: function(s) { 11066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var q = new Quad(); 11166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.scaleFast(q, s); 11266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return q; 11366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 11466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 11566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis scaleFast: function(dstQuad, s) { 11666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.copy(dstQuad.p1, this.p1, s); 11766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.copy(dstQuad.p2, this.p2, s); 11866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.copy(dstQuad.p3, this.p3, s); 11966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.copy(dstQuad.p3, this.p3, s); 12066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 12166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 12266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis isRectangle: function() { 12366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis // Simple rectangle check. Note: will not handle out-of-order components. 12466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var bounds = this.boundingRect(); 12566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return ( 12666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bounds.x == this.p1[0] && 12766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bounds.y == this.p1[1] && 12866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bounds.width == this.p2[0] - this.p1[0] && 12966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bounds.y == this.p2[1] && 13066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bounds.width == this.p3[0] - this.p1[0] && 13166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bounds.height == this.p3[1] - this.p2[1] && 13266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bounds.x == this.p4[0] && 13366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis bounds.height == this.p4[1] - this.p2[1] 13466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ); 13566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 13666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 13766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis projectUnitRect: function(rect) { 13866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var q = new Quad(); 13966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.projectUnitRectFast(q, rect); 14066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return q; 14166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 14266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 14366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis projectUnitRectFast: function(dstQuad, rect) { 14466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var v12 = tmpVec2s[0]; 14566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var v14 = tmpVec2s[1]; 14666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var v23 = tmpVec2s[2]; 14766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var v43 = tmpVec2s[3]; 14866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var l12, l14, l23, l43; 14966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 15066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.sub(v12, this.p2, this.p1); 15166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis l12 = vec2.length(v12); 15266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.scale(v12, v12, 1 / l12); 15366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 15466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.sub(v14, this.p4, this.p1); 15566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis l14 = vec2.length(v14); 15666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.scale(v14, v14, 1 / l14); 15766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 15866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.sub(v23, this.p3, this.p2); 15966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis l23 = vec2.length(v23); 16066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.scale(v23, v23, 1 / l23); 16166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 16266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.sub(v43, this.p3, this.p4); 16366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis l43 = vec2.length(v43); 16466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.scale(v43, v43, 1 / l43); 16566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 16666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var b12 = tmpVec2s[0]; 16766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var b14 = tmpVec2s[1]; 16866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var b23 = tmpVec2s[2]; 16966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var b43 = tmpVec2s[3]; 17066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis lerpVec2(b12, v12, v43, rect.y); 17166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis lerpVec2(b43, v12, v43, 1 - rect.bottom); 17266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis lerpVec2(b14, v14, v23, rect.x); 17366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis lerpVec2(b23, v14, v23, 1 - rect.right); 17466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 17566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.addTwoScaledUnitVectors(tmpVec2a, 17666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis b12, l12 * rect.x, 17766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis b14, l14 * rect.y); 17866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.add(dstQuad.p1, this.p1, tmpVec2a); 17966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 18066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.addTwoScaledUnitVectors(tmpVec2a, 18166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis b12, l12 * -(1.0 - rect.right), 18266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis b23, l23 * rect.y); 18366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.add(dstQuad.p2, this.p2, tmpVec2a); 18466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 18566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 18666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.addTwoScaledUnitVectors(tmpVec2a, 18766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis b43, l43 * -(1.0 - rect.right), 18866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis b23, l23 * -(1.0 - rect.bottom)); 18966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.add(dstQuad.p3, this.p3, tmpVec2a); 19066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 19166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.addTwoScaledUnitVectors(tmpVec2a, 19266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis b43, l43 * rect.left, 19366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis b14, l14 * -(1.0 - rect.bottom)); 19466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.add(dstQuad.p4, this.p4, tmpVec2a); 19566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 19666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 19766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis toString: function() { 19866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return 'Quad(' + 19966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.toString(this.p1) + ', ' + 20066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.toString(this.p2) + ', ' + 20166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.toString(this.p3) + ', ' + 20266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vec2.toString(this.p4) + ')'; 20366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 20466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }; 20566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 20666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis function sign(p1, p2, p3) { 20766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return (p1[0] - p3[0]) * (p2[1] - p3[1]) - 20866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis (p2[0] - p3[0]) * (p1[1] - p3[1]); 20966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 21066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 21166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis function vecInTriangle2(pt, p1, p2, p3) { 21266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var b1 = sign(pt, p1, p2) < 0.0; 21366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var b2 = sign(pt, p2, p3) < 0.0; 21466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var b3 = sign(pt, p3, p1) < 0.0; 21566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return ((b1 == b2) && (b2 == b3)); 21666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 21766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 21866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return { 21966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vecInTriangle2: vecInTriangle2, 22066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis Quad: Quad 22166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }; 22266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis}); 223