PageSourceSearch

https://jensarps.github.io/Ascent/lib/three/ReusableRay.js

js jensarps.github.io collected 2026-10-03 09:22:58 UTC 6,512 bytes, 271 lines download raw bytes

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.