Commit | Line | Data |
---|---|---|
5e27df78 | 1 | // Created by: Kirill GAVRILOV |
d5f74e42 | 2 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
5e27df78 | 3 | // |
973c2be1 | 4 | // This file is part of Open CASCADE Technology software library. |
5e27df78 | 5 | // |
d5f74e42 | 6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
10 | // distribution for complete text of the license and disclaimer of any warranty. | |
5e27df78 | 11 | // |
973c2be1 | 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. | |
5e27df78 | 14 | |
15 | #ifndef _NCollection_Vec4_H__ | |
16 | #define _NCollection_Vec4_H__ | |
17 | ||
18 | #include <NCollection_Vec3.hxx> | |
19 | ||
20 | //! Generic 4-components vector. | |
21 | //! To be used as RGBA color vector or XYZW 3D-point with special W-component | |
22 | //! for operations with projection / model view matrices. | |
23 | //! Use this class for 3D-points carefully because declared W-component may | |
24 | //! results in incorrect results if used without matrices. | |
25 | template<typename Element_t> | |
26 | class NCollection_Vec4 | |
27 | { | |
28 | ||
29 | public: | |
30 | ||
31 | //! Returns the number of components. | |
32 | static size_t Length() | |
33 | { | |
34 | return 4; | |
35 | } | |
36 | ||
37 | //! Empty constructor. Construct the zero vector. | |
38 | NCollection_Vec4() | |
39 | { | |
40 | std::memset (this, 0, sizeof(NCollection_Vec4)); | |
41 | } | |
42 | ||
43 | //! Initialize ALL components of vector within specified value. | |
44 | explicit NCollection_Vec4 (const Element_t theValue) | |
45 | { | |
46 | v[0] = v[1] = v[2] = v[3] = theValue; | |
47 | } | |
48 | ||
49 | //! Per-component constructor. | |
50 | explicit NCollection_Vec4 (const Element_t theX, | |
51 | const Element_t theY, | |
52 | const Element_t theZ, | |
53 | const Element_t theW) | |
54 | { | |
55 | v[0] = theX; | |
56 | v[1] = theY; | |
57 | v[2] = theZ; | |
58 | v[3] = theW; | |
59 | } | |
60 | ||
61 | //! Constructor from 2-components vector. | |
62 | explicit NCollection_Vec4 (const NCollection_Vec2<Element_t>& theVec2) | |
63 | { | |
64 | v[0] = theVec2[0]; | |
65 | v[1] = theVec2[1]; | |
66 | v[2] = v[3] = Element_t (0); | |
67 | } | |
68 | ||
69 | //! Constructor from 3-components vector. | |
70 | explicit NCollection_Vec4(const NCollection_Vec3<Element_t>& theVec3) | |
71 | { | |
72 | std::memcpy (this, &theVec3, sizeof(NCollection_Vec3<Element_t>)); | |
73 | v[3] = Element_t (0); | |
74 | } | |
75 | ||
76 | //! Constructor from 3-components vector + alpha value. | |
77 | explicit NCollection_Vec4(const NCollection_Vec3<Element_t>& theVec3, | |
78 | const Element_t theAlpha) { | |
79 | std::memcpy (this, &theVec3, sizeof(NCollection_Vec3<Element_t>)); | |
80 | v[3] = theAlpha; | |
81 | } | |
82 | ||
83 | //! Copy constructor. | |
84 | NCollection_Vec4 (const NCollection_Vec4& theVec4) | |
85 | { | |
86 | std::memcpy (this, &theVec4, sizeof(NCollection_Vec4)); | |
87 | } | |
88 | ||
89 | //! Assignment operator. | |
90 | const NCollection_Vec4& operator= (const NCollection_Vec4& theVec4) | |
91 | { | |
92 | std::memcpy (this, &theVec4, sizeof(NCollection_Vec4)); | |
93 | return *this; | |
94 | } | |
95 | ||
96 | //! Alias to 1st component as X coordinate in XYZW. | |
97 | Element_t x() const { return v[0]; } | |
98 | ||
99 | //! Alias to 1st component as RED channel in RGBA. | |
100 | Element_t r() const { return v[0]; } | |
101 | ||
102 | //! Alias to 2nd component as Y coordinate in XYZW. | |
103 | Element_t y() const { return v[1]; } | |
104 | ||
105 | //! Alias to 2nd component as GREEN channel in RGBA. | |
106 | Element_t g() const { return v[1]; } | |
107 | ||
108 | //! Alias to 3rd component as Z coordinate in XYZW. | |
109 | Element_t z() const { return v[2]; } | |
110 | ||
111 | //! Alias to 3rd component as BLUE channel in RGBA. | |
112 | Element_t b() const { return v[2]; } | |
113 | ||
114 | //! Alias to 4th component as W coordinate in XYZW. | |
115 | Element_t w() const { return v[3]; } | |
116 | ||
117 | //! Alias to 4th component as ALPHA channel in RGBA. | |
118 | Element_t a() const { return v[3]; } | |
119 | ||
120 | //! @return 2 of XYZW components in specified order as vector in GLSL-style | |
5640d653 DB |
121 | NCOLLECTION_VEC_COMPONENTS_2D(x, y) |
122 | NCOLLECTION_VEC_COMPONENTS_2D(x, z) | |
123 | NCOLLECTION_VEC_COMPONENTS_2D(x, w) | |
124 | NCOLLECTION_VEC_COMPONENTS_2D(y, z) | |
125 | NCOLLECTION_VEC_COMPONENTS_2D(y, w) | |
126 | NCOLLECTION_VEC_COMPONENTS_2D(z, w) | |
5e27df78 | 127 | |
128 | //! @return 3 of XYZW components in specified order as vector in GLSL-style | |
5640d653 DB |
129 | NCOLLECTION_VEC_COMPONENTS_3D(x, y, z) |
130 | NCOLLECTION_VEC_COMPONENTS_3D(x, y, w) | |
131 | NCOLLECTION_VEC_COMPONENTS_3D(x, z, w) | |
132 | NCOLLECTION_VEC_COMPONENTS_3D(y, z, w) | |
5e27df78 | 133 | |
134 | //! @return RGB components as vector | |
5640d653 | 135 | NCOLLECTION_VEC_COMPONENTS_3D(r, g, b) |
5e27df78 | 136 | |
137 | //! Alias to 1st component as X coordinate in XYZW. | |
138 | Element_t& x() { return v[0]; } | |
139 | ||
140 | //! Alias to 1st component as RED channel in RGBA. | |
141 | Element_t& r() { return v[0]; } | |
142 | ||
143 | //! Alias to 2nd component as Y coordinate in XYZW. | |
144 | Element_t& y() { return v[1]; } | |
145 | ||
146 | //! Alias to 2nd component as GREEN channel in RGBA. | |
147 | Element_t& g() { return v[1]; } // Green color | |
148 | ||
149 | //! Alias to 3rd component as Z coordinate in XYZW. | |
150 | Element_t& z() { return v[2]; } | |
151 | ||
152 | //! Alias to 3rd component as BLUE channel in RGBA. | |
153 | Element_t& b() { return v[2]; } | |
154 | ||
155 | //! Alias to 4th component as W coordinate in XYZW. | |
156 | Element_t& w() { return v[3]; } | |
157 | ||
158 | //! Alias to 4th component as ALPHA channel in RGBA. | |
159 | Element_t& a() { return v[3]; } | |
160 | ||
161 | //! @return XY-components modifiable vector | |
162 | NCollection_Vec2<Element_t>& xy() | |
163 | { | |
164 | return *((NCollection_Vec2<Element_t>* )&v[0]); | |
165 | } | |
166 | ||
167 | //! @return YZ-components modifiable vector | |
168 | NCollection_Vec2<Element_t>& yz() | |
169 | { | |
170 | return *((NCollection_Vec2<Element_t>* )&v[1]); | |
171 | } | |
172 | ||
173 | //! @return YZ-components modifiable vector | |
174 | NCollection_Vec2<Element_t>& zw() | |
175 | { | |
176 | return *((NCollection_Vec2<Element_t>* )&v[2]); | |
177 | } | |
178 | ||
179 | //! @return XYZ-components modifiable vector | |
180 | NCollection_Vec3<Element_t>& xyz() | |
181 | { | |
182 | return *((NCollection_Vec3<Element_t>* )&v[0]); | |
183 | } | |
184 | ||
185 | //! @return YZW-components modifiable vector | |
186 | NCollection_Vec3<Element_t>& yzw() | |
187 | { | |
188 | return *((NCollection_Vec3<Element_t>* )&v[1]); | |
189 | } | |
190 | ||
191 | //! Raw access to the data (for OpenGL exchange). | |
938d4544 | 192 | const Element_t* GetData() const { return v; } |
193 | Element_t* ChangeData() { return v; } | |
194 | operator const Element_t*() const { return v; } | |
195 | operator Element_t*() { return v; } | |
5e27df78 | 196 | |
197 | //! Compute per-component summary. | |
198 | NCollection_Vec4& operator+= (const NCollection_Vec4& theAdd) | |
199 | { | |
200 | v[0] += theAdd.v[0]; | |
201 | v[1] += theAdd.v[1]; | |
202 | v[2] += theAdd.v[2]; | |
203 | v[3] += theAdd.v[3]; | |
204 | return *this; | |
205 | } | |
206 | ||
207 | //! Compute per-component summary. | |
208 | friend NCollection_Vec4 operator+ (const NCollection_Vec4& theLeft, | |
209 | const NCollection_Vec4& theRight) | |
210 | { | |
211 | NCollection_Vec4 aSumm = NCollection_Vec4 (theLeft); | |
212 | return aSumm += theRight; | |
213 | } | |
214 | ||
12381341 | 215 | //! Unary -. |
216 | NCollection_Vec4 operator-() const | |
217 | { | |
218 | return NCollection_Vec4 (-x(), -y(), -z(), -w()); | |
219 | } | |
220 | ||
5e27df78 | 221 | //! Compute per-component subtraction. |
222 | NCollection_Vec4& operator-= (const NCollection_Vec4& theDec) | |
223 | { | |
224 | v[0] -= theDec.v[0]; | |
225 | v[1] -= theDec.v[1]; | |
226 | v[2] -= theDec.v[2]; | |
227 | v[3] -= theDec.v[3]; | |
228 | return *this; | |
229 | } | |
230 | ||
231 | //! Compute per-component subtraction. | |
232 | friend NCollection_Vec4 operator- (const NCollection_Vec4& theLeft, | |
233 | const NCollection_Vec4& theRight) | |
234 | { | |
235 | NCollection_Vec4 aSumm = NCollection_Vec4 (theLeft); | |
236 | return aSumm -= theRight; | |
237 | } | |
238 | ||
239 | //! Compute per-component multiplication. | |
240 | NCollection_Vec4& operator*= (const NCollection_Vec4& theRight) | |
241 | { | |
242 | v[0] *= theRight.v[0]; | |
243 | v[1] *= theRight.v[1]; | |
244 | v[2] *= theRight.v[2]; | |
245 | v[3] *= theRight.v[3]; | |
246 | return *this; | |
247 | } | |
248 | ||
249 | //! Compute per-component multiplication. | |
250 | friend NCollection_Vec4 operator* (const NCollection_Vec4& theLeft, | |
251 | const NCollection_Vec4& theRight) | |
252 | { | |
253 | NCollection_Vec4 aResult = NCollection_Vec4 (theLeft); | |
254 | return aResult *= theRight; | |
255 | } | |
256 | ||
257 | //! Compute per-component multiplication. | |
258 | void Multiply (const Element_t theFactor) | |
259 | { | |
260 | v[0] *= theFactor; | |
261 | v[1] *= theFactor; | |
262 | v[2] *= theFactor; | |
263 | v[3] *= theFactor; | |
264 | } | |
265 | ||
266 | //! Compute per-component multiplication. | |
267 | NCollection_Vec4& operator*=(const Element_t theFactor) | |
268 | { | |
269 | Multiply (theFactor); | |
270 | return *this; | |
271 | } | |
272 | ||
273 | //! Compute per-component multiplication. | |
274 | NCollection_Vec4 operator* (const Element_t theFactor) const | |
275 | { | |
276 | return Multiplied (theFactor); | |
277 | } | |
278 | ||
279 | //! Compute per-component multiplication. | |
280 | NCollection_Vec4 Multiplied (const Element_t theFactor) const | |
281 | { | |
282 | NCollection_Vec4 aCopyVec4 (*this); | |
283 | aCopyVec4 *= theFactor; | |
284 | return aCopyVec4; | |
285 | } | |
286 | ||
3c4e78f2 | 287 | //! Compute component-wise minimum of two vectors. |
288 | NCollection_Vec4 cwiseMin (const NCollection_Vec4& theVec) const | |
289 | { | |
200ed755 | 290 | return NCollection_Vec4 (v[0] < theVec.v[0] ? v[0] : theVec.v[0], |
291 | v[1] < theVec.v[1] ? v[1] : theVec.v[1], | |
292 | v[2] < theVec.v[2] ? v[2] : theVec.v[2], | |
293 | v[3] < theVec.v[3] ? v[3] : theVec.v[3]); | |
3c4e78f2 | 294 | } |
295 | ||
296 | //! Compute component-wise maximum of two vectors. | |
297 | NCollection_Vec4 cwiseMax (const NCollection_Vec4& theVec) const | |
298 | { | |
200ed755 | 299 | return NCollection_Vec4 (v[0] > theVec.v[0] ? v[0] : theVec.v[0], |
300 | v[1] > theVec.v[1] ? v[1] : theVec.v[1], | |
301 | v[2] > theVec.v[2] ? v[2] : theVec.v[2], | |
302 | v[3] > theVec.v[3] ? v[3] : theVec.v[3]); | |
3c4e78f2 | 303 | } |
304 | ||
5e27df78 | 305 | //! Compute per-component division by scale factor. |
306 | NCollection_Vec4& operator/= (const Element_t theInvFactor) | |
307 | { | |
308 | v[0] /= theInvFactor; | |
309 | v[1] /= theInvFactor; | |
310 | v[2] /= theInvFactor; | |
311 | v[3] /= theInvFactor; | |
312 | return *this; | |
313 | } | |
314 | ||
315 | //! Compute per-component division by scale factor. | |
316 | NCollection_Vec4 operator/ (const Element_t theInvFactor) | |
317 | { | |
318 | NCollection_Vec4 aResult(this); | |
319 | return aResult /= theInvFactor; | |
320 | } | |
321 | ||
322 | private: | |
323 | ||
324 | Element_t v[4]; //!< define the vector as array to avoid structure alignment issues | |
325 | ||
326 | }; | |
327 | ||
328 | //! Optimized concretization for float type. | |
329 | template<> inline NCollection_Vec4<float>& NCollection_Vec4<float>::operator/= (const float theInvFactor) | |
330 | { | |
331 | Multiply (1.0f / theInvFactor); | |
332 | return *this; | |
333 | } | |
334 | ||
335 | //! Optimized concretization for double type. | |
336 | template<> inline NCollection_Vec4<double>& NCollection_Vec4<double>::operator/= (const double theInvFactor) | |
337 | { | |
338 | Multiply (1.0 / theInvFactor); | |
339 | return *this; | |
340 | } | |
341 | ||
342 | #endif // _NCollection_Vec4_H__ |