1 #ifndef __DALI_VECTOR_3_H__
2 #define __DALI_VECTOR_3_H__
5 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <cstdint> // uint32_t
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/type-traits.h>
32 * @addtogroup dali_core_math
41 * @brief A three dimensional vector.
44 struct DALI_CORE_API Vector3
53 // (x width r), (y height g), (z depth b) must be consecutive in memory.
54 // No other data must be added before (x width r) member.
55 // No virtual methods must be added to this struct.
67 * @param[in] x (or width) component
68 * @param[in] y (or height) component
69 * @param[in] z (or depth) component
71 explicit Vector3(float x, float y, float z)
79 * @brief Conversion constructor from an array of three floats.
82 * @param[in] array Array of xyz
84 explicit Vector3(const float* array)
95 * @param[in] vec2 Vector2 to create this vector from
97 explicit Vector3( const Vector2& vec2 );
100 * @brief Constructor.
103 * @param[in] vec4 Vector4 to create this vector from
105 explicit Vector3( const Vector4& vec4 );
109 static const Vector3 ONE; ///< (1.0f,1.0f,1.0f)
110 static const Vector3 XAXIS; ///< Vector representing the X axis
111 static const Vector3 YAXIS; ///< Vector representing the Y axis
112 static const Vector3 ZAXIS; ///< Vector representing the Z axis
113 static const Vector3 NEGATIVE_XAXIS; ///< Vector representing the negative X axis
114 static const Vector3 NEGATIVE_YAXIS; ///< Vector representing the negative Y axis
115 static const Vector3 NEGATIVE_ZAXIS; ///< Vector representing the negative Z axis
116 static const Vector3 ZERO; ///< (0.0f, 0.0f, 0.0f)
121 * @brief Assignment operator.
124 * @param[in] array Array of floats
127 Vector3& operator=(const float* array)
137 * @brief Assignment operator.
140 * @param[in] rhs Vector to assign
143 Vector3& operator=(const Vector2& rhs);
146 * @brief Assignment operator.
149 * @param[in] rhs Vector to assign
152 Vector3& operator=(const Vector4& rhs);
155 * @brief Addition operator.
158 * @param[in] rhs Vector to add
159 * @return A vector containing the result of the addition
161 Vector3 operator+(const Vector3& rhs) const
169 * @brief Addition assignment operator.
172 * @param[in] rhs Vector to add
175 Vector3& operator+=(const Vector3& rhs)
185 * @brief Subtraction operator.
188 * @param[in] rhs The vector to subtract
189 * @return A vector containing the result of the subtraction
191 Vector3 operator-(const Vector3& rhs) const
199 * @brief Subtraction assignment operator.
202 * @param[in] rhs The vector to subtract
205 Vector3& operator-=(const Vector3& rhs)
215 * @brief Multiplication operator.
218 * @param[in] rhs The vector to multiply
219 * @return A vector containing the result of the multiplication
221 Vector3 operator*(const Vector3& rhs) const
229 * @brief Multiplication operator.
232 * @param[in] rhs The float value to scale the vector
233 * @return A vector containing the result of the scaling
235 Vector3 operator*(float rhs) const
237 return Vector3(x * rhs, y * rhs, z * rhs);
241 * @brief Multiplication assignment operator.
244 * @param[in] rhs The vector to multiply
247 Vector3& operator*=(const Vector3& rhs)
257 * @brief Multiplication assignment operator.
260 * @param[in] rhs The float value to scale the vector
263 Vector3& operator*=(float rhs)
273 * @brief Multiplication assignment operator.
276 * @param[in] rhs The Quaternion value to multiply the vector by
279 Vector3& operator*=(const Quaternion& rhs);
282 * @brief Division operator.
285 * @param[in] rhs The vector to divide
286 * @return A vector containing the result of the division
288 Vector3 operator/(const Vector3& rhs) const
296 * @brief Division operator.
299 * @param[in] rhs The float value to scale the vector by
300 * @return A vector containing the result of the scaling
302 Vector3 operator/(float rhs) const
304 return Vector3(x / rhs, y / rhs, z / rhs);
308 * @brief Division assignment operator.
311 * @param[in] rhs The vector to divide
314 Vector3& operator/=(const Vector3& rhs)
324 * @brief Division assignment operator.
327 * @param[in] rhs The float value to scale the vector by
330 Vector3& operator/=(float rhs)
332 float oneOverRhs = 1.0f / rhs;
341 * @brief Unary negation operator.
344 * @return A vector containing the negation
346 Vector3 operator-() const
348 Vector3 temp(-x, -y, -z);
354 * @brief Equality operator.
356 * Utilizes appropriate machine epsilon values.
359 * @param[in] rhs The vector to test against
360 * @return True if the vectors are equal
362 bool operator==(const Vector3& rhs) const;
365 * @brief Inequality operator.
367 * Utilizes appropriate machine epsilon values.
370 * @param[in] rhs The vector to test against
371 * @return True if the vectors are not equal
373 bool operator!=(const Vector3& rhs) const
375 return !(*this == rhs);
379 * @brief Const array subscript operator overload.
381 * Asserts if index is out of range. Should be 0, 1 or 2.
383 * @param[in] index Subscript index
384 * @return The float at the given index
386 const float& operator[](const uint32_t index) const
388 DALI_ASSERT_ALWAYS( index < 3 && "Vector element index out of bounds" );
390 return AsFloat()[index];
394 * @brief Mutable array subscript operator overload.
396 * Asserts if index is out of range. Should be 0, 1 or 2.
398 * @param[in] index Subscript index
399 * @return The float at the given index
401 float& operator[](const uint32_t index)
403 DALI_ASSERT_ALWAYS( index < 3 && "Vector element index out of bounds" );
405 return AsFloat()[index];
409 * @brief Returns the dot product of this vector and another vector.
411 * The dot product is the length of one vector in the direction of another vector.
412 * This is great for lighting, threshold testing the angle between two unit vectors,
413 * calculating the distance between two points in a particular direction.
415 * @param[in] other The other vector
416 * @return The dot product
418 float Dot(const Vector3& other) const;
421 * @brief Returns the cross produce of this vector and another vector.
423 * The cross produce of two vectors is a vector which is perpendicular to the plane of the
424 * two vectors. This is great for calculating normals and making matrices orthogonal.
427 * @param[in] other The other vector
428 * @return The cross product
430 Vector3 Cross(const Vector3& other) const;
433 * @brief Returns the length of the vector.
436 * @return The length of the vector
438 float Length() const;
441 * @brief Returns the length of the vector squared.
443 * This is more efficient than Length() for threshold
444 * testing as it avoids the use of a square root.
446 * @return The length of the vector squared
448 float LengthSquared() const;
451 * @brief Sets the vector to be unit length, whilst maintaining its direction.
458 * @brief Clamps the vector between minimum and maximum vectors.
461 * @param[in] min The minimum vector
462 * @param[in] max The maximum vector
464 void Clamp( const Vector3& min, const Vector3& max );
467 * @brief Returns the contents of the vector as an array of 3 floats.
469 * The order of the values in this array are as follows:
470 * 0: x (or width, or r)
471 * 1: y (or height, or g)
472 * 2: z (or depth, or b)
474 * @return The vector contents as an array of 3 floats
475 * @note inlined for performance reasons (generates less code than a function call)
477 const float* AsFloat() const {return &x;}
480 * @brief Returns the contents of the vector as an array of 3 floats.
482 * The order of the values in this array are as follows:
483 * 0: x (or width, or r)
484 * 1: y (or height, or g)
485 * 2: z (or depth, or b)
487 * @return The vector contents as an array of 3 floats
488 * @note inlined for performance reasons (generates less code than a function call)
490 float* AsFloat() {return &x;}
493 * @brief Returns the x & y components (or width & height, or r & g) as a Vector2.
496 * @return The partial vector contents as Vector2 (x,y)
497 * @note inlined for performance reasons (generates less code than a function call)
499 const Vector2& GetVectorXY() const {return reinterpret_cast<const Vector2&>(x);}
502 * @brief Returns the x & y components (or width & height, or r & g) as a Vector2.
505 * @return The partial vector contents as Vector2 (x,y)
506 * @note inlined for performance reasons (generates less code than a function call)
508 Vector2& GetVectorXY() {return reinterpret_cast<Vector2&>(x);}
511 * @brief Returns the y & z components (or height & depth, or g & b) as a Vector2.
514 * @return The partial vector contents as Vector2 (y,z)
515 * @note inlined for performance reasons (generates less code than a function call)
517 const Vector2& GetVectorYZ() const {return reinterpret_cast<const Vector2&>(y);}
520 * @brief Returns the y & z components (or height & depth, or g & b) as a Vector2.
523 * @return The partial vector contents as Vector2 (y,z)
524 * @note inlined for performance reasons (generates less code than a function call)
526 Vector2& GetVectorYZ() {return reinterpret_cast<Vector2&>(y);}
531 // (x width r), (y height g), (z depth b) must be consecutive in memory.
532 // No other data must be added before (x width r) member.
533 // No virtual methods must be added to this struct.
536 float x; ///< x component
537 float width; ///< width component
538 float r; ///< red component
542 float y; ///< y component
543 float height; ///< height component
544 float g; ///< green component
548 float z; ///< z component
549 float depth; ///< depth component
550 float b; ///< blue component
555 * @brief Prints a Vector3.
558 * @param[in] o The output stream operator
559 * @param[in] vector The vector to print
560 * @return The output stream operator
562 DALI_CORE_API std::ostream& operator<< (std::ostream& o, const Vector3& vector);
565 * @brief Returns a vector with components set to the minimum of the corresponding component in a and b.
567 * If a=0,1,2 and b=2,1,0 returns a vector of 2,1,2.
569 * @param[in] a A vector
570 * @param[in] b A vector
571 * @return A vector containing the minimum of each component from a and b
573 inline Vector3 Min( const Vector3& a, const Vector3& b )
575 return Vector3( a.x < b.x ? a.x : b.x ,
576 a.y < b.y ? a.y : b.y,
577 a.z < b.z ? a.z : b.z );
581 * @brief Returns a vector with components set to the maximum of the corresponding component in a and b.
583 * If a=0,1 and b=1,0 returns a vector of 1,1.
585 * @param[in] a A vector
586 * @param[in] b A vector
587 * @return A vector containing the maximum of each component from a and b
589 inline Vector3 Max( const Vector3& a, const Vector3& b )
591 return Vector3( a.x > b.x ? a.x : b.x,
592 a.y > b.y ? a.y : b.y,
593 a.z > b.z ? a.z : b.z );
597 * @brief Clamps each of vector v's components between minimum and maximum values.
600 * @param[in] v A vector
601 * @param[in] min The minimum value
602 * @param[in] max The maximum value
603 * @return A vector containing the clamped components of v
605 DALI_CORE_API Vector3 Clamp( const Vector3& v, const float& min, const float& max );
607 // Allow Vector3 to be treated as a POD type
608 template <> struct TypeTraits< Vector3 > : public BasicTypes< Vector3 > { enum { IS_TRIVIAL_TYPE = true }; };
615 #endif // __DALI_VECTOR_3_H__