forked from freme/raybeam
-
Notifications
You must be signed in to change notification settings - Fork 0
/
uvsphere.cc
75 lines (57 loc) · 2.12 KB
/
uvsphere.cc
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
// uvsphere.cc
#include "uvsphere.h"
UVSphere::UVSphere(const Vector3& _center, float _radius, Texture* _tex)
: center(_center), radius(_radius), tex(_tex) {}
bool UVSphere::hit(const Ray& r, float tmin, float tmax, float time, HitRecord& record)const {
Vector3 temp = r.origin() - center;
double a = dot(r.direction(), r.direction());
double b = 2*dot( r.direction(), temp);
double c = dot(temp, temp) - radius*radius;
double discriminant = b*b - 4.0*a*c;
// first check to see if ray intersects sphere
if ( discriminant > 0.0 ) {
discriminant = sqrt(discriminant);
double t = (-b -discriminant) /(2.0*a);
//now check for valid interval
if(t < tmin)
t = ( - b + discriminant) / (2.0*a);
if(t < tmin || t > tmax)
return false;
//we have a valid hit
record.t = t;
record.hit_p = (r.origin() + t* r.direction());
Vector3 n = record.normal = (record.hit_p - center) / radius;
//calculate UV coordinates
float twopi = 2*M_PI;
float theta = acos( n.y());
float phi = atan2(n.x(), n.z())+M_PI;
if(phi < 0.0f )
phi += twopi;
float one_over_2pi = 1/twopi;
float one_over_pi = 1/M_PI;
record.uv = Vector2(phi*one_over_2pi, (M_PI - theta) * one_over_pi);
record.hit_tex = tex;
return true;
}
return false;
}
bool UVSphere::shadowHit(const Ray& r, float tmin, float tmax, float time)const {
Vector3 temp = r.origin() - center;
double a = dot(r.direction(), r.direction());
double b = 2*dot( r.direction(), temp);
double c = dot(temp, temp) - radius*radius;
double discriminant = b*b - 4.0*a*c;
// first check to see if ray intersects sphere
if ( discriminant > 0.0 ) {
discriminant = sqrt(discriminant);
double t = (-b -discriminant) /(2.0*a);
//now check for valid interval
if(t < tmin)
t = ( - b + discriminant) / (2.0*a);
if(t < tmin || t > tmax)
return false;
// valid hit
return true;
}
return false;
}