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_Vec3_H__ |
20 | #define _NCollection_Vec3_H__ |
21 | |
22 | #include <cstring> |
23 | #include <cmath> |
24 | #include <NCollection_Vec2.hxx> |
25 | |
26 | //! Auxiliary macros to define couple of similar access components as vector methods |
27 | #define NCOLLECTION_VEC_COMPONENTS_3D(theX, theY, theZ) \ |
bf75be98 |
28 | const NCollection_Vec3<Element_t> theX##theY##theZ() const { return NCollection_Vec3<Element_t>(theX(), theY(), theZ()); } \ |
29 | const NCollection_Vec3<Element_t> theX##theZ##theY() const { return NCollection_Vec3<Element_t>(theX(), theZ(), theY()); } \ |
30 | const NCollection_Vec3<Element_t> theY##theX##theZ() const { return NCollection_Vec3<Element_t>(theY(), theX(), theZ()); } \ |
31 | const NCollection_Vec3<Element_t> theY##theZ##theX() const { return NCollection_Vec3<Element_t>(theY(), theZ(), theX()); } \ |
32 | const NCollection_Vec3<Element_t> theZ##theY##theX() const { return NCollection_Vec3<Element_t>(theZ(), theY(), theX()); } \ |
33 | const NCollection_Vec3<Element_t> theZ##theX##theY() const { return NCollection_Vec3<Element_t>(theZ(), theX(), theY()); } |
5e27df78 |
34 | |
35 | //! Generic 3-components vector. |
36 | //! To be used as RGB color pixel or XYZ 3D-point. |
37 | //! The main target for this class - to handle raw low-level arrays (from/to graphic driver etc.). |
38 | template<typename Element_t> |
39 | class NCollection_Vec3 |
40 | { |
41 | |
42 | public: |
43 | |
44 | //! Returns the number of components. |
45 | static int Length() |
46 | { |
47 | return 3; |
48 | } |
49 | |
50 | //! Empty constructor. Construct the zero vector. |
51 | NCollection_Vec3() |
52 | { |
53 | std::memset (this, 0, sizeof(NCollection_Vec3)); |
54 | } |
55 | |
56 | //! Initialize ALL components of vector within specified value. |
57 | explicit NCollection_Vec3 (Element_t theValue) |
58 | { |
59 | v[0] = v[1] = v[2] = theValue; |
60 | } |
61 | |
62 | //! Per-component constructor. |
63 | explicit NCollection_Vec3 (const Element_t theX, |
64 | const Element_t theY, |
65 | const Element_t theZ) |
66 | { |
67 | v[0] = theX; |
68 | v[1] = theY; |
69 | v[2] = theZ; |
70 | } |
71 | |
72 | //! Constructor from 2-components vector. |
73 | explicit NCollection_Vec3 (const NCollection_Vec2<Element_t>& theVec2) |
74 | { |
75 | v[0] = theVec2[0]; |
76 | v[1] = theVec2[1]; |
77 | v[2] = Element_t(0); |
78 | } |
79 | |
80 | //! Copy constructor. |
81 | NCollection_Vec3 (const NCollection_Vec3& theVec3) |
82 | { |
83 | std::memcpy (this, &theVec3, sizeof(NCollection_Vec3)); |
84 | } |
85 | |
86 | //! Assignment operator. |
87 | const NCollection_Vec3& operator= (const NCollection_Vec3& theVec3) |
88 | { |
89 | std::memcpy (this, &theVec3, sizeof(NCollection_Vec3)); |
90 | return *this; |
91 | } |
92 | |
93 | //! Alias to 1st component as X coordinate in XYZ. |
94 | Element_t x() const { return v[0]; } |
95 | |
96 | //! Alias to 1st component as RED channel in RGB. |
97 | Element_t r() const { return v[0]; } |
98 | |
99 | //! Alias to 2nd component as Y coordinate in XYZ. |
100 | Element_t y() const { return v[1]; } |
101 | |
102 | //! Alias to 2nd component as GREEN channel in RGB. |
103 | Element_t g() const { return v[1]; } |
104 | |
105 | //! Alias to 3rd component as Z coordinate in XYZ. |
106 | Element_t z() const { return v[2]; } |
107 | |
108 | //! Alias to 3rd component as BLUE channel in RGB. |
109 | Element_t b() const { return v[2]; } |
110 | |
111 | //! @return 2 components by their names in specified order (in GLSL-style) |
112 | NCOLLECTION_VEC_COMPONENTS_2D(x, y); |
113 | NCOLLECTION_VEC_COMPONENTS_2D(x, z); |
114 | NCOLLECTION_VEC_COMPONENTS_2D(y, z); |
115 | |
116 | //! @return 3 components by their names in specified order (in GLSL-style) |
117 | NCOLLECTION_VEC_COMPONENTS_3D(x, y, z); |
118 | |
119 | //! Alias to 1st component as X coordinate in XYZ. |
120 | Element_t& x() { return v[0]; } |
121 | |
122 | //! Alias to 1st component as RED channel in RGB. |
123 | Element_t& r() { return v[0]; } |
124 | |
125 | //! Alias to 2nd component as Y coordinate in XYZ. |
126 | Element_t& y() { return v[1]; } |
127 | |
128 | //! Alias to 2nd component as GREEN channel in RGB. |
129 | Element_t& g() { return v[1]; } |
130 | |
131 | //! Alias to 3rd component as Z coordinate in XYZ. |
132 | Element_t& z() { return v[2]; } |
133 | |
134 | //! Alias to 3rd component as BLUE channel in RGB. |
135 | Element_t& b() { return v[2]; } |
136 | |
137 | //! @return XY-components modifiable vector |
138 | NCollection_Vec2<Element_t>& xy() |
139 | { |
140 | return *((NCollection_Vec2<Element_t>* )&v[0]); |
141 | } |
142 | |
143 | //! @return YZ-components modifiable vector |
144 | NCollection_Vec2<Element_t>& yz() |
145 | { |
146 | return *((NCollection_Vec2<Element_t>* )&v[1]); |
147 | } |
148 | |
149 | //! Raw access to the data (for OpenGL exchange). |
938d4544 |
150 | const Element_t* GetData() const { return v; } |
151 | Element_t* ChangeData() { return v; } |
152 | operator const Element_t*() const { return v; } |
153 | operator Element_t*() { return v; } |
5e27df78 |
154 | |
155 | //! Compute per-component summary. |
156 | NCollection_Vec3& operator+= (const NCollection_Vec3& theAdd) |
157 | { |
158 | v[0] += theAdd.v[0]; |
159 | v[1] += theAdd.v[1]; |
160 | v[2] += theAdd.v[2]; |
161 | return *this; |
162 | } |
163 | |
164 | //! Compute per-component summary. |
165 | friend NCollection_Vec3 operator+ (const NCollection_Vec3& theLeft, |
166 | const NCollection_Vec3& theRight) |
167 | { |
168 | NCollection_Vec3 aSumm = NCollection_Vec3 (theLeft); |
169 | return aSumm += theRight; |
170 | } |
171 | |
172 | //! Unary -. |
173 | NCollection_Vec3 operator-() const |
174 | { |
175 | return NCollection_Vec3 (-x(), -y(), -z()); |
176 | } |
177 | |
178 | //! Compute per-component subtraction. |
179 | NCollection_Vec3& operator-= (const NCollection_Vec3& theDec) |
180 | { |
181 | v[0] -= theDec.v[0]; |
182 | v[1] -= theDec.v[1]; |
183 | v[2] -= theDec.v[2]; |
184 | return *this; |
185 | } |
186 | |
187 | //! Compute per-component subtraction. |
188 | friend NCollection_Vec3 operator- (const NCollection_Vec3& theLeft, |
189 | const NCollection_Vec3& theRight) |
190 | { |
191 | NCollection_Vec3 aSumm = NCollection_Vec3 (theLeft); |
192 | return aSumm -= theRight; |
193 | } |
194 | |
195 | //! Compute per-component multiplication by scale factor. |
196 | void Multiply (const Element_t theFactor) |
197 | { |
198 | v[0] *= theFactor; |
199 | v[1] *= theFactor; |
200 | v[2] *= theFactor; |
201 | } |
202 | |
203 | //! Compute per-component multiplication. |
204 | NCollection_Vec3& operator*= (const NCollection_Vec3& theRight) |
205 | { |
206 | v[0] *= theRight.v[0]; |
207 | v[1] *= theRight.v[1]; |
208 | v[2] *= theRight.v[2]; |
209 | return *this; |
210 | } |
211 | |
212 | //! Compute per-component multiplication. |
213 | friend NCollection_Vec3 operator* (const NCollection_Vec3& theLeft, |
214 | const NCollection_Vec3& theRight) |
215 | { |
216 | NCollection_Vec3 aResult = NCollection_Vec3 (theLeft); |
217 | return aResult *= theRight; |
218 | } |
219 | |
220 | //! Compute per-component multiplication by scale factor. |
221 | NCollection_Vec3& operator*= (const Element_t theFactor) |
222 | { |
223 | Multiply (theFactor); |
224 | return *this; |
225 | } |
226 | |
227 | //! Compute per-component multiplication by scale factor. |
228 | NCollection_Vec3 operator* (const Element_t theFactor) const |
229 | { |
230 | return Multiplied (theFactor); |
231 | } |
232 | |
233 | //! Compute per-component multiplication by scale factor. |
234 | NCollection_Vec3 Multiplied (const Element_t theFactor) const |
235 | { |
236 | NCollection_Vec3 aCopyVec3 (*this); |
237 | aCopyVec3 *= theFactor; |
238 | return aCopyVec3; |
239 | } |
240 | |
241 | //! Compute per-component division by scale factor. |
242 | NCollection_Vec3& operator/= (const Element_t theInvFactor) |
243 | { |
244 | v[0] /= theInvFactor; |
245 | v[1] /= theInvFactor; |
246 | v[2] /= theInvFactor; |
247 | return *this; |
248 | } |
249 | |
250 | //! Compute per-component division by scale factor. |
251 | NCollection_Vec3 operator/ (const Element_t theInvFactor) |
252 | { |
253 | NCollection_Vec3 aResult (this); |
254 | return aResult /= theInvFactor; |
255 | } |
256 | |
257 | //! Computes the dot product. |
258 | Element_t Dot (const NCollection_Vec3& theOther) const |
259 | { |
260 | return x() * theOther.x() + y() * theOther.y() + z() * theOther.z(); |
261 | } |
262 | |
263 | //! Computes the vector modulus (magnitude, length). |
264 | Element_t Modulus() const |
265 | { |
266 | return std::sqrt (x() * x() + y() * y() + z() * z()); |
267 | } |
268 | |
269 | //! Computes the square of vector modulus (magnitude, length). |
270 | //! This method may be used for performance tricks. |
271 | Element_t SquareModulus() const |
272 | { |
273 | return x() * x() + y() * y() + z() * z(); |
274 | } |
275 | |
276 | //! Normalize the vector. |
277 | void Normalize() |
278 | { |
279 | Element_t aModulus = Modulus(); |
280 | if (aModulus != Element_t(0)) // just avoid divide by zero |
281 | { |
282 | x() = x() / aModulus; |
283 | y() = y() / aModulus; |
284 | z() = z() / aModulus; |
285 | } |
286 | } |
287 | |
288 | //! Normalize the vector. |
289 | NCollection_Vec3 Normalized() const |
290 | { |
291 | NCollection_Vec3 aCopy (*this); |
292 | aCopy.Normalize(); |
293 | return aCopy; |
294 | } |
295 | |
296 | //! Computes the cross product. |
297 | static NCollection_Vec3 Cross (const NCollection_Vec3& theVec1, |
298 | const NCollection_Vec3& theVec2) |
299 | { |
300 | return NCollection_Vec3(theVec1.y() * theVec2.z() - theVec1.z() * theVec2.y(), |
301 | theVec1.z() * theVec2.x() - theVec1.x() * theVec2.z(), |
302 | theVec1.x() * theVec2.y() - theVec1.y() * theVec2.x()); |
303 | } |
304 | |
305 | //! Compute linear interpolation between to vectors. |
306 | //! @param theT - interpolation coefficient 0..1; |
307 | //! @return interpolation result. |
308 | static NCollection_Vec3 GetLERP (const NCollection_Vec3& theFrom, |
309 | const NCollection_Vec3& theTo, |
310 | const Element_t theT) |
311 | { |
312 | return theFrom * (Element_t(1) - theT) + theTo * theT; |
313 | } |
314 | |
315 | //! Constuct DX unit vector. |
316 | static NCollection_Vec3 DX() |
317 | { |
318 | return NCollection_Vec3 (Element_t(1), Element_t(0), Element_t(0)); |
319 | } |
320 | |
321 | //! Constuct DY unit vector. |
322 | static NCollection_Vec3 DY() |
323 | { |
324 | return NCollection_Vec3 (Element_t(0), Element_t(1), Element_t(0)); |
325 | } |
326 | |
327 | //! Constuct DZ unit vector. |
328 | static NCollection_Vec3 DZ() |
329 | { |
330 | return NCollection_Vec3 (Element_t(0), Element_t(0), Element_t(1)); |
331 | } |
332 | |
333 | private: |
334 | |
335 | Element_t v[3]; //!< define the vector as array to avoid structure alignment issues |
336 | |
337 | }; |
338 | |
339 | //! Optimized concretization for float type. |
340 | template<> inline NCollection_Vec3<float>& NCollection_Vec3<float>::operator/= (const float theInvFactor) |
341 | { |
342 | Multiply (1.0f / theInvFactor); |
343 | return *this; |
344 | } |
345 | |
346 | //! Optimized concretization for double type. |
347 | template<> inline NCollection_Vec3<double>& NCollection_Vec3<double>::operator/= (const double theInvFactor) |
348 | { |
349 | Multiply (1.0 / theInvFactor); |
350 | return *this; |
351 | } |
352 | |
353 | #endif // _NCollection_Vec3_H__ |