/
prSphere.cpp
96 lines (86 loc) · 2.32 KB
/
prSphere.cpp
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "prSphere.h"
prSphere::prSphere(const vec3 center, real radius, const shBase* MatFront, const shBase* MatBack)
: mCenter (center)
, mNorth (0.0, -1.0, 0.0)
, mEquador (0.0, 0.0, 1.0)
, mRadius (radius)
, mMaterialFront(MatFront)
, mMaterialBack (MatBack?MatBack:MatFront)
, mNcrossE (mNorth.cross(mEquador))
, mSqrRadius (Square(mRadius))
{
}
bool
prSphere::Hits(const Ray &r) const
{
const vec3 vec = r.pos-mCenter;
const real b = -vec.dot(r.dir);
real det = Square(b) - r.dir.dot(r.dir) * vec.sqr_length() + mSqrRadius;
if (det > real(0)) {
det = det.Sqrt();
const real
i1 = b - det,
i2 = b + det;
if (i2 > r.minDist) {
if (mMaterialFront && i1 < r.dist && i1 > r.minDist) {
return true;
} else if (mMaterialBack && i2 < r.dist) {
return true;
}
}
}
return false;
}
void
prSphere::Intersect(Ray &r) const
{
const vec3 vec = r.pos-mCenter;
const real b = -vec.dot(r.dir);
real det = Square(b) - r.dir.dot(r.dir) * vec.sqr_length() + mSqrRadius;
if (det > real(0)) {
det = det.Sqrt();
const real i1 = b - det;
const real i2 = b + det;
if (i2 > r.minDist) {
if (mMaterialFront && i1 < r.dist && i1 > r.minDist) {
//outside
r.gState.object = this;
r.dist = i1;
} else if (mMaterialBack && i2 < r.dist) {
//inside
r.gState.object = this;
r.dist = i2;
}
return;
}
}
}
void
prSphere::Shade(Ray &r, rgba* result) const
{
r.gState.faceId = 0;
r.UpdatePoint();
//normal
r.gState.normal = (r.gState.point - mCenter) / mRadius;
r.UpdateNormal();
//texture
r.gState.textureUV.y = (-r.gState.normal.dot(mNorth)).ACos();
r.gState.textureUV.x = (r.gState.normal.dot(mEquador) / r.gState.textureUV.y.Sin()).ACos() * (real(1.0)/(cMath::PI*real(2.0)));
//if (mNcrossE.dot(r.gState.normal) < real(0)) {
// r.gState.textureUV.x = real(1.0) - r.gState.textureUV.x;
//}
r.gState.textureUV.y /= cMath::PI;
//partials
//r.gState.partialU = mNorth;
//r.gState.partialV = mNorth.cross(r.gState.normal);
//material
(r.gState.inside ? mMaterialBack : mMaterialFront)->Shade(r, result);
}
// bool prSphere::TestPoint(vec3 &p) {
// return mCenter.sqr_distance(p) <= mSqrRadius;
// }
aabb
prSphere::GetAabb() const
{
return aabb(mCenter-mRadius, mCenter+mRadius);
}