-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPolygon.cpp
80 lines (66 loc) · 1.94 KB
/
Polygon.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
#include "Polygon.h"
#include "Shape.h"
#include "Ray.h"
#include "Material.h"
#include <memory>
#include "Vector3.h"
#include <vector>
#include "Vector2.h"
#include <algorithm>
Polygon::Polygon(const std::vector<Vector3> &_vertex,const Material &_material,const DynamicVector3Type &_animation)
:vertex(_vertex),material(_material),animation(_animation){}
Polygon::Polygon(const Polygon &_orig)
:material(_orig.getMaterial()),animation(_orig.getAnimation()){
for(int i=0;i<_orig.getVertexNum();i++)
vertex.push_back(_orig.getVertex(i));
}
void Polygon::setVertex(int i,const Vector3 &_vertex){
vertex[i]=_vertex;
}
Vector3 Polygon::getVertex(int i)const{
return vertex[i];
}
int Polygon::getVertexNum()const{
return vertex.size();
}
void Polygon::setMaterial(const Material &_material){
material=_material;
}
Material Polygon::getMaterial()const{
return material;
}
void Polygon::setAnimation(const DynamicVector3Type &_animation){
animation=_animation;
}
DynamicVector3Type Polygon::getAnimation()const{
return animation;
}
void Polygon::addVertex(const Vector3 &_vertex){
vertex.push_back(_vertex);
}
bool Polygon::hit(const Ray &r,double tmax,double time,HitRecord &record)const{
std::vector<Vector3> _vertex;
for(auto it=vertex.begin();it!=vertex.end();++it)
_vertex.push_back(animation(*it,time));
Vector3 n=cross(_vertex[1]-_vertex[0],_vertex[2]-_vertex[1]);
double t=(dot(n,vertex[vertex.size()-1])-dot(n,r.getOrigin()))/dot(n,r.getDirection());
if((t<=0.0f)||(t>tmax))
return false;
Vector3 hit=r.pointAt(t);
double theta=0.0f;
for(int i=0;i<_vertex.size();i++){
Vector3 e1=_vertex[i]-hit;
Vector3 e2=_vertex[(i+1)%_vertex.size()]-hit;
double cos0=dot(e1,e2)/(e1.length()*e2.length());
theta+=acos(cos0);
}
if(fabs(theta-2.0f*M_PI)<EPSILON){
record.t=t;
record.hitpoint=hit;
record.material=std::make_shared<Material>(material);
record.UVcoord=Vector2(0,0);
record.normal=normalize(n);
return true;
}
return false;
}