53 virtual ~Shape() {}; |
53 virtual ~Shape() {}; |
54 |
54 |
55 // first intersection point |
55 // first intersection point |
56 virtual bool intersect(const Ray &ray, Float &dist) const = 0; |
56 virtual bool intersect(const Ray &ray, Float &dist) const = 0; |
57 |
57 |
|
58 #ifndef NO_SSE |
58 virtual __m128 intersect_packet(const RayPacket &rays, __m128 &dists) |
59 virtual __m128 intersect_packet(const RayPacket &rays, __m128 &dists) |
59 { |
60 { |
60 __m128 results; |
61 __m128 results; |
61 ((int*)&results)[0] = intersect(rays[0], ((float*)&dists)[0]) ? -1 : 0; |
62 ((int*)&results)[0] = intersect(rays[0], ((float*)&dists)[0]) ? -1 : 0; |
62 ((int*)&results)[1] = intersect(rays[1], ((float*)&dists)[1]) ? -1 : 0; |
63 ((int*)&results)[1] = intersect(rays[1], ((float*)&dists)[1]) ? -1 : 0; |
63 ((int*)&results)[2] = intersect(rays[2], ((float*)&dists)[2]) ? -1 : 0; |
64 ((int*)&results)[2] = intersect(rays[2], ((float*)&dists)[2]) ? -1 : 0; |
64 ((int*)&results)[3] = intersect(rays[3], ((float*)&dists)[3]) ? -1 : 0; |
65 ((int*)&results)[3] = intersect(rays[3], ((float*)&dists)[3]) ? -1 : 0; |
65 return results; |
66 return results; |
66 }; |
67 }; |
|
68 #endif |
67 |
69 |
68 // all intersections (only for CSG) |
70 // all intersections (only for CSG) |
69 virtual bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const = 0; |
71 virtual bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const = 0; |
70 |
72 |
71 // intersection with AABB |
73 // intersection with AABB |
72 virtual bool intersect_bbox(const BBox &bbox) const = 0; |
74 virtual bool intersect_bbox(const BBox &bbox) const = 0; |
73 |
75 |
74 // normal at point P |
76 // normal at point P |
75 virtual const Vector3 normal(const Vector3 &P) const = 0; |
77 virtual const Vector normal(const Vector &P) const = 0; |
76 |
78 |
77 virtual BBox get_bbox() const = 0; |
79 virtual BBox get_bbox() const = 0; |
78 |
80 |
79 virtual ostream & dump(ostream &st) const = 0; |
81 virtual ostream & dump(ostream &st) const = 0; |
80 }; |
82 }; |
87 /** |
89 /** |
88 * sphere shape |
90 * sphere shape |
89 */ |
91 */ |
90 class Sphere: public Shape |
92 class Sphere: public Shape |
91 { |
93 { |
92 Vector3 center; |
94 Vector center; |
93 Float radius; |
95 Float radius; |
94 |
96 |
95 Float sqr_radius; |
97 Float sqr_radius; |
96 Float inv_radius; |
98 Float inv_radius; |
97 public: |
99 public: |
98 Sphere(const Vector3 &acenter, const Float aradius, Material *amaterial): |
100 Sphere(const Vector &acenter, const Float aradius, Material *amaterial): |
99 center(acenter), radius(aradius), |
101 center(acenter), radius(aradius), |
100 sqr_radius(aradius*aradius), inv_radius(1.0f/aradius) |
102 sqr_radius(aradius*aradius), inv_radius(1.0f/aradius) |
101 { material = amaterial; } |
103 { material = amaterial; } |
102 bool intersect(const Ray &ray, Float &dist) const; |
104 bool intersect(const Ray &ray, Float &dist) const; |
103 __m128 intersect_packet(const RayPacket &rays, __m128 &dists); |
|
104 bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const; |
105 bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const; |
105 bool intersect_bbox(const BBox &bbox) const; |
106 bool intersect_bbox(const BBox &bbox) const; |
106 const Vector3 normal(const Vector3 &P) const { return (P - center) * inv_radius; }; |
107 const Vector normal(const Vector &P) const { return (P - center) * inv_radius; }; |
107 BBox get_bbox() const; |
108 BBox get_bbox() const; |
108 const Vector3 getCenter() const { return center; }; |
109 const Vector getCenter() const { return center; }; |
109 Float getRadius() const { return radius; }; |
110 Float getRadius() const { return radius; }; |
110 ostream & dump(ostream &st) const; |
111 ostream & dump(ostream &st) const; |
|
112 #ifndef NO_SSE |
|
113 __m128 intersect_packet(const RayPacket &rays, __m128 &dists); |
|
114 #endif |
111 }; |
115 }; |
112 |
116 |
113 /** |
117 /** |
114 * box shape |
118 * box shape |
115 */ |
119 */ |
116 class Box: public Shape |
120 class Box: public Shape |
117 { |
121 { |
118 Vector3 L; |
122 Vector L; |
119 Vector3 H; |
123 Vector H; |
120 public: |
124 public: |
121 Box(const Vector3 &aL, const Vector3 &aH, Material *amaterial): L(aL), H(aH) |
125 Box(const Vector &aL, const Vector &aH, Material *amaterial): L(aL), H(aH) |
122 { |
126 { |
123 for (int i = 0; i < 3; i++) |
127 for (int i = 0; i < 3; i++) |
124 if (L.cell[i] > H.cell[i]) |
128 if (L.cell[i] > H.cell[i]) |
125 swap(L.cell[i], H.cell[i]); |
129 swap(L.cell[i], H.cell[i]); |
126 material = amaterial; |
130 material = amaterial; |
127 }; |
131 }; |
128 bool intersect(const Ray &ray, Float &dist) const; |
132 bool intersect(const Ray &ray, Float &dist) const; |
129 __m128 intersect_packet(const RayPacket &rays, __m128 &dists); |
|
130 bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const { return false; }; |
133 bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const { return false; }; |
131 bool intersect_bbox(const BBox &bbox) const; |
134 bool intersect_bbox(const BBox &bbox) const; |
132 const Vector3 normal(const Vector3 &P) const; |
135 const Vector normal(const Vector &P) const; |
133 BBox get_bbox() const { return BBox(L, H); }; |
136 BBox get_bbox() const { return BBox(L, H); }; |
134 const Vector3 getL() const { return L; }; |
137 const Vector getL() const { return L; }; |
135 const Vector3 getH() const { return H; }; |
138 const Vector getH() const { return H; }; |
136 ostream & dump(ostream &st) const; |
139 ostream & dump(ostream &st) const; |
|
140 #ifndef NO_SSE |
|
141 __m128 intersect_packet(const RayPacket &rays, __m128 &dists); |
|
142 #endif |
137 }; |
143 }; |
138 |
144 |
139 /** |
145 /** |
140 * triangle vertex |
146 * triangle vertex |
141 */ |
147 */ |
142 class Vertex |
148 class Vertex |
143 { |
149 { |
144 public: |
150 public: |
145 Vector3 P; |
151 Vector P; |
146 Vertex(const Vector3 &aP): P(aP) {}; |
152 Vertex(const Vector &aP): P(aP) {}; |
147 virtual ~Vertex() {}; |
153 virtual ~Vertex() {}; |
148 virtual ostream & dump(ostream &st) const; |
154 virtual ostream & dump(ostream &st) const; |
149 }; |
155 }; |
150 |
156 |
151 /** |
157 /** |
152 * triangle vertex with normal |
158 * triangle vertex with normal |
153 */ |
159 */ |
154 class NormalVertex: public Vertex |
160 class NormalVertex: public Vertex |
155 { |
161 { |
156 public: |
162 public: |
157 Vector3 N; |
163 Vector N; |
158 NormalVertex(const NormalVertex *v): Vertex(v->P), N(v->N) {}; |
164 NormalVertex(const NormalVertex *v): Vertex(v->P), N(v->N) {}; |
159 NormalVertex(const Vector3 &aP): Vertex(aP) {}; |
165 NormalVertex(const Vector &aP): Vertex(aP) {}; |
160 NormalVertex(const Vector3 &aP, const Vector3 &aN): Vertex(aP), N(aN) {}; |
166 NormalVertex(const Vector &aP, const Vector &aN): Vertex(aP), N(aN) {}; |
161 const Vector3 &getNormal() { return N; }; |
167 const Vector &getNormal() { return N; }; |
162 void setNormal(const Vector3 &aN) { N = aN; }; |
168 void setNormal(const Vector &aN) { N = aN; }; |
163 ostream & dump(ostream &st) const; |
169 ostream & dump(ostream &st) const; |
164 }; |
170 }; |
165 |
171 |
166 /** |
172 /** |
167 * triangle shape |
173 * triangle shape |
178 int k; // dominant axis |
184 int k; // dominant axis |
179 #endif |
185 #endif |
180 #ifdef TRI_PLUCKER |
186 #ifdef TRI_PLUCKER |
181 Float pla[6], plb[6], plc[6]; |
187 Float pla[6], plb[6], plc[6]; |
182 #endif |
188 #endif |
183 Vector3 N; |
189 Vector N; |
184 const Vector3 smooth_normal(const Vector3 &P) const |
190 const Vector smooth_normal(const Vector &P) const |
185 { |
191 { |
186 #ifdef TRI_BARI_PRE |
192 #ifdef TRI_BARI_PRE |
187 const Vector3 &NA = static_cast<NormalVertex*>(A)->N; |
193 const Vector &NA = static_cast<NormalVertex*>(A)->N; |
188 const Vector3 &NB = static_cast<NormalVertex*>(B)->N; |
194 const Vector &NB = static_cast<NormalVertex*>(B)->N; |
189 const Vector3 &NC = static_cast<NormalVertex*>(C)->N; |
195 const Vector &NC = static_cast<NormalVertex*>(C)->N; |
190 static const int modulo3[5] = {0,1,2,0,1}; |
196 static const int modulo3[5] = {0,1,2,0,1}; |
191 register const int ku = modulo3[k+1]; |
197 register const int ku = modulo3[k+1]; |
192 register const int kv = modulo3[k+2]; |
198 register const int kv = modulo3[k+2]; |
193 const Float pu = P[ku] - A->P[ku]; |
199 const Float pu = P[ku] - A->P[ku]; |
194 const Float pv = P[kv] - A->P[kv]; |
200 const Float pv = P[kv] - A->P[kv]; |
195 const Float u = pv * bnu + pu * bnv; |
201 const Float u = pv * bnu + pu * bnv; |
196 const Float v = pu * cnv + pv * cnu; |
202 const Float v = pu * cnv + pv * cnu; |
197 Vector3 n = NA + u * (NB - NA) + v * (NC - NA); |
203 Vector n = NA + u * (NB - NA) + v * (NC - NA); |
198 n.normalize(); |
204 n.normalize(); |
199 return n; |
205 return n; |
200 #else |
206 #else |
201 return N; // not implemented for other algorithms |
207 return N; // not implemented for other algorithms |
202 #endif |
208 #endif |
205 Vertex *A, *B, *C; |
211 Vertex *A, *B, *C; |
206 |
212 |
207 Triangle() {}; |
213 Triangle() {}; |
208 Triangle(Vertex *aA, Vertex *aB, Vertex *aC, Material *amaterial); |
214 Triangle(Vertex *aA, Vertex *aB, Vertex *aC, Material *amaterial); |
209 bool intersect(const Ray &ray, Float &dist) const; |
215 bool intersect(const Ray &ray, Float &dist) const; |
210 #ifdef TRI_BARI_PRE |
|
211 __m128 intersect_packet(const RayPacket &rays, __m128 &dists); |
|
212 #endif |
|
213 bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const {return false;}; |
216 bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const {return false;}; |
214 bool intersect_bbox(const BBox &bbox) const; |
217 bool intersect_bbox(const BBox &bbox) const; |
215 const Vector3 normal(const Vector3 &P) const { return (material->smooth ? smooth_normal(P) : N); }; |
218 const Vector normal(const Vector &P) const { return (material->smooth ? smooth_normal(P) : N); }; |
216 const Vector3 getNormal() const { return N; }; |
219 const Vector getNormal() const { return N; }; |
217 BBox get_bbox() const; |
220 BBox get_bbox() const; |
218 ostream & dump(ostream &st) const; |
221 ostream & dump(ostream &st) const; |
|
222 #if not defined(NO_SSE) and defined(TRI_BARI_PRE) |
|
223 __m128 intersect_packet(const RayPacket &rays, __m128 &dists); |
|
224 #endif |
219 }; |
225 }; |
220 |
226 |
221 template <class T> class Array |
227 template <class T> class Array |
222 { |
228 { |
223 T *array; |
229 T *array; |