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