-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRay.js
executable file
·82 lines (66 loc) · 1.89 KB
/
Ray.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
var Ray = function (origin, endpoint) { return (function (self) {
self.hits = [];
self.nearestHit = null;
self.origin = origin || vec3.create();
self.endpoint = endpoint || vec3.create();
// calculate and normalize direction
self.direction = vec3.create();
if (endpoint && origin) {
vec3.subtract(self.direction, endpoint, origin);
vec3.normalize(self.direction, self.direction);
}
self.addHit = function (h) {
if (h != null) {
if ( !self.nearestHit
// check that t isn't within margin of error
|| ((h.t < self.nearestHit.t) && (h.t > 0.01)) ) {
self.nearestHit = h;
}
self.hits.push(h);
}
}
self.cast = function (geometry, baseShape) {
var hit;
geometry.forEach(function (shape) {
if (!baseShape || shape != baseShape) {
hit = shape.findHit(self);
if (hit) {
self.addHit(hit);
}
}
});
}
self.isShadowCast = function (geometry, surfaceHit, distSquared) {
var h, i, g, shape = surfaceHit.shape;
for (i = 0; i < geometry.length; i++) {
g = geometry[i];
if (g == shape)
continue;
h = g.findHit(self);
if (h != null) {
// check that hit is not behind light
if ((h.distance(self.origin) < distSquared)
&& h.t > 0.01) {
self.hits.push(h);
return true;
}
}
}
return null;
}
self.reflect = function (hit) {
var n = vec3.create(), v = vec3.create();
vec3.copy(n, hit.normal);
vec3.copy(v, self.direction);
vec3.normalize(v, v);
var c = vec3.dot(n, v);
var reflectedDirection = vec3.create();
vec3.scaleAndAdd(reflectedDirection, v, n, -2*c);
var r = Ray();
vec3.copy(r.origin, hit.coord);
vec3.normalize(r.direction, reflectedDirection);
r.reflected = true;
return r;
}
return self;
})(Object.create(null))};