-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathObject.cpp
152 lines (136 loc) · 6.65 KB
/
Object.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//
// Object.cpp
// PI_shadow_mirror
//
// Created by ललित सिंह on 30/11/2016.
// Copyright © 2016 ललित सिंह. All rights reserved.
//
#include "Object.hpp"
Sphere::Sphere(){
this->center = mypoint3f();
this->radius = 0;
}
Sphere::Sphere(double radius, mypoint3f center1){
this->center = center1;
this->radius = radius;
}
TriangularMesh::TriangularMesh(){
std::vector <glm::vec3> vertices;
std::vector <glm::vec2> uvs;
std::vector <glm::vec3> normals;
loadOBJ2("bunny.obj", vertices, normals);
double theta = M_PI * 90/180;
rotateOBJ( vertices, normals, theta);
std::vector<std::vector<mypoint3f>> triangularMesh = fitObjectInFrustum(vertices,normals);
this->vertices = triangularMesh[0];
this-> normals = triangularMesh[1];
}
mypoint3f Sphere::getCenter(){
return this->center;
}
intersectionPoint Sphere::shootRay(Line L){
mypoint3f currentPixelPoint = L.getEndPoint();
mypoint3f viewPoint = L.getStartPoint();
mypoint3f pixelPointMinusViewPoint = currentPixelPoint - viewPoint;
// Formula:(X,Y,Z) = currentPixelPoint(i,j,k) - viewpoint(Vx,Vy,Vz)
double sumOfSquaresOfViewPoint = viewPoint.sumOfSquaresOfXYZ();
//(Vx^2+Vy^2+Vz^2) where(VX, Vy, Vz) are the co-ordinates of viewpoint
double sumSquaresOfXYZ = pixelPointMinusViewPoint.sumOfSquaresOfXYZ(); //(X^2+Y^2+Z^2)
//(X^2+Y^2+Z^2)
struct mypoint3f viewPointTimesXYZ = pixelPointMinusViewPoint * viewPoint;
//(Vx*X, Vy*Y, Vz*Z)
double sumOfviewPointTimesXYZ = viewPointTimesXYZ.sumXYZ();
//(Vx*X + Vy*Y + Vz*Z)
mypoint3f product = this->center * viewPoint;
double sumOfCenterTimesViewPoint = product.sumXYZ();
//if (h,k,l) is center of circle then above variable represents
// h*Vx + k*Vy + l*Vz
double sumSquaresOfHKL = this->center.sumOfSquaresOfXYZ();
//(h^2+k^2+l^2)
mypoint3f tempProduct = this->center * pixelPointMinusViewPoint;
double sumOfCenterTimesXYZ = tempProduct.sumXYZ();
//(h*X + k*Y + l*Z)
//After deriving the equation for the intersection of sphere and line through the viewpoint and given pixel of the
//screen..... we can represent it in form of [[[a*t^2 +b*t + c = 0]]
//where a, b and c has followint values
// To view the calculation click on the link given below
// https://www.dropbox.com/s/8evzmszo19bfybo/Code_logic.pdf?dl=0
double a = sumSquaresOfXYZ;
double b = 2*(sumOfviewPointTimesXYZ - sumOfCenterTimesXYZ);
double c = sumOfSquaresOfViewPoint -2* sumOfCenterTimesViewPoint + sumSquaresOfHKL - this->radius;
// if the ray intersects the sphere then the discriminant of the equation is positive
//such that we get real point of intersection
double discriminant = sqr(b) - 4 * a * c;
double t1 = NULL, t2 = NULL; // roots of the equation a*t^2 + b*t + c = 0
intersectionPoint myintersectionPoint;
myintersectionPoint.doesIntersect = false;
if ( discriminant> 0 ){
t1 = (-b + sqrt(discriminant))/(2*a);
t2 = (-b - sqrt(discriminant))/(2*a);
//if (t1<=6 || t2<=6){ // t=[0,1] is equivalent to [0,2] because the screen is 2 unit farfrom view point
//Since the viewsight range is maximum up 12 units, the min(t1,t1) should be lesser than 6
// myintersectionPoint.point = pointSum(viewPoint, scalarProduct(pointDifference(currentPixelPoint, viewPoint), min(t1,t2) ));
mypoint3f diff = currentPixelPoint - viewPoint;
double minval = min(t1,t2);
myintersectionPoint.t = minval;
mypoint3f scalarP = minval * diff;
myintersectionPoint.point = viewPoint + scalarP;
// intersection point (x,y,z) = (Vx,Vy,Vz) + t* (pix.x -Vx, pix.y-Vy, pix.z -Vz)
myintersectionPoint.doesIntersect = true;
myintersectionPoint.normal = normalize(myintersectionPoint.point - this->center);
//}
}
return myintersectionPoint;
}
intersectionPoint TriangularMesh::shootRay(Line L){
std::vector<intersectionPoint> intersectedPoints; //this vector records all the t values for each triangular meshes to which the ray intersects
for (int k = 0 ; k < this->vertices.size();k+=3){
Triangle T = Triangle(this->vertices[k], this->vertices[k+1], this->vertices[k+2]);
Triangle NT = Triangle(this->normals[k], this->normals[k+1], this->normals[k+2]); //normals
mypoint3f vp = L.getStartPoint(); // view point
mypoint3f cp = L.getEndPoint(); // current pixel point
Vect N = normal(T); // normal to the plane of the triangle
mypoint3f tp = T.getv1(); // one of the three vertices of triangle or [triangle point]
double tpx = tp.getx(), tpy= tp.gety(), tpz = tp.getz();
double Nx = N.getx(), Ny = N.gety(), Nz = N.getz();
double vpx = vp.getx(), vpy = vp.gety(), vpz = vp.getz(); //viewpoint
double cpx = cp.getx(), cpy = cp.gety(), cpz = cp.getz(); //currentPixelPoint
double num = Nx * (vpx -tpx) + Ny *(vpy-tpy) + Nz *(vpz - tpz);
double den = Nx *(cpx -vpx) + Ny* (cpy-vpy) + Nz *(cpz - vpz);
//std::cout<<"num:"<<num<<" den: "<<den<<std::endl;
intersectionPoint result;
if (den == 0 ){
result.doesIntersect = false;
}
else {
double temp = -num / den;
// std::cout<<"t:"<<t<<std::endl;
mypoint3f intsecPoint = findPointOnLine(temp, L);
//std::cout<<T;
//std::cout<<intsecPoint<<std::endl;
bool var = doesPointLiesInsideTriangle(intsecPoint, T);
result.doesIntersect= var;
if (result.doesIntersect){
result.point =intsecPoint;
result.t = temp;
mypoint3f BC = barycentricCoordinates(intsecPoint, T);
mypoint3f temp1 = mypoint3f( NT.getv1().getx() * BC.getx(), NT.getv1().gety() * BC.getx(), NT.getv1().getz() * BC.getx());
mypoint3f temp2 = mypoint3f( NT.getv2().getx() * BC.gety(), NT.getv2().gety() * BC.gety(), NT.getv2().getz() * BC.gety());
mypoint3f temp3 = mypoint3f( NT.getv3().getx() * BC.getz(), NT.getv3().gety() * BC.getz(), NT.getv3().getz() * BC.getz());
mypoint3f sum = temp1 + temp2;
sum = sum + temp3;
result.normal = normalize( sum );
intersectedPoints.push_back(result);
}
}
}
intersectionPoint intersecPoint;
if(intersectedPoints.size() == 0){
intersecPoint.doesIntersect = false;
}
else{
intersecPoint = closestPoint(intersectedPoints, L);
intersecPoint.doesIntersect = true;
}
return intersecPoint;
}