1 /**
  2  * potree.js 
  3  * http://potree.org
  4  *
  5  * Copyright 2012, Markus Sch�tz
  6  * Licensed under the GPL Version 2 or later.
  7  * - http://potree.org/wp/?page_id=7
  8  * - http://www.gnu.org/licenses/gpl-3.0.html
  9  *
 10  */
 11 
 12 /**
 13  * extensions for the mjs.js library
 14  * 
 15  * @author Markus Sch�tz
 16  *
 17  * @class extends the mjs V3 class
 18  */
 19 V3 = V3;
 20 
 21 /**
 22  * @class extends the mjs M4x4 class
 23  */
 24 M4x4 = M4x4;
 25 
 26 
 27 /**
 28  * Function: V3.transform
 29  *
 30  *
 31  * Parameters:
 32  *
 33  *   a - the first vector operand
 34  *   b - the transformation matrix
 35  *
 36  * Returns:
 37  *
 38  *   transformed vector
 39  */
 40 V3.transform = function V3_transform(a, b){
 41 	var r = new MJS_FLOAT_ARRAY_TYPE(3);
 42 	
 43 	r[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + b[12];
 44 	r[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + b[13];
 45 	r[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + b[14];
 46 	var h = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + b[15];
 47 	r[0] = r[0] / h;
 48 	r[1] = r[1] / h;
 49 	r[2] = r[2] / h;
 50 	
 51 	return r;
 52 };
 53 
 54 
 55 
 56 /**
 57  * The original inverseOrthonormal function does not work because it uses Vec3 instead of V3.
 58  */
 59 M4x4.inverseOrthonormal = function M4x4_inverseOrthonormal(m, r) {
 60 
 61     if (r == undefined)
 62         r = new MJS_FLOAT_ARRAY_TYPE(16);
 63     M4x4.transpose(m, r);
 64     var t = [m[12], m[13], m[14]];
 65     r[3] = r[7] = r[11] = 0;
 66     r[12] = -V3.dot([r[0], r[4], r[8]], t);
 67     r[13] = -V3.dot([r[1], r[5], r[9]], t);
 68     r[14] = -V3.dot([r[2], r[6], r[10]], t);
 69     return r;
 70 };
 71 
 72 /**
 73  * the original direction function returned the direction from b to a, instead of a to b as stated in the comment.
 74  * 
 75  * Function: V3.direction
 76  *
 77  * Perform
 78  * r = (a - b) / |a - b|.  The result is the normalized
 79  * direction from a to b.
 80  *
 81  * Parameters:
 82  *
 83  *   a - the first vector operand
 84  *   b - the second vector operand
 85  *   r - optional vector to store the result in
 86  *
 87  * Returns:
 88  *
 89  *   If r is specified, returns r after performing the operation.
 90  *   Otherwise, returns a new 3-element vector with the result.
 91  */
 92 V3.direction = function V3_direction(a, b, r) {
 93     if (r == undefined)
 94         r = new MJS_FLOAT_ARRAY_TYPE(3);
 95     return V3.normalize(V3.sub(b, a, r), r);
 96 };
 97 
 98 
 99 /**
100  * from http://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison
101  * 
102  * @param a
103  * @param b
104  * @param epsilon 
105  * @returns {Boolean}
106  */
107 V3.equalScalar = function V3_equalScalar(a,b,epsilon){
108 	var absA = Math.abs(a);
109     var absB = Math.abs(b);
110     var diff = Math.abs(a - b);
111 
112     if (a == b) { // shortcut, handles infinities
113         return true;
114     } else if (a * b == 0) { // a or b or both are zero
115         // relative error is not meaningful here
116         return diff < (epsilon * epsilon);
117     } else { // use relative error
118         return diff / (absA + absB) < epsilon;
119     }
120 };
121 
122 V3.equal = function V3_equal(a,b,epsilon){
123 	if(epsilon == undefined){
124 		epsilon = 0.000001;
125 	}
126 //	return 
127 //		V3.equalScalar(a[0], b[0], 0.000001) && 
128 //		V3.equalScalar(a[1], b[1], 0.000001) && 
129 //		V3.equalScalar(a[2], b[2], 0.000001);
130 	var equals = V3.equalScalar(a[0], b[0], epsilon);
131 	equals = equals && V3.equalScalar(a[1], b[1], epsilon);
132 	equals = equals && V3.equalScalar(a[2], b[2], epsilon);
133 	return equals;
134 };
135