Explorar o código

Added a few math and node convenience functions

Nick Royer %!s(int64=12) %!d(string=hai) anos
pai
achega
0e84a2a2d9

+ 9 - 1
Source/Engine/Math/MathDefs.h

@@ -32,7 +32,7 @@ namespace Urho3D
 
 #undef M_PI
 static const float M_PI = 3.14159265358979323846264338327950288f;
-
+static const float M_HALF_PI = M_PI * 0.5f;
 static const int M_MIN_INT = 0x80000000;
 static const int M_MAX_INT = 0x7fffffff;
 static const unsigned M_MIN_UNSIGNED = 0x00000000;
@@ -80,6 +80,14 @@ inline float Clamp(float value, float min, float max)
         return value;
 }
 
+/// Smoothly damp between values
+inline float SmoothStep(float lhs, float rhs, float t)
+{
+    t = Clamp((t - lhs)/(rhs-lhs), 0, 1); //Saturate t
+    return t*t*(3-2*t);
+}
+
+
 /// Return sine of an angle in degrees.
 inline float Sin(float angle) { return sinf(angle * M_DEGTORAD); }
 /// Return cosine of an angle in degrees.

+ 29 - 0
Source/Engine/Math/Quaternion.cpp

@@ -145,6 +145,23 @@ void Quaternion::FromRotationMatrix(const Matrix3& matrix)
     }
 }
 
+void Quaternion::FromLookRotation(const Vector3& direction, const Vector3& upDirection)
+{
+    Vector3 forward = direction.Normalized();
+    Vector3 v = forward.CrossProduct(upDirection).Normalized(); 
+    Vector3 up = v.CrossProduct(forward);
+    Vector3 right = up.CrossProduct(forward);
+
+    Quaternion ret;
+    ret.w_ = sqrtf(1.0f + right.x_ + up.y_ + forward.z_) * 0.5f;
+    float w4_recip = 1.0f / (4.0f * ret.w_);
+    ret.x_ = (up.z_ - forward.y_) * w4_recip;
+    ret.y_ = (forward.x_ - right.z_) * w4_recip;
+    ret.z_ = (right.y_ - up.x_) * w4_recip;
+
+    (*this) = ret;
+}
+
 Vector3 Quaternion::EulerAngles() const
 {
     // Derivation from http://www.geometrictools.com/Documentation/EulerAngles.pdf
@@ -236,6 +253,18 @@ Quaternion Quaternion::Slerp(Quaternion rhs, float t) const
     return *this * t1 + rhs * t2;
 }
 
+Quaternion Quaternion::Nlerp(Quaternion rhs, float t, bool shortestPath) const
+{
+    Quaternion result;
+    float fCos = DotProduct(rhs);
+    if (fCos < 0.0f && shortestPath)
+        result = (*this) + (((-rhs) - (*this)) * t);
+    else
+        result = (*this) + ((rhs - (*this)) * t);
+    result.Normalize();
+    return result;
+}
+
 String Quaternion::ToString() const
 {
     char tempBuffer[CONVERSION_BUFFER_LENGTH];

+ 5 - 1
Source/Engine/Math/Quaternion.h

@@ -171,7 +171,9 @@ public:
     void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
     /// Define from a rotation matrix.
     void FromRotationMatrix(const Matrix3& matrix);
-    
+    /// Define from a direction to look in and an up direction
+    void FromLookRotation(const Vector3& direction, const Vector3&up = Vector3::UP);
+
     /// Normalize to unit length.
     void Normalize()
     {
@@ -232,6 +234,8 @@ public:
     Matrix3 RotationMatrix() const;
     /// Spherical interpolation with another quaternion.
     Quaternion Slerp(Quaternion rhs, float t) const;
+    /// Normalized inear interpolation with another quaternion.   
+    Quaternion Nlerp(Quaternion rhs, float t, bool shortestPath = false) const;
     /// Return float data.
     const float* Data() const { return &w_; }
     /// Return as string.

+ 23 - 0
Source/Engine/Scene/Node.h

@@ -199,6 +199,11 @@ public:
     const Quaternion& GetRotation() const { return rotation_; }
     /// Return forward direction in parent space. Positive Z axis equals identity rotation.
     Vector3 GetDirection() const { return rotation_ * Vector3::FORWARD; }
+    /// Return up direction in parent space. Positive Y axis equals identity rotation.
+    Vector3 GetUp() const { return rotation_ * Vector3::UP; }
+    /// Return right direction in parent space. Positive X axis equals identity rotation.
+    Vector3 GetRight() const { return rotation_ * Vector3::RIGHT; }
+
     /// Return scale in parent space.
     const Vector3& GetScale() const { return scale_; }
     /// Return parent space transform matrix.
@@ -231,6 +236,24 @@ public:
         return worldRotation_ * Vector3::FORWARD;
     }
 
+    /// Return node's up vector in world space.
+    Vector3 GetWorldUp() const
+    {
+        if (dirty_)
+            UpdateWorldTransform();
+        
+        return worldRotation_ * Vector3::UP;
+    }
+
+    /// Return node's right vector in world space.
+    Vector3 GetWorldRight() const
+    {
+        if (dirty_)
+            UpdateWorldTransform();
+        
+        return worldRotation_ * Vector3::RIGHT;
+    }
+
     /// Return scale in world space.
     Vector3 GetWorldScale() const
     {