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;  |