2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include <dali/public-api/math/vector3.h>
19 #include <dali/public-api/math/quaternion.h>
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/math/vector2.h>
27 #include <dali/public-api/math/vector4.h>
28 #include <dali/public-api/math/math-utils.h>
29 #include <dali/internal/render/common/performance-monitor.h>
33 using Internal::PerformanceMonitor;
35 const Vector3 Vector3::ONE(1.0f, 1.0f, 1.0f);
36 const Vector3 Vector3::XAXIS(1.0f, 0.0f, 0.0f);
37 const Vector3 Vector3::YAXIS(0.0f, 1.0f, 0.0f);
38 const Vector3 Vector3::ZAXIS(0.0f, 0.0f, 1.0f);
39 const Vector3 Vector3::NEGATIVE_XAXIS(-1.0f, 0.0f, 0.0f);
40 const Vector3 Vector3::NEGATIVE_YAXIS(0.0f, -1.0f, 0.0f);
41 const Vector3 Vector3::NEGATIVE_ZAXIS(0.0f, 0.0f, -1.0f);
42 const Vector3 Vector3::ZERO(0.0f, 0.0f, 0.0f);
44 Vector3::Vector3( const Vector2& vec2 )
51 Vector3::Vector3( const Vector4& vec4 )
58 Vector3& Vector3::operator=(const Vector2& rhs)
67 Vector3& Vector3::operator=(const Vector4& rhs)
76 Vector3& Vector3::operator*=(const Quaternion& rhs)
78 // nVidia SDK implementation
79 Vector3 qvec(rhs.mVector.x, rhs.mVector.y, rhs.mVector.z);
81 Vector3 uv( (qvec.y * z) - (qvec.z * y),
82 (qvec.z * x) - (qvec.x * z),
83 (qvec.x * y) - (qvec.y * x) );
85 Vector3 uuv( (qvec.y * uv.z) - (qvec.z * uv.y),
86 (qvec.z * uv.x) - (qvec.x * uv.z),
87 (qvec.x * uv.y) - (qvec.y * uv.x) );
91 x += (uv.x + uuv.x) * 2.0f;
92 y += (uv.y + uuv.y) * 2.0f;
93 z += (uv.z + uuv.z) * 2.0f;
98 bool Vector3::operator==(const Vector3& rhs) const
100 if (fabsf(x - rhs.x) > GetRangedEpsilon(x, rhs.x) )
104 if (fabsf(y - rhs.y) > GetRangedEpsilon(y, rhs.y) )
108 if (fabsf(z - rhs.z) > GetRangedEpsilon(z, rhs.z) )
116 float Vector3::Dot(const Vector3 &other) const
118 MATH_INCREASE_BY(PerformanceMonitor::FLOAT_POINT_MULTIPLY,3);
120 return x * other.x + y * other.y + z * other.z;
123 Vector3 Vector3::Cross(const Vector3 &other) const
125 MATH_INCREASE_BY(PerformanceMonitor::FLOAT_POINT_MULTIPLY,6);
127 return Vector3( (y * other.z) - (z * other.y),
128 (z * other.x) - (x * other.z),
129 (x * other.y) - (y * other.x));
132 float Vector3::Length() const
134 MATH_INCREASE_BY(PerformanceMonitor::FLOAT_POINT_MULTIPLY,3);
136 return sqrtf(x*x + y*y + z*z);
139 float Vector3::LengthSquared() const
141 MATH_INCREASE_BY(PerformanceMonitor::FLOAT_POINT_MULTIPLY,3);
143 return x*x + y*y + z*z;
146 void Vector3::Normalize()
148 float length = Length();
149 if( ! EqualsZero(length) )
151 MATH_INCREASE_BY(PerformanceMonitor::FLOAT_POINT_MULTIPLY,3);
153 const float inverseLength = 1.0f / length;
160 void Vector3::Clamp( const Vector3& min, const Vector3& max )
162 Dali::ClampInPlace<float>( x, min.x, max.x );
163 Dali::ClampInPlace<float>( y, min.y, max.y );
164 Dali::ClampInPlace<float>( z, min.z, max.z );
167 std::ostream& operator<< (std::ostream& o, const Vector3& vector)
169 return o << "[" << vector.x << ", " << vector.y << ", " << vector.z << "]";
172 Vector3 Clamp( const Vector3& v, const float& min, const float& max )
175 result.Clamp( Vector3( min, min, min ) , Vector3( max, max, max ) );
180 Vector3 FitKeepAspectRatio( const Vector3& target, const Vector3& source )
184 if ( fabsf(source.x) > 0.0f )
186 scale = target.x / source.x;
189 if ( fabsf(source.y) > 0.0f )
191 if ( scale > Math::MACHINE_EPSILON_1 )
193 scale = std::min( scale, target.y / source.y );
197 scale = target.y / source.y;
201 if ( fabsf(source.z) > 0.0f )
203 if ( scale > Math::MACHINE_EPSILON_1 )
205 scale = std::min( scale, target.z / source.z );
209 scale = target.z / source.z;
213 if ( scale < Math::MACHINE_EPSILON_1 )
218 return Vector3( scale, scale, scale );
221 Vector3 FillKeepAspectRatio( const Vector3& target, const Vector3& source )
225 if ( fabsf(source.x) > 0.0f )
227 scale = target.x / source.x;
230 if ( fabsf(source.y) > 0.0f )
232 if ( scale > Math::MACHINE_EPSILON_1 )
234 scale = std::max( scale, target.y / source.y );
238 scale = target.y / source.y;
242 if ( fabsf(source.z) > 0.0f )
244 if ( scale > Math::MACHINE_EPSILON_1 )
246 scale = std::max( scale, target.z / source.z );
250 scale = target.z / source.z;
254 if ( scale < Math::MACHINE_EPSILON_1 )
259 return Vector3( scale, scale, scale );
262 Vector3 FillXYKeepAspectRatio( const Vector3& target, const Vector3& source )
266 if ( fabsf(source.x) > 0.0f )
268 scale = target.x / source.x;
271 if ( fabsf(source.y) > 0.0f )
273 if ( scale > Math::MACHINE_EPSILON_1 )
275 scale = std::max( scale, target.y / source.y );
279 scale = target.y / source.y;
283 if ( scale < Math::MACHINE_EPSILON_1 )
288 return Vector3( scale, scale, scale );
291 Vector3 ShrinkInsideKeepAspectRatio( const Vector3& target, const Vector3& source )
293 // calculate source size vs target size to see if we need to shrink
294 float widthScale = 1.0f;
295 if( target.width < source.width )
297 // not enough width, width needs to shrink
298 widthScale = target.width / source.width;
300 float heightScale = 1.0f;
301 if( target.height < source.height )
303 // not enough height, height needs to shrink
304 heightScale = target.height / source.height;
306 float depthScale = 1.0f;
307 if( target.depth < source.depth )
309 // not enough depth, depth needs to shrink
310 depthScale = target.depth / source.depth;
312 // use smaller of the scales
313 float scale = std::min( std::min( widthScale, heightScale ), depthScale );
315 // check if we need to scale
318 // scale natural size to fit inside
319 return Vector3( scale, scale, scale );
321 // there is enough space so use source size