// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of NVIDIA CORPORATION nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef DY_ARTICULATION_DEBUG_FNS_H #define DY_ARTICULATION_DEBUG_FNS_H #include "DyArticulationFnsScalar.h" #include "DyArticulationFnsSimd.h" namespace physx { namespace Dy { #if 0 void printMomentum(const char* id, PxTransform* pose, Cm::SpatialVector* velocity, FsInertia* inertia, PxU32 linkCount) { typedef ArticulationFnsScalar Fns; Cm::SpatialVector m = Cm::SpatialVector::zero(); for(PxU32 i=0;i Simd; typedef ArticulationFnsScalar Scalar; public: static PX_FORCE_INLINE FsInertia addInertia(const FsInertia& in1, const FsInertia& in2) { return FsInertia(M33Add(in1.ll, in2.ll), M33Add(in1.la, in2.la), M33Add(in1.aa, in2.aa)); } static PX_FORCE_INLINE FsInertia subtractInertia(const FsInertia& in1, const FsInertia& in2) { return FsInertia(M33Sub(in1.ll, in2.ll), M33Sub(in1.la, in2.la), M33Sub(in1.aa, in2.aa)); } static Mat33V invertSym33(const Mat33V &m) { PxMat33 n_ = Scalar::invertSym33(unsimdify(m)); Mat33V n = SimdBase::invertSym33(m); compare33(n_, unsimdify(n)); return n; } static Mat33V invSqrt(const Mat33V &m) { PxMat33 n_ = Scalar::invSqrt(unsimdify(m)); Mat33V n = SimdBase::invSqrt(m); compare33(n_, unsimdify(n)); return n; } static FsInertia invertInertia(const FsInertia &I) { SpInertia J_ = Scalar::invertInertia(unsimdify(I)); FsInertia J = SimdBase::invertInertia(I); compareInertias(J_,unsimdify(J)); return J; } static Mat33V computeSIS(const FsInertia &I, const Cm::SpatialVectorV S[3], Cm::SpatialVectorV*PX_RESTRICT IS) { Cm::SpatialVector IS_[3]; Scalar::multiply(IS_, unsimdify(I), unsimdify(&S[0])); PxMat33 D_ = Scalar::multiplySym(IS_, unsimdify(&S[0])); Mat33V D = SimdBase::computeSIS(I, S, IS); compare33(unsimdify(D), D_); return D; } static FsInertia multiplySubtract(const FsInertia &I, const Mat33V &D, const Cm::SpatialVectorV IS[3], Cm::SpatialVectorV*PX_RESTRICT DSI) { Cm::SpatialVector DSI_[3]; Scalar::multiply(DSI_, unsimdify(IS), unsimdify(D)); SpInertia J_ = Scalar::multiplySubtract(unsimdify(I), DSI_, unsimdify(IS)); FsInertia J = SimdBase::multiplySubtract(I, D, IS, DSI); compareInertias(unsimdify(J), J_); return J; } static FsInertia multiplySubtract(const FsInertia &I, const Cm::SpatialVectorV S[3]) { SpInertia J_ = Scalar::multiplySubtract(unsimdify(I), unsimdify(S), unsimdify(S)); FsInertia J = SimdBase::multiplySubtract(I, S); compareInertias(unsimdify(J), J_); return J; } static FsInertia translateInertia(Vec3V offset, const FsInertia &I) { PxVec3 offset_; V3StoreU(offset, offset_); SpInertia J_ = Scalar::translate(offset_, unsimdify(I)); FsInertia J = SimdBase::translateInertia(offset, I); compareInertias(J_, unsimdify(J)); return J; } static PX_FORCE_INLINE FsInertia propagate(const FsInertia &I, const Cm::SpatialVectorV S[3], const Mat33V &load, const FloatV isf) { SpInertia J_ = Scalar::propagate(unsimdify(I), unsimdify(&S[0]), unsimdify(load), unsimdify(isf)); FsInertia J = Simd::propagate(I, S, load, isf); compareInertias(J_, unsimdify(J)); return J; } static PX_FORCE_INLINE Mat33V computeDriveInertia(const FsInertia &I0, const FsInertia &I1, const Cm::SpatialVectorV S[3]) { PxMat33 m_ = Scalar::computeDriveInertia(unsimdify(I0), unsimdify(I1), unsimdify(&S[0])); Mat33V m = Simd::computeDriveInertia(I0, I1, S); compare33(m_, unsimdify(m)); return m; } static const PxMat33 unsimdify(const Mat33V &m) { PX_ALIGN(16, PxMat33) m_; PxMat33_From_Mat33V(m, m_); return m_; } static PxReal unsimdify(const FloatV &m) { PxF32 f; FStore(m, &f); return f; } static SpInertia unsimdify(const FsInertia &I) { return SpInertia (unsimdify(I.ll), unsimdify(I.la), unsimdify(I.aa)); } static const Cm::SpatialVector* unsimdify(const Cm::SpatialVectorV *S) { return reinterpret_cast(S); } private: static PxReal absmax(const PxVec3& n) { return PxMax(PxAbs(n.x), PxMax(PxAbs(n.y),PxAbs(n.z))); } static PxReal norm(const PxMat33& n) { return PxMax(absmax(n.column0), PxMax(absmax(n.column1), absmax(n.column2))); } static void compare33(const PxMat33& ref, const PxMat33& n) { PxReal errNorm = norm(ref-n); PX_UNUSED(errNorm); PX_ASSERT(errNorm <= PxMax(norm(ref)*1e-3f, 1e-4f)); } static void compareInertias(const SpInertia& a, const SpInertia& b) { compare33(a.mLL, b.mLL); compare33(a.mLA, b.mLA); compare33(a.mAA, b.mAA); } }; #if DY_ARTICULATION_DEBUG_VERIFY static bool isPositiveDefinite(const Mat33V& m) { PX_ALIGN_PREFIX(16) PxMat33 m1 PX_ALIGN_SUFFIX(16); PxMat33_From_Mat33V(m, m1); return isPositiveDefinite(m1); } static bool isPositiveDefinite(const FsInertia& s) { return isPositiveDefinite(ArticulationFnsDebug::unsimdify(s)); } static PxReal magnitude(const Cm::SpatialVectorV &v) { return PxSqrt(FStore(V3Dot(v.linear, v.linear)) + FStore(V3Dot(v.angular, v.angular))); } static bool almostEqual(const Cm::SpatialVectorV &ref, const Cm::SpatialVectorV& test, PxReal tolerance) { return magnitude(ref-test)<=tolerance*magnitude(ref); } #endif } } #endif //DY_ARTICULATION_DEBUG_FNS_H