-
Notifications
You must be signed in to change notification settings - Fork 0
/
3DElement.h
246 lines (212 loc) · 6.12 KB
/
3DElement.h
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#pragma once
#include "rely.h"
#define MY_OBJECT_SPHERE 0x1
#define MY_OBJECT_CUBE 0x2
#define MY_OBJECT_MODEL 0x3
#define MY_OBJECT_PLANE 0x4
#define MY_OBJECT_BALLPLANE 0x5
const char MY_OBJECT_NAME[][10] =
{ "ERROR","sphere","cube","model","plane","ballplane" };
#define MY_LIGHT_PARALLEL 0x1
#define MY_LIGHT_POINT 0x2
#define MY_LIGHT_SPOT 0x3
const char MY_LIGHT_NAME[][10] =
{ "ERROR","parallel","point","spot" };
#define MY_MODEL_AMBIENT 0x1
#define MY_MODEL_DIFFUSE 0x2
#define MY_MODEL_SPECULAR 0x4
#define MY_MODEL_SHINESS 0x8
#define MY_MODEL_EMISSION 0x10
#define MY_MODEL_POSITION 0x100
#define MY_MODEL_ATTENUATION 0x200
#define MY_RAY_BASERAY 0x1
#define MY_RAY_SHADOWRAY 0x2
#define MY_RAY_REFLECTRAY 0x3
#define MY_RAY_REFRACTRAY 0x4
class Coord2D
{
public:
float u, v;
Coord2D() { u = v = 0.0; };
Coord2D(const float &iu, const float &iv) :u(iu), v(iv) { };
Coord2D operator+(const Coord2D &c) const;
Coord2D operator*(const float &n) const;
operator float*() { return &u; };
};
_MM_ALIGN16 class Vertex
{
public:
union
{
__m128 dat;
struct
{
float x, y, z, w;
};
struct
{
float r, g, b, alpha;
};
};
Vertex();
Vertex(const __m128 &idat);
Vertex(const float ix, const float iy, const float iz, const float ia = 0) :x(ix), y(iy), z(iz), w(ia) { };
operator float*() { return &x; };
operator __m128() const { return dat; };
float length() const;
float length_sqr() const;
Vertex muladd(const float &n, const Vertex &v) const;
Vertex mixmul(const Vertex &v) const;
Vertex operator+(const Vertex &v) const;
Vertex &operator+=(const Vertex &right);
Vertex operator-(const Vertex &v) const;
Vertex &operator-=(const Vertex &right);
Vertex operator/(const float &n) const;
Vertex &operator/=(const float &right);
Vertex operator*(const float &n) const;
Vertex &operator*=(const float &right);
Vertex operator*(const Vertex &v) const;
float operator&(const Vertex &v) const;//点积
};
class Normal : public Vertex
{
public:
Normal() : Vertex() { };
Normal(const float &ix, const float &iy, const float &iz, const float &iw = 0.0f) :Vertex(ix, iy, iz, iw) { };
Normal(const Vertex &v);//归一化
};
class Texture
{
public:
string name;
int16_t w, h;
uint8_t *data = nullptr;
Texture(bool check = false);
Texture(const string &iname, const int16_t iw, const int16_t ih, const uint8_t *img);
~Texture();
Texture(const Texture& t);
Texture(Texture &&t);
Texture &operator=(const Texture &t);
};
class Material
{
public:
Vertex ambient,
diffuse,
specular,
emission;
float shiness, reflect, refract, rfr;//高光权重,反射比率,折射比率,折射率
string name;
Material();
~Material();
void SetMtl(const uint8_t prop, const float r, const float g, const float b, const float a = 1.0f);
void SetMtl(const uint8_t prop, const Vertex &v);
void SetMtl(const uint8_t prop, const float val);
};
_MM_ALIGN16 struct clTri
{
Vertex axisu, axisv, p0;
int16_t numa, numb;
clTri(const Vertex &u = Vertex(), const Vertex &v = Vertex(), const Vertex &p = Vertex()) :axisu(u), axisv(v), p0(p) { };
};
class Triangle
{
public:
Vertex points[3];
Normal norms[3];
Coord2D tcoords[3];
Triangle();
Triangle(const Vertex &va, const Vertex &vb, const Vertex &vc);
Triangle(const Vertex &va, const Normal &na, const Vertex &vb, const Normal &nb, const Vertex &vc, const Normal &nc);
Triangle(const Vertex &va, const Normal &na, const Coord2D &ta, const Vertex &vb, const Normal &nb, const Coord2D &tb, const Vertex &vc, const Normal &nc, const Coord2D &tc);
};
class Color : public Vertex
{
public:
Color(const bool white = false);
Color(const float &ix, const float &iy, const float &iz) :Vertex(ix, iy, iz, 1e20f) { };
Color(const Vertex &v);
Color(const Normal &n);
Color(const Texture* tex, const Coord2D &coord);
void set(const float depth, const float mindepth, const float maxdepth);
void put(uint8_t *addr);
void get(uint8_t *addr);
};
class Ray
{
public:
Vertex origin;
Normal direction;
float mtlrfr = 1.0f;
uint8_t type, isInside = 0x0;
Ray(const Vertex &o, const Normal &dir, const uint8_t type = 0x0) : origin(o), direction(dir), type(type) { };
};
class HitRes
{
public:
Vertex position;
Normal normal;
Coord2D tcoord;
Material *mtl = nullptr;
Texture *tex = nullptr;
intptr_t obj = (intptr_t)this;
float distance, rfr = 1.0f;
uint8_t isInside = 0x0;
HitRes(bool b = false);
HitRes(float dis) : distance(dis){ };
bool operator<(const HitRes &right);
operator bool();
};
class DrawObject
{
protected:
GLuint GLListNum;
public:
Vertex position;
Material mtl;
uint8_t type;
bool bShow = true;
DrawObject(GLuint n) : GLListNum(n) { };
virtual ~DrawObject() { };
virtual void SetMtl(const Material &mtl) { this->mtl = mtl; };
void GLDraw();
virtual void GLPrepare() = 0;
virtual void RTPrepare() { };
virtual HitRes intersect(const Ray &ray, const HitRes &hr, const float min = 0) = 0;
};
class Light
{
public:
Vertex position,
ambient,
diffuse,
specular,
attenuation;
float rangy, rangz, rdis,
angy, angz, dis;
float coang, exponent;//for spot light
uint8_t type;
bool bLight;
Light(const uint8_t type);
bool turn();
void move(const float dangy, const float dangz, const float ddis);
void SetProperty(const int16_t prop, const float r, const float g, const float b, const float a = 1.0f);
void SetLumi(const float lum);
};
class Camera
{
public:
Normal u, v, n;//to right,up,toward
Vertex position;
GLint width, height;
float fovy, aspect, zNear, zFar;
Camera(GLint w = 1120, GLint h = 630);
void move(const float &x, const float &y, const float &z);
void yaw(const float angz);
void pitch(float angy);
void resize(GLint w, GLint h);
};
void Coord_sph2car(float &angy, float &angz, const float dis, Vertex &v);
void Coord_sph2car2(float &angy, float &angz, const float dis, Vertex &v);
void Coord_car2sph(const Vertex &v, float &angy, float &angz, float &dis);
float mod(const float &l, const float &r);