73 /** |
74 /** |
74 * a camera |
75 * a camera |
75 */ |
76 */ |
76 class Camera |
77 class Camera |
77 { |
78 { |
78 public: |
|
79 Vector eye, p, u, v; |
79 Vector eye, p, u, v; |
80 Float F; |
80 Float F; |
81 |
81 public: |
82 Camera(): eye(0,0,10), p(0,0,-1), u(-1,0,0), v(0,1,0), F(2.*tan(M_PI/8.)) {}; |
82 Camera(): eye(0,0,10), p(0,0,-1), u(-1,0,0), v(0,1,0), F(2.*tan(M_PI/8.)) {}; |
83 Camera(const Vector &C, const Vector &ap, const Vector &au, const Vector &av): |
83 Camera(const Vector &C, const Vector &ap, const Vector &au, const Vector &av): |
84 eye(C), p(ap), u(au), v(av), F(2.*tan(M_PI/8.)) {}; |
84 eye(C), p(ap), u(au), v(av), F(2.*tan(M_PI/8.)) {}; |
85 Camera(const Vector &from, const Vector &lookat, const Vector &up): |
85 Camera(const Vector &from, const Vector &lookat, const Vector &up): |
86 eye(from), F(2.*tan(M_PI/8.)) |
86 eye(from), F(2.*tan(M_PI/8.)) |
87 { |
87 { |
88 p = lookat - from; u = cross(up, p); |
88 p = lookat - from; u = cross(up, p); |
89 p.normalize(); u.normalize(); |
89 p.normalize(); u.normalize(); |
90 v = cross(p, u); |
90 v = cross(p, u); |
91 }; |
91 }; |
|
92 |
|
93 const Vector &getEye() const { return eye; }; |
|
94 const Vector &getp() const { return p; }; |
|
95 const Vector &getu() const { return u; }; |
|
96 const Vector &getv() const { return v; }; |
|
97 const Float &getF() const { return F; }; |
92 void setEye(const Vector &aeye) { eye = aeye; }; |
98 void setEye(const Vector &aeye) { eye = aeye; }; |
93 void setAngle(const Float angle) { F = 2.*tan(angle/2.); }; |
99 void setp(const Vector &ap) { p = ap; }; |
|
100 void setu(const Vector &au) { u = au; }; |
|
101 void setv(const Vector &av) { v = av; }; |
|
102 void setF(const Float &aF) { F = aF; }; |
|
103 void setAngle(const Float angle) { F = 2.0f*tan(angle/2.0f); }; |
94 void rotate(const Quaternion &q); |
104 void rotate(const Quaternion &q); |
95 void move(const Float fw, const Float left, const Float up); |
105 void move(const Float fw, const Float left, const Float up); |
96 |
106 |
97 Ray makeRay(Sample &samp) |
107 const Ray makeRay(const Sample &samp) const |
98 { |
108 { |
99 Vector dir = p - (u*samp.x + v*samp.y)*F; |
109 Vector dir = normalize(p - (u*samp.x + v*samp.y)*F); |
100 dir.normalize(); |
|
101 return Ray(eye, dir); |
110 return Ray(eye, dir); |
102 }; |
111 }; |
103 |
112 |
104 #ifndef NO_SSE |
113 #ifndef NO_SIMD |
105 void makeRayPacket(Sample *samples, RayPacket &rays) |
114 void makeRayPacket(const Sample *samples, RayPacket &rays) const |
106 { |
115 { |
107 __m128 m1x,m1y,m1z; |
116 mfloat4 m1x,m1y,m1z; |
108 __m128 m2x,m2y,m2z; |
117 mfloat4 m2x,m2y,m2z; |
109 __m128 m; |
118 mfloat4 m; |
110 |
119 |
111 // m1(xyz) = u * samples[i].x |
120 // m1(xyz) = u * samples[i].x |
112 m1x = _mm_set_ps1(u.x); |
121 m1x = mset1(u.x); |
113 m1y = _mm_set_ps1(u.y); |
122 m1y = mset1(u.y); |
114 m1z = _mm_set_ps1(u.z); |
123 m1z = mset1(u.z); |
115 m = _mm_set_ps(samples[3].x, samples[2].x, samples[1].x, samples[0].x); |
124 m = mset(samples[3].x, samples[2].x, samples[1].x, samples[0].x); |
116 m1x = _mm_mul_ps(m1x, m); |
125 m1x = mmul(m1x, m); |
117 m1y = _mm_mul_ps(m1y, m); |
126 m1y = mmul(m1y, m); |
118 m1z = _mm_mul_ps(m1z, m); |
127 m1z = mmul(m1z, m); |
119 |
128 |
120 // m2(xyz) = v * samples[i].y |
129 // m2(xyz) = v * samples[i].y |
121 m2x = _mm_set_ps1(v.x); |
130 m2x = mset1(v.x); |
122 m2y = _mm_set_ps1(v.y); |
131 m2y = mset1(v.y); |
123 m2z = _mm_set_ps1(v.z); |
132 m2z = mset1(v.z); |
124 m = _mm_set_ps(samples[3].y, samples[2].y, samples[1].y, samples[0].y); |
133 m = mset(samples[3].y, samples[2].y, samples[1].y, samples[0].y); |
125 m2x = _mm_mul_ps(m2x, m); |
134 m2x = mmul(m2x, m); |
126 m2y = _mm_mul_ps(m2y, m); |
135 m2y = mmul(m2y, m); |
127 m2z = _mm_mul_ps(m2z, m); |
136 m2z = mmul(m2z, m); |
128 |
137 |
129 // m1(xyz) = (m1 + m2) = (u*samples[i].x + v*samples[i].y) |
138 // m1(xyz) = (m1 + m2) = (u*samples[i].x + v*samples[i].y) |
130 m1x = _mm_add_ps(m1x, m2x); |
139 m1x = madd(m1x, m2x); |
131 m1y = _mm_add_ps(m1y, m2y); |
140 m1y = madd(m1y, m2y); |
132 m1z = _mm_add_ps(m1z, m2z); |
141 m1z = madd(m1z, m2z); |
133 |
142 |
134 // m1(xyz) = m1*F = (u*samples[i].x + v*samples[i].y)*F |
143 // m1(xyz) = m1*F = (u*samples[i].x + v*samples[i].y)*F |
135 m = _mm_set_ps1(F); |
144 m = mset1(F); |
136 m1x = _mm_mul_ps(m1x, m); |
145 m1x = mmul(m1x, m); |
137 m1y = _mm_mul_ps(m1y, m); |
146 m1y = mmul(m1y, m); |
138 m1z = _mm_mul_ps(m1z, m); |
147 m1z = mmul(m1z, m); |
139 |
148 |
140 // m1(xyz) = p - m1 = p - (u*samples[i].x + v*samples[i].y)*F = dir |
149 // m1(xyz) = p - m1 = p - (u*samples[i].x + v*samples[i].y)*F = dir |
141 m2x = _mm_set_ps1(p.x); |
150 m2x = mset1(p.x); |
142 m2y = _mm_set_ps1(p.y); |
151 m2y = mset1(p.y); |
143 m2z = _mm_set_ps1(p.z); |
152 m2z = mset1(p.z); |
144 rays.dir.mx = _mm_sub_ps(m2x, m1x); |
153 rays.dir.mx = msub(m2x, m1x); |
145 rays.dir.my = _mm_sub_ps(m2y, m1y); |
154 rays.dir.my = msub(m2y, m1y); |
146 rays.dir.mz = _mm_sub_ps(m2z, m1z); |
155 rays.dir.mz = msub(m2z, m1z); |
147 |
156 |
148 // copy origin |
157 // copy origin |
149 rays.o.mx = _mm_set_ps1(eye.x); |
158 rays.o.mx = mset1(eye.x); |
150 rays.o.my = _mm_set_ps1(eye.y); |
159 rays.o.my = mset1(eye.y); |
151 rays.o.mz = _mm_set_ps1(eye.z); |
160 rays.o.mz = mset1(eye.z); |
152 |
161 |
153 rays.dir.normalize(); |
162 rays.dir.normalize(); |
|
163 rays.invdir = mOne/rays.dir; |
154 }; |
164 }; |
155 #endif |
165 #endif |
156 }; |
166 }; |
157 |
167 |
158 /** |
168 /** |