include/vector.h
branchpyrit
changeset 94 4c8abb8977dc
parent 93 96d65f841791
child 95 ca7d4c665531
equal deleted inserted replaced
93:96d65f841791 94:4c8abb8977dc
     1 /*
     1 /**
     2  * vector.h: Vector class with Colour alias
     2  * @file  vector.h
       
     3  * @brief Vector class with Colour alias
     3  *
     4  *
     4  * This file is part of Pyrit Ray Tracer.
     5  * This file is part of Pyrit Ray Tracer.
     5  *
     6  *
     6  * Copyright 2006, 2007, 2008  Radek Brich
     7  * Copyright 2006, 2007, 2008  Radek Brich
     7  *
     8  *
    62 	const Float &operator[](int index) const { return cell[index]; };
    63 	const Float &operator[](int index) const { return cell[index]; };
    63 	Float &operator[](int index) { return cell[index]; };
    64 	Float &operator[](int index) { return cell[index]; };
    64 
    65 
    65 	bool operator==(const Vector &v) const { return x==v.x && y==v.y && z==v.z; };
    66 	bool operator==(const Vector &v) const { return x==v.x && y==v.y && z==v.z; };
    66 
    67 
    67 	// normalize
    68 	/** Normalize the vector */
    68 	Vector normalize()
    69 	Vector normalize()
    69 	{
    70 	{
    70 		const Float f = 1.0f / mag();
    71 		const Float f = 1.0f / mag();
    71 		*this *= f;
    72 		*this *= f;
    72 		return *this;
    73 		return *this;
    73 	};
    74 	};
    74 
    75 
    75 	// get normalized copy
    76 	/** Get normalized copy of vector */
    76 	friend Vector normalize(const Vector &v)
    77 	friend Vector normalize(const Vector &v)
    77 	{
    78 	{
    78 		const Float f = 1.0f / v.mag();
    79 		const Float f = 1.0f / v.mag();
    79 		return v * f;
    80 		return v * f;
    80 	};
    81 	};
    81 
    82 
    82 	// square magnitude, magnitude
    83 	/** Square magnitude */
    83 	Float mag2() const	{ return dot(*this, *this); };
    84 	Float mag2() const	{ return dot(*this, *this); };
       
    85 
       
    86 	/** Vector magnitude */
    84 	Float mag() const	{ return sqrtf(mag2()); };
    87 	Float mag() const	{ return sqrtf(mag2()); };
    85 
    88 
    86 	// negative
    89 	/** Get negative vector */
    87 	Vector operator-() const { return Vector(-x, -y, -z); };
    90 	Vector operator-() const { return Vector(-x, -y, -z); };
    88 
    91 
    89 	// accumulate
    92 	/** Accumulate. Useful for colors. */
    90 	Vector operator+=(const Vector &v)
    93 	Vector operator+=(const Vector &v)
    91 	{
    94 	{
    92 #ifdef NO_SIMD
    95 #ifdef NO_SIMD
    93 		x += v.x;
    96 		x += v.x;
    94 		y += v.y;
    97 		y += v.y;
    97 		mf4 = madd(mf4, v.mf4);
   100 		mf4 = madd(mf4, v.mf4);
    98 #endif
   101 #endif
    99 		return *this;
   102 		return *this;
   100 	};
   103 	};
   101 
   104 
   102 	// multiply
   105 	/** Multiply by scalar */
   103 	Vector operator*=(const Float &f)
   106 	Vector operator*=(const Float &f)
   104 	{
   107 	{
   105 		x *= f;
   108 		x *= f;
   106 		y *= f;
   109 		y *= f;
   107 		z *= f;
   110 		z *= f;
   108 		return *this;
   111 		return *this;
   109 	};
   112 	};
   110 
   113 
   111 
   114 	/** Cut with scalar */
   112 	// cut
       
   113 	Vector operator/=(const Float &f)
   115 	Vector operator/=(const Float &f)
   114 	{
   116 	{
   115 		Float finv = 1.0f / f;
   117 		Float finv = 1.0f / f;
   116 		x *= finv;
   118 		x *= finv;
   117 		y *= finv;
   119 		y *= finv;
   118 		z *= finv;
   120 		z *= finv;
   119 		return *this;
   121 		return *this;
   120 	};
   122 	};
   121 
   123 
   122 	// sum
   124 	/** Sum of two vectors */
   123 	friend Vector operator+(const Vector &a, const Vector &b)
   125 	friend Vector operator+(const Vector &a, const Vector &b)
   124 	{
   126 	{
   125 #ifdef NO_SIMD
   127 #ifdef NO_SIMD
   126 		return Vector(a.x + b.x, a.y + b.y, a.z + b.z);
   128 		return Vector(a.x + b.x, a.y + b.y, a.z + b.z);
   127 #else
   129 #else
   128 		return Vector(madd(a.mf4, b.mf4));
   130 		return Vector(madd(a.mf4, b.mf4));
   129 #endif
   131 #endif
   130 	};
   132 	};
   131 
   133 
   132 	// difference
   134 	/** Difference of two vectors */
   133 	friend Vector operator-(const Vector &a, const Vector &b)
   135 	friend Vector operator-(const Vector &a, const Vector &b)
   134 	{
   136 	{
   135 #if defined(NO_SIMD) || defined(MSVC)
   137 #if defined(NO_SIMD) || defined(MSVC)
   136 		return Vector(a.x - b.x, a.y - b.y, a.z - b.z);
   138 		return Vector(a.x - b.x, a.y - b.y, a.z - b.z);
   137 #else
   139 #else
   138 		// this faults in MSVC, for unknown reason
   140 		// this faults in MSVC, for unknown reason
   139 		return Vector(msub(a.mf4, b.mf4));
   141 		return Vector(msub(a.mf4, b.mf4));
   140 #endif
   142 #endif
   141 	};
   143 	};
   142 
   144 
   143 	// dot product
   145 	/** Dot product */
   144 	friend Float dot(const Vector &a, const Vector &b)
   146 	friend Float dot(const Vector &a, const Vector &b)
   145 	{
   147 	{
   146 		return a.x * b.x + a.y * b.y + a.z * b.z;
   148 		return a.x * b.x + a.y * b.y + a.z * b.z;
   147 	};
   149 	};
   148 
   150 
   149 	// cross product
   151 	/** Cross product */
   150 	friend Vector cross(const Vector &a, const Vector &b)
   152 	friend Vector cross(const Vector &a, const Vector &b)
   151 	{
   153 	{
   152 		return Vector(a.y * b.z - a.z * b.y,
   154 		return Vector(a.y * b.z - a.z * b.y,
   153 			a.z * b.x - a.x * b.z,
   155 			a.z * b.x - a.x * b.z,
   154 			a.x * b.y - a.y * b.x);
   156 			a.x * b.y - a.y * b.x);
   155 	};
   157 	};
   156 
   158 
   157 	// product of vector and scalar
   159 	/** Get vector multiplied by scalar */
   158 	friend Vector operator*(const Vector &v, const Float &f)
   160 	friend Vector operator*(const Vector &v, const Float &f)
   159 	{
   161 	{
   160 		return Vector(f * v.x, f * v.y, f * v.z);
   162 		return Vector(f * v.x, f * v.y, f * v.z);
   161 	};
   163 	};
   162 
   164 
       
   165 	/** Get vector multiplied by scalar */
   163 	friend Vector operator*(const Float &f, const Vector &v)
   166 	friend Vector operator*(const Float &f, const Vector &v)
   164 	{
   167 	{
   165 		return v * f;
   168 		return v * f;
   166 	};
   169 	};
   167 
   170 
   168 	// scalar division
   171 	/** Get vector divided by scalar */
   169 	friend Vector operator/(const Vector &v, const Float &f)
   172 	friend Vector operator/(const Vector &v, const Float &f)
   170 	{
   173 	{
   171 		const Float finv = 1.0f / f;
   174 		const Float finv = 1.0f / f;
   172 		return Vector(v.x * finv, v.y * finv, v.z * finv);
   175 		return Vector(v.x * finv, v.y * finv, v.z * finv);
   173 	};
   176 	};
   174 
   177 
       
   178 	/** Get f/v, i.e. inverted vector multiplied by scalar */
   175 	friend Vector operator/(const Float &f, const Vector &v)
   179 	friend Vector operator/(const Float &f, const Vector &v)
   176 	{
   180 	{
   177 #ifdef NO_SIMD
   181 #ifdef NO_SIMD
   178 		return Vector(f / v.x, f / v.y, f / v.z);
   182 		return Vector(f / v.x, f / v.y, f / v.z);
   179 #else
   183 #else
   180 		return Vector(mdiv(mset1(f), v.mf4));
   184 		return Vector(mdiv(mset1(f), v.mf4));
   181 #endif
   185 #endif
   182 	};
   186 	};
   183 
   187 
   184 	// vector plus scalar
   188 	/** Add scalar to the vector */
   185 	friend Vector operator+(const Vector &v, const Float &f)
   189 	friend Vector operator+(const Vector &v, const Float &f)
   186 	{
   190 	{
   187 		return Vector(v.x + f, v.y + f, v.z + f);
   191 		return Vector(v.x + f, v.y + f, v.z + f);
   188 	};
   192 	};
   189 
   193 
   190 	// vector minus scalar
   194 	/** Subtract scalar from the vector */
   191 	friend Vector operator-(const Vector &v, const Float &f)
   195 	friend Vector operator-(const Vector &v, const Float &f)
   192 	{
   196 	{
   193 		return Vector(v.x - f, v.y - f, v.z - f);
   197 		return Vector(v.x - f, v.y - f, v.z - f);
   194 	};
   198 	};
   195 
   199 
   196 	// cell by cell product (only usable for colours)
   200 	/** Cell by cell product (only useful for colors) */
   197 	friend Vector operator*(const Vector &a,  const Vector &b)
   201 	friend Vector operator*(const Vector &a, const Vector &b)
   198 	{
   202 	{
   199 #ifdef NO_SIMD
   203 #ifdef NO_SIMD
   200 		return Vector(a.x * b.x, a.y * b.y, a.z * b.z);
   204 		return Vector(a.x * b.x, a.y * b.y, a.z * b.z);
   201 #else
   205 #else
   202 		return Vector(mmul(a.mf4, b.mf4));
   206 		return Vector(mmul(a.mf4, b.mf4));
   203 #endif
   207 #endif
   204 	};
   208 	};
   205 
   209 
   206 	// write
   210 	/** Write textual representation of the vector to stream */
   207 	friend ostream & operator<<(ostream &st, const Vector &v)
   211 	friend ostream & operator<<(ostream &st, const Vector &v)
   208 	{
   212 	{
   209 		return st << "(" << v.x << "," << v.y  << "," << v.z << ")";
   213 		return st << "(" << v.x << "," << v.y  << "," << v.z << ")";
   210 	};
   214 	};
   211 
   215 
   212 	// read
   216 	/** Read the vector from stream */
   213 	friend istream & operator>>(istream &st, Vector &v)
   217 	friend istream & operator>>(istream &st, Vector &v)
   214 	{
   218 	{
   215 		char s[10];
   219 		char s[10];
   216 		st.getline(s, 10, '(');
   220 		st.getline(s, 10, '(');
   217 		st >> v.x;
   221 		st >> v.x;
   222 		st.getline(s, 10, ')');
   226 		st.getline(s, 10, ')');
   223 		return st;
   227 		return st;
   224 	};
   228 	};
   225 };
   229 };
   226 
   230 
       
   231 /** Colour is a alias name of Vector. */
   227 typedef Vector Colour;
   232 typedef Vector Colour;
   228 
   233 
   229 #ifndef NO_SIMD
   234 #ifndef NO_SIMD
       
   235 /**
       
   236   * Packet of four Vectors
       
   237   */
   230 class VectorPacket
   238 class VectorPacket
   231 {
   239 {
   232 public:
   240 public:
   233 	union {
   241 	union {
   234 		mfloat4 ma[3];
   242 		mfloat4 ma[3];