1/** 2 * @author mr.doob / http://mrdoob.com/ 3 */ 4 5THREE.ReusableRay = function () { 6 7 this.precision = 0.0001; 8 9 this.vectorPool = { 10 11 a: new THREE.Vector3(), 12 b: new THREE.Vector3(), 13 c: new THREE.Vector3(), 14 d: new THREE.Vector3(), 15 16 originCopy: new THREE.Vector3(), 17 directionCopy: new THREE.Vector3(), 18 19 vector: new THREE.Vector3(), 20 normal: new THREE.Vector3(), 21 intersectPoint: new THREE.Vector3(), 22 23 v0: new THREE.Vector3(), 24 v1: new THREE.Vector3(), 25 v2: new THREE.Vector3() 26 27 }; 28 29}; 30 31THREE.ReusableRay.prototype = { 32 33 distanceFromIntersection: function (origin, direction, position) { 34 35 var dot, intersect, distance, 36 vp = this.vectorPool, 37 v0 = vp.v0, 38 v1 = vp.v1, 39 v2 = vp.v2; 40 41 v0.sub(position, origin); 42 dot = v0.dot(direction); 43 44 intersect = v1.add(origin, v2.copy(direction).multiplyScalar(dot)); 45 distance = position.distanceTo(intersect); 46 47 return distance; 48 49 }, 50 51 intersectMesh: function (object, parent) { 52 53 var distance, intersect, intersects = [], 54 vp = this.vectorPool, 55 originCopy = vp.originCopy, 56 directionCopy = vp.directionCopy, 57 vector = vp.vector, 58 normal = vp.normal, 59 intersectPoint = vp.intersectPoint, 60 a = vp.a, 61 b = vp.b, 62 c = vp.c, 63 d = vp.d; 64 65 // Checking boundingSphere 66 67 distance = this.distanceFromIntersection(this.origin, this.direction, object.matrixWorld.getPosition()); 68 var scale = THREE.Frustum.__v1.set(object.matrixWorld.getColumnX().length(), object.matrixWorld.getColumnY().length(), object.matrixWorld.getColumnZ().length()); 69 70 if (distance > object.geometry.boundingSphere.radius * Math.max(scale.x, Math.max(scale.y, scale.z))) { 71 72 return intersects; 73 74 } 75 76 // Checking faces 77 78 var f, fl, face, dot, scalar, 79 geometry = object.geometry, 80 vertices = geometry.vertices, 81 objMatrix; 82 83 object.matrixRotationWorld.extractRotation(object.matrixWorld); 84 85 for (f = 0, fl = geometry.faces.length; f < fl; f++) { 86 87 face = geometry.faces[ f ]; 88 89 originCopy.copy(this.origin); 90 directionCopy.copy(this.direction); 91 92 objMatrix = object.matrixWorld; 93 94 // determine if ray intersects the plane of the face 95 // note: this works regardless of the direction of the face normal 96 97 vector = objMatrix.multiplyVector3(vector.copy(face.centroid)).subSelf(originCopy); 98 normal = object.matrixRotationWorld.multiplyVector3(normal.copy(face.normal)); 99 dot = directionCopy.dot(normal); 100 101 // bail if ray and plane are parallel 102 103 if (Math.abs(dot) < this.precision) continue; 104 105 // calc distance to plane 106 107 scalar = normal.dot(vector) / dot; 108 109 // if negative distance, then plane is behind ray 110 111 if (scalar < 0) continue; 112 113 if (object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 )) { 114 115 intersectPoint.add(originCopy, directionCopy.multiplyScalar(scalar)); 116 117 if (face instanceof THREE.Face3) { 118 119 a = objMatrix.multiplyVector3(a.copy(vertices[ face.a ])); 120 b = objMatrix.multiplyVector3(b.copy(vertices[ face.b ])); 121 c = objMatrix.multiplyVector3(c.copy(vertices[ face.c ])); 122 123 if (this.pointInFace3(intersectPoint, a, b, c)) { 124 125 intersect = { 126 127 distance: originCopy.distanceTo(intersectPoint), 128 point: intersectPoint.clone(), 129 face: face, 130 object: object, 131 parent: parent 132 133 }; 134 135 intersects.push(intersect); 136 137 } 138 139 } else if (face instanceof THREE.Face4) { 140 141 a = objMatrix.multiplyVector3(a.copy(vertices[ face.a ])); 142 b = objMatrix.multiplyVector3(b.copy(vertices[ face.b ])); 143 c = objMatrix.multiplyVector3(c.copy(vertices[ face.c ])); 144 d = objMatrix.multiplyVector3(d.copy(vertices[ face.d ])); 145 146 if (this.pointInFace3(intersectPoint, a, b, d) || this.pointInFace3(intersectPoint, b, c, d)) { 147 148 intersect = { 149 150 distance: originCopy.distanceTo(intersectPoint), 151 point: intersectPoint.clone(), 152 face: face, 153 object: object, 154 parent: parent 155 156 }; 157 158 intersects.push(intersect); 159 160 } 161 162 } 163 164 } 165 166 } 167 168 return intersects; 169 }, 170 171 intersectObject: function (object) { 172 173 var distance, intersect, intersects = []; 174 175 if (object instanceof THREE.Particle) { 176 177 distance = this.distanceFromIntersection(this.origin, this.direction, object.matrixWorld.getPosition()); 178 179 if (distance > object.scale.x) { 180 181 return intersects; 182 183 } 184 185 intersect = { 186 187 distance: distance, 188 point: object.position, 189 face: null, 190 object: object 191 192 }; 193 194 intersects.push(intersect); 195 196 } else if (object instanceof THREE.Mesh) { 197 198 intersects = this.intersectMesh(object); 199 200 } else if (object instanceof THREE.Object3D && object.children) { 201 202 for (var i = 0, m = object.children.length; i < m; i++) {
203 // do not do uncontrolled recursion, just do first level child meshes. 204 var obj = object.children[i]; 205 if (obj instanceof THREE.Mesh) { 206 Array.prototype.push.apply(intersects, this.intersectMesh(obj, object)); 207 } 208 209 } 210 211 } 212 213 return intersects; 214 215 }, 216 217 intersectObjects: function (objects) { 218 219 var intersects = []; 220 221 for (var i = 0, l = objects.length; i < l; i++) { 222 223 Array.prototype.push.apply(intersects, this.intersectObject(objects[ i ])); 224 225 } 226 227 intersects.sort(function (a, b) { 228 return a.distance - b.distance; 229 }); 230 231 return intersects; 232 233 }, 234 235 // http://www.blackpawn.com/texts/pointinpoly/default.html 236 pointInFace3: function (p, a, b, c) { 237 238 var dot00, dot01, dot02, dot11, dot12, invDenom, u, v, 239 vp = this.vectorPool, 240 v0 = vp.v0, 241 v1 = vp.v1, 242 v2 = vp.v2; 243 244 v0.sub(c, a); 245 v1.sub(b, a); 246 v2.sub(p, a); 247 248 dot00 = v0.dot(v0); 249 dot01 = v0.dot(v1); 250 dot02 = v0.dot(v2); 251 dot11 = v1.dot(v1); 252 dot12 = v1.dot(v2); 253 254 invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 ); 255 u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; 256 v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; 257 258 return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 ); 259 260 }, 261 262 setPrecision: function (value) { 263 this.precision = value; 264 }, 265 266 setSource: function (origin, direction) { 267 this.origin = origin; 268 this.direction = direction; 269 } 270 271};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.