-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSphere.cpp
87 lines (73 loc) · 2.13 KB
/
Sphere.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
#include "Sphere.hpp"
#include "Ray.hpp"
unsigned int Sphere::counter = 0;
Sphere::Sphere(const json& j)
:Object(j)
{
if(!parseVar(j, "radius", radius))
throw std::invalid_argument("no property 'radius' in SPHERE");
if(name.empty())
name = "SPHERE_"+std::to_string(++counter);
setScale(radius, radius, radius);
}
bool Sphere::intersect(const Ray& ray, float &t,
glm::vec3& vNorm, glm::vec2& uv, glm::vec3& hitPoint){
glm::vec3 oc = ray.o - getPosition();
const double b = 2 * glm::dot(oc, ray.d);
const double c = glm::dot(oc, oc) - radius*radius;
double disc = b*b - 4 * c;
if (disc < 1e-4) return false;
disc = sqrt(disc);
const double t0 = -b - disc;
const double t1 = -b + disc;
t = (t0 < t1) ? t0 : t1;
t /= 2.f;
hitPoint = ray.o+t*ray.d;
vNorm = (getPosition()-hitPoint)/radius;
return true;
}
void Sphere::renderGui(){
Object::renderGui();
if(ImGui::InputFloat("radius", &radius)){
setScale(radius, radius, radius);
}
}
SolidSphereData::SolidSphereData(){}
SolidSphereData::SolidSphereData(float radius,
unsigned int rings, unsigned int sectors){
float const R = 1./(float)(rings-1);
float const S = 1./(float)(sectors-1);
unsigned int r, s;
vertices.resize(rings * sectors * 3);
normals.resize(rings * sectors * 3);
texcoords.resize(rings * sectors * 2);
verticesAndNormals.resize(rings * sectors * 6);
std::vector<float>::iterator vn = verticesAndNormals.begin();
float m_pi_2 = 1.570796326;
float m_pi = 3.141592653;
for(r = 0; r < rings; r++){
for(s = 0; s < sectors; s++){
float const y = sin( -m_pi_2 + m_pi * r * R );
float const x = cos(2*m_pi * s * S) * sin( m_pi * r * R );
float const z = sin(2*m_pi * s * S) * sin( m_pi * r * R );
*vn++ = x * radius;
*vn++ = y * radius;
*vn++ = z * radius;
*vn++ = x;
*vn++ = y;
*vn++ = z;
}
}
indices.resize(rings * sectors * 6);
std::vector<ushort>::iterator i = indices.begin();
for(r = 0; r < rings-1; r++){
for(s = 0; s < sectors-1; s++){
*i++ = r * sectors + s;
*i++ = r * sectors + (s+1);
*i++ = (r+1) * sectors + (s+1);
*i++ = r * sectors + s;
*i++ = (r+1) * sectors + (s+1);
*i++ = (r+1) * sectors + s;
}
}
}