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