0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / NCollection / NCollection_Vec4.hxx
CommitLineData
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.
29template<typename Element_t>
30class NCollection_Vec4
31{
32
33public:
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
308private:
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.
315template<> 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.
322template<> 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__