1<!DOCTYPE html> 2<!-- 3Copyright (c) 2014 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7<link rel="import" href="/tracing/base/base.html"> 8<link rel="import" href="/tracing/base/math.html"> 9<script> 10'use strict'; 11 12tr.exportTo('tr.b', function() { 13 var tmpVec2s = []; 14 for (var i = 0; i < 8; i++) 15 tmpVec2s[i] = vec2.create(); 16 17 var tmpVec2a = vec4.create(); 18 var tmpVec4a = vec4.create(); 19 var tmpVec4b = vec4.create(); 20 var tmpMat4 = mat4.create(); 21 var tmpMat4b = mat4.create(); 22 23 var p00 = vec2.createXY(0, 0); 24 var p10 = vec2.createXY(1, 0); 25 var p01 = vec2.createXY(0, 1); 26 var p11 = vec2.createXY(1, 1); 27 28 var lerpingVecA = vec2.create(); 29 var lerpingVecB = vec2.create(); 30 function lerpVec2(out, a, b, amt) { 31 vec2.scale(lerpingVecA, a, amt); 32 vec2.scale(lerpingVecB, b, 1 - amt); 33 vec2.add(out, lerpingVecA, lerpingVecB); 34 vec2.normalize(out, out); 35 return out; 36 } 37 38 /** 39 * @constructor 40 */ 41 function Quad() { 42 this.p1 = vec2.create(); 43 this.p2 = vec2.create(); 44 this.p3 = vec2.create(); 45 this.p4 = vec2.create(); 46 } 47 48 Quad.fromXYWH = function(x, y, w, h) { 49 var q = new Quad(); 50 vec2.set(q.p1, x, y); 51 vec2.set(q.p2, x + w, y); 52 vec2.set(q.p3, x + w, y + h); 53 vec2.set(q.p4, x, y + h); 54 return q; 55 } 56 57 Quad.fromRect = function(r) { 58 return new Quad.fromXYWH( 59 r.x, r.y, 60 r.width, r.height); 61 } 62 63 Quad.from4Vecs = function(p1, p2, p3, p4) { 64 var q = new Quad(); 65 vec2.set(q.p1, p1[0], p1[1]); 66 vec2.set(q.p2, p2[0], p2[1]); 67 vec2.set(q.p3, p3[0], p3[1]); 68 vec2.set(q.p4, p4[0], p4[1]); 69 return q; 70 } 71 72 Quad.from8Array = function(arr) { 73 if (arr.length != 8) 74 throw new Error('Array must be 8 long'); 75 var q = new Quad(); 76 q.p1[0] = arr[0]; 77 q.p1[1] = arr[1]; 78 q.p2[0] = arr[2]; 79 q.p2[1] = arr[3]; 80 q.p3[0] = arr[4]; 81 q.p3[1] = arr[5]; 82 q.p4[0] = arr[6]; 83 q.p4[1] = arr[7]; 84 return q; 85 }; 86 87 Quad.prototype = { 88 pointInside: function(point) { 89 return pointInImplicitQuad(point, 90 this.p1, this.p2, this.p3, this.p4); 91 }, 92 93 boundingRect: function() { 94 var x0 = Math.min(this.p1[0], this.p2[0], this.p3[0], this.p4[0]); 95 var y0 = Math.min(this.p1[1], this.p2[1], this.p3[1], this.p4[1]); 96 97 var x1 = Math.max(this.p1[0], this.p2[0], this.p3[0], this.p4[0]); 98 var y1 = Math.max(this.p1[1], this.p2[1], this.p3[1], this.p4[1]); 99 100 return new tr.b.Rect.fromXYWH(x0, y0, x1 - x0, y1 - y0); 101 }, 102 103 clone: function() { 104 var q = new Quad(); 105 vec2.copy(q.p1, this.p1); 106 vec2.copy(q.p2, this.p2); 107 vec2.copy(q.p3, this.p3); 108 vec2.copy(q.p4, this.p4); 109 return q; 110 }, 111 112 scale: function(s) { 113 var q = new Quad(); 114 this.scaleFast(q, s); 115 return q; 116 }, 117 118 scaleFast: function(dstQuad, s) { 119 vec2.copy(dstQuad.p1, this.p1, s); 120 vec2.copy(dstQuad.p2, this.p2, s); 121 vec2.copy(dstQuad.p3, this.p3, s); 122 vec2.copy(dstQuad.p3, this.p3, s); 123 }, 124 125 isRectangle: function() { 126 // Simple rectangle check. Note: will not handle out-of-order components. 127 var bounds = this.boundingRect(); 128 return ( 129 bounds.x == this.p1[0] && 130 bounds.y == this.p1[1] && 131 bounds.width == this.p2[0] - this.p1[0] && 132 bounds.y == this.p2[1] && 133 bounds.width == this.p3[0] - this.p1[0] && 134 bounds.height == this.p3[1] - this.p2[1] && 135 bounds.x == this.p4[0] && 136 bounds.height == this.p4[1] - this.p2[1] 137 ); 138 }, 139 140 projectUnitRect: function(rect) { 141 var q = new Quad(); 142 this.projectUnitRectFast(q, rect); 143 return q; 144 }, 145 146 projectUnitRectFast: function(dstQuad, rect) { 147 var v12 = tmpVec2s[0]; 148 var v14 = tmpVec2s[1]; 149 var v23 = tmpVec2s[2]; 150 var v43 = tmpVec2s[3]; 151 var l12, l14, l23, l43; 152 153 vec2.sub(v12, this.p2, this.p1); 154 l12 = vec2.length(v12); 155 vec2.scale(v12, v12, 1 / l12); 156 157 vec2.sub(v14, this.p4, this.p1); 158 l14 = vec2.length(v14); 159 vec2.scale(v14, v14, 1 / l14); 160 161 vec2.sub(v23, this.p3, this.p2); 162 l23 = vec2.length(v23); 163 vec2.scale(v23, v23, 1 / l23); 164 165 vec2.sub(v43, this.p3, this.p4); 166 l43 = vec2.length(v43); 167 vec2.scale(v43, v43, 1 / l43); 168 169 var b12 = tmpVec2s[0]; 170 var b14 = tmpVec2s[1]; 171 var b23 = tmpVec2s[2]; 172 var b43 = tmpVec2s[3]; 173 lerpVec2(b12, v12, v43, rect.y); 174 lerpVec2(b43, v12, v43, 1 - rect.bottom); 175 lerpVec2(b14, v14, v23, rect.x); 176 lerpVec2(b23, v14, v23, 1 - rect.right); 177 178 vec2.addTwoScaledUnitVectors(tmpVec2a, 179 b12, l12 * rect.x, 180 b14, l14 * rect.y); 181 vec2.add(dstQuad.p1, this.p1, tmpVec2a); 182 183 vec2.addTwoScaledUnitVectors(tmpVec2a, 184 b12, l12 * -(1.0 - rect.right), 185 b23, l23 * rect.y); 186 vec2.add(dstQuad.p2, this.p2, tmpVec2a); 187 188 189 vec2.addTwoScaledUnitVectors(tmpVec2a, 190 b43, l43 * -(1.0 - rect.right), 191 b23, l23 * -(1.0 - rect.bottom)); 192 vec2.add(dstQuad.p3, this.p3, tmpVec2a); 193 194 vec2.addTwoScaledUnitVectors(tmpVec2a, 195 b43, l43 * rect.left, 196 b14, l14 * -(1.0 - rect.bottom)); 197 vec2.add(dstQuad.p4, this.p4, tmpVec2a); 198 }, 199 200 toString: function() { 201 return 'Quad(' + 202 vec2.toString(this.p1) + ', ' + 203 vec2.toString(this.p2) + ', ' + 204 vec2.toString(this.p3) + ', ' + 205 vec2.toString(this.p4) + ')'; 206 } 207 }; 208 209 function sign(p1, p2, p3) { 210 return (p1[0] - p3[0]) * (p2[1] - p3[1]) - 211 (p2[0] - p3[0]) * (p1[1] - p3[1]); 212 } 213 214 function pointInTriangle2(pt, p1, p2, p3) { 215 var b1 = sign(pt, p1, p2) < 0.0; 216 var b2 = sign(pt, p2, p3) < 0.0; 217 var b3 = sign(pt, p3, p1) < 0.0; 218 return ((b1 == b2) && (b2 == b3)); 219 } 220 221 function pointInImplicitQuad(point, p1, p2, p3, p4) { 222 return pointInTriangle2(point, p1, p2, p3) || 223 pointInTriangle2(point, p1, p3, p4); 224 } 225 226 return { 227 pointInTriangle2: pointInTriangle2, 228 pointInImplicitQuad: pointInImplicitQuad, 229 Quad: Quad 230 }; 231}); 232</script> 233