// David Eberly, Geometric Tools, Redmond WA 98052 // Copyright (c) 1998-2020 // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt // Version: 4.0.2019.08.13 #pragma once #include #include #include #include namespace WwiseGTE { template class FrenetFrame2 { public: // Construction. The curve must persist as long as the FrenetFrame2 // object does. FrenetFrame2(std::shared_ptr> const& curve) : mCurve(curve) { } // The normal is perpendicular to the tangent, rotated clockwise by // pi/2 radians. void operator()(Real t, Vector2& position, Vector2& tangent, Vector2& normal) const { std::array, 2> jet; mCurve->Evaluate(t, 1, jet.data()); position = jet[0]; tangent = jet[1]; Normalize(tangent); normal = Perp(tangent); } Real GetCurvature(Real t) const { std::array, 3> jet; mCurve->Evaluate(t, 2, jet.data()); Real speedSqr = Dot(jet[1], jet[1]); if (speedSqr > (Real)0) { Real numer = DotPerp(jet[1], jet[2]); Real denom = std::pow(speedSqr, (Real)1.5); return numer / denom; } else { // Curvature is indeterminate, just return 0. return (Real)0; } } private: std::shared_ptr> mCurve; }; template class FrenetFrame3 { public: // Construction. The curve must persist as long as the FrenetFrame3 // object does. FrenetFrame3(std::shared_ptr> const& curve) : mCurve(curve) { } // The binormal is Cross(tangent, normal). void operator()(Real t, Vector3& position, Vector3& tangent, Vector3& normal, Vector3& binormal) const { std::array, 3> jet; mCurve->Evaluate(t, 2, jet.data()); position = jet[0]; Real VDotV = Dot(jet[1], jet[1]); Real VDotA = Dot(jet[1], jet[2]); normal = VDotV * jet[2] - VDotA * jet[1]; Normalize(normal); tangent = jet[1]; Normalize(tangent); binormal = Cross(tangent, normal); } Real GetCurvature(Real t) const { std::array, 3> jet; mCurve->Evaluate(t, 2, jet.data()); Real speedSqr = Dot(jet[1], jet[1]); if (speedSqr > (Real)0) { Real numer = Length(Cross(jet[1], jet[2])); Real denom = std::pow(speedSqr, (Real)1.5); return numer / denom; } else { // Curvature is indeterminate, just return 0. return (Real)0; } } Real GetTorsion(Real t) const { std::array, 4> jet; mCurve->Evaluate(t, 3, jet.data()); Vector3 cross = Cross(jet[1], jet[2]); Real denom = Dot(cross, cross); if (denom > (Real)0) { Real numer = Dot(cross, jet[3]); return numer / denom; } else { // Torsion is indeterminate, just return 0. return (Real)0; } } private: std::shared_ptr> mCurve; }; }