1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 base.require('base.gl_matrix');
9 base.exportTo('base', function() {
11 for (var i = 0; i < 8; i++)
12 tmpVec2s[i] = vec2.create();
14 var tmpVec2a = vec4.create();
15 var tmpVec4a = vec4.create();
16 var tmpVec4b = vec4.create();
17 var tmpMat4 = mat4.create();
18 var tmpMat4b = mat4.create();
20 var p00 = vec2.createXY(0, 0);
21 var p10 = vec2.createXY(1, 0);
22 var p01 = vec2.createXY(0, 1);
23 var p11 = vec2.createXY(1, 1);
25 var lerpingVecA = vec2.create();
26 var lerpingVecB = vec2.create();
27 function lerpVec2(out, a, b, amt) {
28 vec2.scale(lerpingVecA, a, amt);
29 vec2.scale(lerpingVecB, b, 1 - amt);
30 vec2.add(out, lerpingVecA, lerpingVecB);
31 vec2.normalize(out, out);
39 this.p1 = vec2.create();
40 this.p2 = vec2.create();
41 this.p3 = vec2.create();
42 this.p4 = vec2.create();
45 Quad.fromXYWH = function(x, y, w, h) {
48 vec2.set(q.p2, x + w, y);
49 vec2.set(q.p3, x + w, y + h);
50 vec2.set(q.p4, x, y + h);
54 Quad.fromRect = function(r) {
55 return new Quad.fromXYWH(
60 Quad.from4Vecs = function(p1, p2, p3, p4) {
62 vec2.set(q.p1, p1[0], p1[1]);
63 vec2.set(q.p2, p2[0], p2[1]);
64 vec2.set(q.p3, p3[0], p3[1]);
65 vec2.set(q.p4, p4[0], p4[1]);
69 Quad.from8Array = function(arr) {
71 throw new Error('Array must be 8 long');
85 pointInside: function(point) {
86 return pointInImplicitQuad(point,
87 this.p1, this.p2, this.p3, this.p4);
90 boundingRect: function() {
91 var x0 = Math.min(this.p1[0], this.p2[0], this.p3[0], this.p4[0]);
92 var y0 = Math.min(this.p1[1], this.p2[1], this.p3[1], this.p4[1]);
94 var x1 = Math.max(this.p1[0], this.p2[0], this.p3[0], this.p4[0]);
95 var y1 = Math.max(this.p1[1], this.p2[1], this.p3[1], this.p4[1]);
97 return new base.Rect.fromXYWH(x0, y0, x1 - x0, y1 - y0);
102 vec2.copy(q.p1, this.p1);
103 vec2.copy(q.p2, this.p2);
104 vec2.copy(q.p3, this.p3);
105 vec2.copy(q.p4, this.p4);
111 this.scaleFast(q, s);
115 scaleFast: function(dstQuad, s) {
116 vec2.copy(dstQuad.p1, this.p1, s);
117 vec2.copy(dstQuad.p2, this.p2, s);
118 vec2.copy(dstQuad.p3, this.p3, s);
119 vec2.copy(dstQuad.p3, this.p3, s);
122 isRectangle: function() {
123 // Simple rectangle check. Note: will not handle out-of-order components.
124 var bounds = this.boundingRect();
126 bounds.x == this.p1[0] &&
127 bounds.y == this.p1[1] &&
128 bounds.width == this.p2[0] - this.p1[0] &&
129 bounds.y == this.p2[1] &&
130 bounds.width == this.p3[0] - this.p1[0] &&
131 bounds.height == this.p3[1] - this.p2[1] &&
132 bounds.x == this.p4[0] &&
133 bounds.height == this.p4[1] - this.p2[1]
137 projectUnitRect: function(rect) {
139 this.projectUnitRectFast(q, rect);
143 projectUnitRectFast: function(dstQuad, rect) {
144 var v12 = tmpVec2s[0];
145 var v14 = tmpVec2s[1];
146 var v23 = tmpVec2s[2];
147 var v43 = tmpVec2s[3];
148 var l12, l14, l23, l43;
150 vec2.sub(v12, this.p2, this.p1);
151 l12 = vec2.length(v12);
152 vec2.scale(v12, v12, 1 / l12);
154 vec2.sub(v14, this.p4, this.p1);
155 l14 = vec2.length(v14);
156 vec2.scale(v14, v14, 1 / l14);
158 vec2.sub(v23, this.p3, this.p2);
159 l23 = vec2.length(v23);
160 vec2.scale(v23, v23, 1 / l23);
162 vec2.sub(v43, this.p3, this.p4);
163 l43 = vec2.length(v43);
164 vec2.scale(v43, v43, 1 / l43);
166 var b12 = tmpVec2s[0];
167 var b14 = tmpVec2s[1];
168 var b23 = tmpVec2s[2];
169 var b43 = tmpVec2s[3];
170 lerpVec2(b12, v12, v43, rect.y);
171 lerpVec2(b43, v12, v43, 1 - rect.bottom);
172 lerpVec2(b14, v14, v23, rect.x);
173 lerpVec2(b23, v14, v23, 1 - rect.right);
175 vec2.addTwoScaledUnitVectors(tmpVec2a,
178 vec2.add(dstQuad.p1, this.p1, tmpVec2a);
180 vec2.addTwoScaledUnitVectors(tmpVec2a,
181 b12, l12 * -(1.0 - rect.right),
183 vec2.add(dstQuad.p2, this.p2, tmpVec2a);
186 vec2.addTwoScaledUnitVectors(tmpVec2a,
187 b43, l43 * -(1.0 - rect.right),
188 b23, l23 * -(1.0 - rect.bottom));
189 vec2.add(dstQuad.p3, this.p3, tmpVec2a);
191 vec2.addTwoScaledUnitVectors(tmpVec2a,
192 b43, l43 * rect.left,
193 b14, l14 * -(1.0 - rect.bottom));
194 vec2.add(dstQuad.p4, this.p4, tmpVec2a);
197 toString: function() {
199 vec2.toString(this.p1) + ', ' +
200 vec2.toString(this.p2) + ', ' +
201 vec2.toString(this.p3) + ', ' +
202 vec2.toString(this.p4) + ')';
206 function sign(p1, p2, p3) {
207 return (p1[0] - p3[0]) * (p2[1] - p3[1]) -
208 (p2[0] - p3[0]) * (p1[1] - p3[1]);
211 function pointInTriangle2(pt, p1, p2, p3) {
212 var b1 = sign(pt, p1, p2) < 0.0;
213 var b2 = sign(pt, p2, p3) < 0.0;
214 var b3 = sign(pt, p3, p1) < 0.0;
215 return ((b1 == b2) && (b2 == b3));
218 function pointInImplicitQuad(point, p1, p2, p3, p4) {
219 return pointInTriangle2(point, p1, p2, p3) ||
220 pointInTriangle2(point, p1, p3, p4);
224 pointInTriangle2: pointInTriangle2,
225 pointInImplicitQuad: pointInImplicitQuad,