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 * 14 * @class 15 * Axis aligned bounding box 16 * 17 * 18 * <pre> 19 * 7----6 y 20 * / /| | 21 * 4----5 | | 22 * | 3--|-2 |______ x 23 * |/ |/ .� 24 * 0----1 �z 25 * </pre> 26 * 27 * @see http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ 28 */ 29 function AABB(){ 30 this.points = 24; 31 this.color = [ 1.0, 0.0, 0.0, 1.0]; 32 33 // transformed minimum and maximum coordinates 34 this.min = V3.$(0,0,0); 35 this.max = V3.$(0,0,0); 36 this.center = null; 37 this.radius = null; 38 39 this.vbo = null; 40 41 this.transform = M4x4.I; 42 43 // object space coordinates. of the bounding box. 44 this.p0 = null; 45 this.p1 = null; 46 this.p2 = null; 47 this.p3 = null; 48 this.p4 = null; 49 this.p5 = null; 50 this.p6 = null; 51 this.p7 = null; 52 this.objectSpaceMin = V3.$(0,0,0); 53 this.objectSpaceMax = V3.$(0,0,0); 54 } 55 56 /** 57 * set object space coordinates of this bounding box 58 * 59 * @param p0 60 * @param p1 61 * @param p2 62 * @param p3 63 * @param p4 64 * @param p5 65 * @param p6 66 * @param p7 67 */ 68 AABB.prototype.setDimension = function(p0, p1, p2, p3, p4, p5, p6, p7) { 69 this.p0 = p0; 70 this.p1 = p1; 71 this.p2 = p2; 72 this.p3 = p3; 73 this.p4 = p4; 74 this.p5 = p5; 75 this.p6 = p6; 76 this.p7 = p7; 77 this.update(); 78 }; 79 80 /** 81 * set object space coordinates by providing the minimum and the maximum vertex of the aabb. 82 * 83 * @param min 84 * @param max 85 */ 86 AABB.prototype.setDimensionByMinMax = function(min, max){ 87 this.p0 = [min[0], min[1], max[2]]; 88 this.p1 = [max[0], min[1], max[2]]; 89 this.p2 = [max[0], min[1], min[2]]; 90 this.p3 = [min[0], min[1], min[2]]; 91 this.p4 = [min[0], max[1], max[2]]; 92 this.p5 = [max[0], max[1], max[2]]; 93 this.p6 = [max[0], max[1], min[2]]; 94 this.p7 = [min[0], max[1], min[2]]; 95 this.update(); 96 }; 97 98 /** 99 * transforms the aabb from object space. 100 * 101 * @param transform 102 */ 103 AABB.prototype.setTransform = function(transform){ 104 this.transform = transform; 105 106 this.update(); 107 }; 108 109 110 AABB.tmpVec = V3.$(0,0,0); 111 /** 112 * calculates min, max, center and radius of the transformed AABB. p0 to p7 will be kept in object space. 113 */ 114 AABB.prototype.update = function update(){ 115 116 // calculate the minimum of the box 117 this.objectSpaceMin[0] = Math.min(this.p0[0], this.p1[0], this.p2[0], this.p3[0], this.p4[0], this.p5[0], this.p6[0], this.p7[0]); 118 this.objectSpaceMin[1] = Math.min(this.p0[1], this.p1[1], this.p2[1], this.p3[1], this.p4[1], this.p5[1], this.p6[1], this.p7[1]); 119 this.objectSpaceMin[2] = Math.min(this.p0[2], this.p1[2], this.p2[2], this.p3[2], this.p4[2], this.p5[2], this.p6[2], this.p7[2]); 120 121 // calculate maximum of the box 122 this.objectSpaceMax[0] = Math.max(this.p0[0], this.p1[0], this.p2[0], this.p3[0], this.p4[0], this.p5[0], this.p6[0], this.p7[0]); 123 this.objectSpaceMax[1] = Math.max(this.p0[1], this.p1[1], this.p2[1], this.p3[1], this.p4[1], this.p5[1], this.p6[1], this.p7[1]); 124 this.objectSpaceMax[2] = Math.max(this.p0[2], this.p1[2], this.p2[2], this.p3[2], this.p4[2], this.p5[2], this.p6[2], this.p7[2]); 125 126 // calculate transformed box coordinates 127 var p0 = V3.transform(this.p0, this.transform); 128 var p1 = V3.transform(this.p1, this.transform); 129 var p2 = V3.transform(this.p2, this.transform); 130 var p3 = V3.transform(this.p3, this.transform); 131 var p4 = V3.transform(this.p4, this.transform); 132 var p5 = V3.transform(this.p5, this.transform); 133 var p6 = V3.transform(this.p6, this.transform); 134 var p7 = V3.transform(this.p7, this.transform); 135 136 // calculate the minimum of the transformed box 137 this.min[0] = Math.min(p0[0], p1[0], p2[0], p3[0], p4[0], p5[0], p6[0], p7[0]); 138 this.min[1] = Math.min(p0[1], p1[1], p2[1], p3[1], p4[1], p5[1], p6[1], p7[1]); 139 this.min[2] = Math.min(p0[2], p1[2], p2[2], p3[2], p4[2], p5[2], p6[2], p7[2]); 140 141 // calculate maximum of the transformed box 142 this.max[0] = Math.max(p0[0], p1[0], p2[0], p3[0], p4[0], p5[0], p6[0], p7[0]); 143 this.max[1] = Math.max(p0[1], p1[1], p2[1], p3[1], p4[1], p5[1], p6[1], p7[1]); 144 this.max[2] = Math.max(p0[2], p1[2], p2[2], p3[2], p4[2], p5[2], p6[2], p7[2]); 145 146 // center 147 this.center = V3.add(this.min, this.max); 148 this.center = V3.scale(this.center, 0.5); 149 150 // radius 151 V3.sub(this.max, this.min, AABB.tmpVec); 152 this.radius = V3.length(AABB.tmpVec) / 2.0; 153 }; 154 155 156 /** 157 * returns the distance from minPos to maxPos in projected space 158 */ 159 AABB.prototype.getOnScreenSize = function(sceneNode, camera){ 160 var world = sceneNode.globalTransformation; 161 var view = camera.viewMatrix; 162 var proj = camera.projectionMatrix; 163 164 var worldViewProj = M4x4.mul(proj, M4x4.mul(view, world)); 165 var min = V3.transform(this.min, worldViewProj); 166 var max = V3.transform(this.max, worldViewProj); 167 var diff = V3.sub(min, max); 168 var length = V3.length(diff); 169 170 return length; 171 172 }; 173 174 /** 175 * 176 * @param {[r,g,b,a]} color each value must be between 0 and 1 177 */ 178 AABB.prototype.setColor = function(color){ 179 this.color = color; 180 }; 181 182 AABB.prototype.render = function(sceneNode, camera){ 183 this.material.setColor(this.color); 184 this.material.render(this, sceneNode, camera); 185 }; 186 187 /** 188 * returns the positive coordinate of the transformed bounding box. 189 * 190 * @see http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ 191 * @param normal 192 */ 193 AABB.prototype.getPositive = function getPositive(normal){ 194 var min = this.min; 195 var max = this.max; 196 var p = [min[0], min[1], min[2]]; 197 if (normal[0] >= 0){ 198 p[0] = max[0]; 199 } 200 if (normal[1] >=0){ 201 p[1] = max[1]; 202 } 203 if (normal[2] >= 0){ 204 p[2] = max[2]; 205 } 206 207 return p; 208 }; 209 210 /** 211 * returns the negative coordinate of the transformed bounding box. 212 * 213 * @see http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ 214 * @param normal 215 */ 216 AABB.prototype.getNegative = function(normal){ 217 var min = this.min; 218 var max = this.max;; 219 var p = [max[0], max[1], max[2]]; 220 if (normal[0] >= 0){ 221 p[0] = min[0]; 222 } 223 if (normal[1] >=0){ 224 p[1] = min[1]; 225 } 226 if (normal[2] >= 0){ 227 p[2] = min[2]; 228 } 229 230 return p; 231 }; 232