YafaRay Core  v3.2.0-ALPHA-10-g60452c5
vector3d.h
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * vector3d.h: Vector 3d and point representation and manipulation api
4  * This is part of the yafray package
5  * Copyright (C) 2002 Alejandro Conty Estevez
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  */
22 #ifndef Y_VECTOR3D_H
23 #define Y_VECTOR3D_H
24 
25 #include <yafray_config.h>
26 
28 #include <iostream>
29 
30 #include <boost/serialization/nvp.hpp>
31 #include <boost/serialization/vector.hpp>
32 
34 
35 // useful trick found in trimesh2 lib by Szymon Rusinkiewicz
36 // makes code for vector dot- cross-products much more readable
37 #define VDOT *
38 #define VCROSS ^
39 
40 #ifndef M_PI //in most cases pi is defined as M_PI in cmath ohterwise we define it
41 #define M_PI 3.1415926535897932384626433832795
42 #endif
43 
44 class normal_t;
45 class point3d_t;
46 
48 {
49  public:
50  vector3d_t() { }
51  vector3d_t(float v): x(v), y(v), z(v) { }
52  vector3d_t(float ix, float iy, float iz=0): x(ix), y(iy), z(iz) { }
53  vector3d_t(const vector3d_t &s): x(s.x), y(s.y), z(s.z) { }
54  explicit vector3d_t(const normal_t &n);
55  explicit vector3d_t(const point3d_t &p);
56 
57  void set(float ix, float iy, float iz=0) { x=ix; y=iy; z=iz; }
58  vector3d_t& normalize();
59  vector3d_t& reflect(const vector3d_t &n);
60  // normalizes and returns length
61  float normLen()
62  {
63  float vl = x*x + y*y + z*z;
64  if (vl!=0.0) {
65  vl = fSqrt(vl);
66  const float d = 1.0/vl;
67  x*=d; y*=d; z*=d;
68  }
69  return vl;
70  }
71  // normalizes and returns length squared
72  float normLenSqr()
73  {
74  float vl = x*x + y*y + z*z;
75  if (vl!=0.0) {
76  const float d = 1.0/fSqrt(vl);
77  x*=d; y*=d; z*=d;
78  }
79  return vl;
80  }
81  float length() const;
82  float lengthSqr() const{ return x*x+y*y+z*z; }
83  bool null()const { return ((x==0) && (y==0) && (z==0)); }
84  float sinFromVectors(const vector3d_t &v);
85  vector3d_t& operator = (const vector3d_t &s) { x=s.x; y=s.y; z=s.z; return *this;}
86  vector3d_t& operator +=(const vector3d_t &s) { x+=s.x; y+=s.y; z+=s.z; return *this;}
87  vector3d_t& operator -=(const vector3d_t &s) { x-=s.x; y-=s.y; z-=s.z; return *this;}
88  vector3d_t& operator /=(float s) { x/=s; y/=s; z/=s; return *this;}
89  vector3d_t& operator *=(float s) { x*=s; y*=s; z*=s; return *this;}
90  float operator[] (int i) const{ return (&x)[i]; } //Lynx
91  void abs() { x=std::fabs(x); y=std::fabs(y); z=std::fabs(z); }
93  float x,y,z;
94 
95  friend class boost::serialization::access;
96  template<class Archive> void serialize(Archive & ar, const unsigned int version)
97  {
98  ar & BOOST_SERIALIZATION_NVP(x);
99  ar & BOOST_SERIALIZATION_NVP(y);
100  ar & BOOST_SERIALIZATION_NVP(z);
101  }
102 };
103 
105 {
106  public:
107  normal_t(){};
108  normal_t(float nx, float ny, float nz): x(nx), y(ny), z(nz){}
109  explicit normal_t(const vector3d_t &v): x(v.x), y(v.y), z(v.z) { }
110  normal_t& normalize();
111  normal_t& operator = (const vector3d_t &v){ x=v.x, y=v.y, z=v.z; return *this; }
112  normal_t& operator +=(const vector3d_t &s) { x+=s.x; y+=s.y; z+=s.z; return *this; }
113  float x, y, z;
114 
115  friend class boost::serialization::access;
116  template<class Archive> void serialize(Archive & ar, const unsigned int version)
117  {
118  ar & BOOST_SERIALIZATION_NVP(x);
119  ar & BOOST_SERIALIZATION_NVP(y);
120  ar & BOOST_SERIALIZATION_NVP(z);
121  }
122 };
123 
125 {
126  public:
128  point3d_t(float ix, float iy, float iz=0): x(ix), y(iy), z(iz) { }
129  point3d_t(const point3d_t &s): x(s.x), y(s.y), z(s.z) { }
130  point3d_t(const vector3d_t &v): x(v.x), y(v.y), z(v.z) { }
131  void set(float ix, float iy, float iz=0) { x=ix; y=iy; z=iz; }
132  float length() const;
133  point3d_t& operator= (const point3d_t &s) { x=s.x; y=s.y; z=s.z; return *this; }
134  point3d_t& operator *=(float s) { x*=s; y*=s; z*=s; return *this;}
135  point3d_t& operator +=(float s) { x+=s; y+=s; z+=s; return *this;}
136  point3d_t& operator +=(const point3d_t &s) { x+=s.x; y+=s.y; z+=s.z; return *this;}
137  point3d_t& operator -=(const point3d_t &s) { x-=s.x; y-=s.y; z-=s.z; return *this;}
138  float operator[] (int i) const{ return (&x)[i]; } //Lynx
139  float &operator[](int i) { return (&x)[i]; } //Lynx
141  float x,y,z;
142 
143  friend class boost::serialization::access;
144  template<class Archive> void serialize(Archive & ar, const unsigned int version)
145  {
146  ar & BOOST_SERIALIZATION_NVP(x);
147  ar & BOOST_SERIALIZATION_NVP(y);
148  ar & BOOST_SERIALIZATION_NVP(z);
149  }
150 };
151 
152 
153 inline vector3d_t::vector3d_t(const normal_t &n): x(n.x), y(n.y), z(n.z) { }
154 inline vector3d_t::vector3d_t(const point3d_t &p): x(p.x), y(p.y), z(p.z) { }
155 
156 #define FAST_ANGLE(a,b) ( (a).x*(b).y - (a).y*(b).x )
157 #define FAST_SANGLE(a,b) ( (((a).x*(b).y - (a).y*(b).x) >= 0) ? 0 : 1 )
158 #define SIN(a,b) fSqrt(1-((a)*(b))*((a)*(b)))
159 
160 YAFRAYCORE_EXPORT std::ostream & operator << (std::ostream &out,const vector3d_t &v);
161 YAFRAYCORE_EXPORT std::ostream & operator << (std::ostream &out,const point3d_t &p);
162 
163 inline float operator * ( const vector3d_t &a,const vector3d_t &b)
164 {
165  return (a.x*b.x+a.y*b.y+a.z*b.z);
166 }
167 
168 inline vector3d_t operator * ( float f,const vector3d_t &b)
169 {
170  return vector3d_t(f*b.x,f*b.y,f*b.z);
171 }
172 
173 inline vector3d_t operator * (const vector3d_t &b,float f)
174 {
175  return vector3d_t(f*b.x,f*b.y,f*b.z);
176 }
177 
178 inline point3d_t operator * (float f,const point3d_t &b)
179 {
180  return point3d_t(f*b.x,f*b.y,f*b.z);
181 }
182 
183 inline vector3d_t operator / (const vector3d_t &b,float f)
184 {
185  return vector3d_t(b.x/f,b.y/f,b.z/f);
186 }
187 
188 inline point3d_t operator / (const point3d_t &b,float f)
189 {
190  return point3d_t(b.x/f,b.y/f,b.z/f);
191 }
192 
193 inline point3d_t operator * (const point3d_t &b,float f)
194 {
195  return point3d_t(b.x*f,b.y*f,b.z*f);
196 }
197 
198 inline vector3d_t operator / (float f,const vector3d_t &b)
199 {
200  return vector3d_t(b.x/f,b.y/f,b.z/f);
201 }
202 
203 inline vector3d_t operator ^ ( const vector3d_t &a,const vector3d_t &b)
204 {
205  return vector3d_t(a.y*b.z-a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
206 }
207 
208 inline vector3d_t operator - ( const vector3d_t &a,const vector3d_t &b)
209 {
210  return vector3d_t(a.x-b.x,a.y-b.y,a.z-b.z);
211 }
212 
213 inline vector3d_t operator - ( const point3d_t &a,const point3d_t &b)
214 {
215  return vector3d_t(a.x-b.x,a.y-b.y,a.z-b.z);
216 }
217 
218 inline point3d_t operator - ( const point3d_t &a,const vector3d_t &b)
219 {
220  return point3d_t(a.x-b.x,a.y-b.y,a.z-b.z);
221 }
222 
224 {
225  return vector3d_t(-b.x,-b.y,-b.z);
226 }
227 
228 inline vector3d_t operator + ( const vector3d_t &a,const vector3d_t &b)
229 {
230  return vector3d_t(a.x+b.x,a.y+b.y,a.z+b.z);
231 }
232 
233 inline point3d_t operator + ( const point3d_t &a,const point3d_t &b)
234 {
235  return point3d_t(a.x+b.x,a.y+b.y,a.z+b.z);
236 }
237 
238 inline point3d_t operator + ( const point3d_t &a,const vector3d_t &b)
239 {
240  return point3d_t(a.x+b.x,a.y+b.y,a.z+b.z);
241 }
242 
243 inline normal_t operator + ( const normal_t &a,const vector3d_t &b)
244 {
245  return normal_t(a.x+b.x,a.y+b.y,a.z+b.z);
246 }
247 
248 
249 inline bool operator == ( const point3d_t &a,const point3d_t &b)
250 {
251  return ((a.x==b.x) && (a.y==b.y) && (a.z==b.z));
252 }
253 
254 YAFRAYCORE_EXPORT bool operator == ( const vector3d_t &a,const vector3d_t &b);
255 YAFRAYCORE_EXPORT bool operator != ( const vector3d_t &a,const vector3d_t &b);
256 
257 inline point3d_t mult(const point3d_t &a, const vector3d_t &b)
258 {
259  return point3d_t(a.x * b.x, a.y * b.y, a.z * b.z);
260 }
261 
262 inline float vector3d_t::length()const
263 {
264  return fSqrt(x*x+y*y+z*z);
265 }
266 
268 {
269  float len = x*x + y*y + z*z;
270  if (len!=0)
271  {
272  len = 1.0/fSqrt(len);
273  x *= len;
274  y *= len;
275  z *= len;
276  }
277  return *this;
278 }
279 
280 
282 {
283  float div = ( length() * v.length() ) * 0.99999f + 0.00001f;
284  float asin_argument = ( (*this ^ v ).length() / div) * 0.99999f;
285  //Fix to avoid black "nan" areas when this argument goes slightly over +1.0. Why that happens in the first place, maybe floating point rounding errors?
286  if(asin_argument > 1.f) asin_argument = 1.f;
287  return asin(asin_argument);
288 }
289 
291 {
292  float len = x*x + y*y + z*z;
293  if (len!=0)
294  {
295  len = 1.0/fSqrt(len);
296  x *= len;
297  y *= len;
298  z *= len;
299  }
300  return *this;
301 }
302 
310 {
311  const float vn = 2.0f*(x*n.x+y*n.y+z*n.z);
312  x = vn*n.x -x;
313  y = vn*n.y -y;
314  z = vn*n.z -z;
315  return *this;
316 }
317 
318 inline vector3d_t reflect_dir(const vector3d_t &n,const vector3d_t &v)
319 {
320  const float vn = v*n;
321  if (vn<0) return -v;
322  return 2*vn*n - v;
323 }
324 
325 
326 inline vector3d_t toVector(const point3d_t &p)
327 {
328  return vector3d_t(p.x,p.y,p.z);
329 }
330 
331 YAFRAYCORE_EXPORT bool refract(const vector3d_t &n,const vector3d_t &wi, vector3d_t &wo, float IOR);
332 YAFRAYCORE_EXPORT bool refract_test(const vector3d_t &n,const vector3d_t &wi, float IOR);
333 YAFRAYCORE_EXPORT bool inv_refract_test(vector3d_t &n,const vector3d_t &wi, const vector3d_t &wo, float IOR);
334 YAFRAYCORE_EXPORT void fresnel(const vector3d_t & I, const vector3d_t & n, float IOR, float &Kr, float &Kt);
335 YAFRAYCORE_EXPORT void fast_fresnel(const vector3d_t & I, const vector3d_t & n, float IORF, float &Kr, float &Kt);
336 
337 inline void createCS(const vector3d_t &N, vector3d_t &u, vector3d_t &v)
338 {
339  if ((N.x==0) && (N.y==0))
340  {
341  if (N.z<0)
342  u.set(-1, 0, 0);
343  else
344  u.set(1, 0, 0);
345  v.set(0, 1, 0);
346  }
347  else
348  {
349  // Note: The root cannot become zero if
350  // N.x==0 && N.y==0.
351  const float d = 1.0/fSqrt(N.y*N.y + N.x*N.x);
352  u.set(N.y*d, -N.x*d, 0);
353  v = N^u;
354  }
355 }
356 
357 YAFRAYCORE_EXPORT void ShirleyDisk(float r1, float r2, float &u, float &v);
358 
359 extern YAFRAYCORE_EXPORT int myseed;
360 
361 inline int ourRandomI()
362 {
363  const int a = 0x000041A7;
364  const int m = 0x7FFFFFFF;
365  const int q = 0x0001F31D; // m/a
366  const int r = 0x00000B14; // m%a;
367  myseed = a * (myseed % q) - r * (myseed/q);
368  if (myseed < 0)
369  myseed += m;
370  return myseed;
371 }
372 
373 inline float ourRandom()
374 {
375  const int a = 0x000041A7;
376  const int m = 0x7FFFFFFF;
377  const int q = 0x0001F31D; // m/a
378  const int r = 0x00000B14; // m%a;
379  myseed = a * (myseed % q) - r * (myseed/q);
380  if (myseed < 0)
381  myseed += m;
382  return (float)myseed/(float)m;
383 }
384 
385 inline float ourRandom(int &seed)
386 {
387  const int a = 0x000041A7;
388  const int m = 0x7FFFFFFF;
389  const int q = 0x0001F31D; // m/a
390  const int r = 0x00000B14; // m%a;
391  seed = a * (seed % q) - r * (seed/q);
392  if (myseed < 0)
393  myseed += m;
394  return (float)seed/(float)m;
395 }
396 
398 {
399  float r;
400  vector3d_t v(0.0, 0.0, ourRandom());
401  if ((r = 1.0 - v.z*v.z)>0.0) {
402  float a = M_2PI * ourRandom();
403  r = fSqrt(r);
404  v.x = r * fCos(a); v.y = r * fSin(a);
405  }
406  else v.z = 1.0;
407  return v;
408 }
409 
411  float cosang, float z1, float z2);
412 YAFRAYCORE_EXPORT vector3d_t randomVectorCone(const vector3d_t &dir, float cosangle, float r1, float r2);
413 YAFRAYCORE_EXPORT vector3d_t discreteVectorCone(const vector3d_t &dir, float cangle, int sample, int square);
414 
416 
417 #endif // Y_VECTOR3D_H
float ourRandom()
Definition: vector3d.h:373
normal_t(float nx, float ny, float nz)
Definition: vector3d.h:108
YAFRAYCORE_EXPORT void fast_fresnel(const vector3d_t &I, const vector3d_t &n, float IORF, float &Kr, float &Kt)
Definition: vector3d.cc:144
void set(float ix, float iy, float iz=0)
Definition: vector3d.h:57
float fCos(float x)
YAFRAYCORE_EXPORT vector3d_t randomVectorCone(const vector3d_t &D, const vector3d_t &U, const vector3d_t &V, float cosang, float z1, float z2)
Definition: vector3d.cc:189
vector3d_t()
Definition: vector3d.h:50
float operator*(const vector3d_t &a, const vector3d_t &b)
Definition: vector3d.h:163
float y
Definition: vector3d.h:113
~point3d_t()
Definition: vector3d.h:140
vector3d_t & normalize()
Definition: vector3d.h:267
YAFRAYCORE_EXPORT void fresnel(const vector3d_t &I, const vector3d_t &n, float IOR, float &Kr, float &Kt)
Definition: vector3d.cc:110
void serialize(Archive &ar, const unsigned int version)
Definition: vector3d.h:144
point3d_t(const vector3d_t &v)
Definition: vector3d.h:130
void createCS(const vector3d_t &N, vector3d_t &u, vector3d_t &v)
Definition: vector3d.h:337
float lengthSqr() const
Definition: vector3d.h:82
float z
Definition: vector3d.h:140
vector3d_t operator/(const vector3d_t &b, float f)
Definition: vector3d.h:183
#define __BEGIN_YAFRAY
void serialize(Archive &ar, const unsigned int version)
Definition: vector3d.h:116
point3d_t(float ix, float iy, float iz=0)
Definition: vector3d.h:128
YAFRAYCORE_EXPORT bool inv_refract_test(vector3d_t &n, const vector3d_t &wi, const vector3d_t &wo, float IOR)
normal_t()
Definition: vector3d.h:107
vector3d_t operator+(const vector3d_t &a, const vector3d_t &b)
Definition: vector3d.h:228
float fSin(float x)
YAFRAYCORE_EXPORT void ShirleyDisk(float r1, float r2, float &u, float &v)
Definition: vector3d.cc:155
vector3d_t(float v)
Definition: vector3d.h:51
float normLenSqr()
Definition: vector3d.h:72
#define M_2PI
float z
Definition: vector3d.h:92
YAFRAYCORE_EXPORT bool refract_test(const vector3d_t &n, const vector3d_t &wi, float IOR)
float x
Definition: vector3d.h:113
YAFRAYCORE_EXPORT bool refract(const vector3d_t &n, const vector3d_t &wi, vector3d_t &wo, float IOR)
Definition: vector3d.cc:86
YAFRAYCORE_EXPORT std::ostream & operator<<(std::ostream &out, const vector3d_t &v)
Definition: vector3d.cc:28
vector3d_t toVector(const point3d_t &p)
Definition: vector3d.h:326
float x
Definition: vector3d.h:92
vector3d_t operator-(const vector3d_t &a, const vector3d_t &b)
Definition: vector3d.h:208
float length() const
Definition: vector3d.h:262
float normLen()
Definition: vector3d.h:61
void abs()
Definition: vector3d.h:91
int ourRandomI()
Definition: vector3d.h:361
vector3d_t(const vector3d_t &s)
Definition: vector3d.h:53
void serialize(Archive &ar, const unsigned int version)
Definition: vector3d.h:96
float x
Definition: vector3d.h:140
YAFRAYCORE_EXPORT bool operator!=(const vector3d_t &a, const vector3d_t &b)
Definition: vector3d.cc:50
normal_t(const vector3d_t &v)
Definition: vector3d.h:109
point3d_t mult(const point3d_t &a, const vector3d_t &b)
Definition: vector3d.h:257
vector3d_t operator^(const vector3d_t &a, const vector3d_t &b)
Definition: vector3d.h:203
vector3d_t reflect_dir(const vector3d_t &n, const vector3d_t &v)
Definition: vector3d.h:318
#define YAFRAYCORE_EXPORT
float z
Definition: vector3d.h:113
point3d_t()
Definition: vector3d.h:127
float sinFromVectors(const vector3d_t &v)
Definition: vector3d.h:281
normal_t & normalize()
Definition: vector3d.h:290
float y
Definition: vector3d.h:92
float & operator[](int i)
Definition: vector3d.h:139
YAFRAYCORE_EXPORT vector3d_t discreteVectorCone(const vector3d_t &dir, float cangle, int sample, int square)
Definition: vector3d.cc:204
float y
Definition: vector3d.h:140
vector3d_t RandomSpherical()
Definition: vector3d.h:397
point3d_t(const point3d_t &s)
Definition: vector3d.h:129
float fSqrt(float a)
~vector3d_t()
Definition: vector3d.h:92
bool null() const
Definition: vector3d.h:83
vector3d_t & reflect(const vector3d_t &n)
Definition: vector3d.h:309
YAFRAYCORE_EXPORT int myseed
Definition: vector3d.cc:187
vector3d_t(float ix, float iy, float iz=0)
Definition: vector3d.h:52
bool operator==(const point3d_t &a, const point3d_t &b)
Definition: vector3d.h:249
#define __END_YAFRAY