29#ifndef CM_CONE_LIMIT_HELPER_H
30#define CM_CONE_LIMIT_HELPER_H
38#include "foundation/PxMathUtils.h"
46 PX_ASSERT(
PxAbs(1-tan1*tan2)>1e-6f);
47 return (tan1+tan2)/(1-tan1*tan2);
50 PX_FORCE_INLINE float computeAxisAndError(
const PxVec3& r,
const PxVec3& d,
const PxVec3& twistAxis, PxVec3& axis)
55 PxReal r2 = r.dot(r), a = 1-r2, b = 1/(1+r2), b2 = b*b;
57 PxVec3 v2(a, 2*r.z, -2*r.y);
58 PxVec3 coneLine = v1 * v2 - p;
62 PxReal dv1 = -4*rd*(3-r2)*b2*b;
63 PxVec3 dv2(-2*rd, 2*d.z, -2*d.y);
65 PxVec3 coneNormal = v1 * dv2 + dv1 * v2;
67 axis = coneLine.cross(coneNormal)/coneNormal.magnitude();
68 return coneLine.cross(axis).dot(twistAxis);
77 ConeLimitHelper(PxReal tanQSwingY, PxReal tanQSwingZ, PxReal tanQPadding)
78 : mTanQYMax(tanQSwingY), mTanQZMax(tanQSwingZ), mTanQPadding(tanQPadding) {}
85 PxReal tanQSwingYPadded = tanAdd(
PxAbs(tanQSwing.y),mTanQPadding);
86 PxReal tanQSwingZPadded = tanAdd(
PxAbs(tanQSwing.z),mTanQPadding);
87 return PxSqr(tanQSwingYPadded/mTanQYMax)+
PxSqr(tanQSwingZPadded/mTanQZMax) <= 1;
94#ifdef PX_PARANOIA_ELLIPSE_CHECK
108 bool getLimit(
const PxQuat& swing,
PxVec3& axis, PxReal& error)
const
110 PX_ASSERT(swing.w>0);
113 if(contains(tanQSwing))
116 PxVec3 normal, clamped = clamp(tanQSwing, normal);
119 PxVec3 r(0,-clamped.z,clamped.y), d(0, -normal.z, normal.y);
121 error = computeAxisAndError(r, d, twistAxis, axis);
123 PX_ASSERT(
PxAbs(axis.magnitude()-1)<1e-5f);
125#ifdef PX_PARANOIA_ELLIPSE_CHECK
126 bool inside =
PxSqr(tanQSwing.y/mTanQYMax) +
PxSqr(tanQSwing.z/mTanQZMax) <= 1;
127 PX_ASSERT(inside && error>-1e-4f || !inside && error<1e-4f);
135 PxReal mTanQYMax, mTanQZMax, mTanQPadding;
142 : mYMax(swingY), mZMax(swingZ), mPadding(padding) {}
149 PxReal swingYPadded =
PxAbs(swing.y) + mPadding;
150 PxReal swingZPadded =
PxAbs(swing.z) + mPadding;
152 return PxSqr(swingYPadded/mYMax)+
PxSqr(swingZPadded/mZMax) <= 1;
161#ifdef PX_PARANOIA_ELLIPSE_CHECK
175 bool getLimit(
const PxQuat& swing,
PxVec3& axis, PxReal& error)
const
177 PX_ASSERT(swing.w>0);
178 PxVec3 twistAxis = swing.getBasisVector0();
181 if(contains(swingAngle))
184 PxVec3 normal, clamped = clamp(swingAngle, normal);
187 PxVec3 r(0,
PxTan(clamped.y/4),
PxTan(clamped.z/4)), d(0, normal.y, normal.z);
189 error = computeAxisAndError(r, d, twistAxis, axis);
191 PX_ASSERT(
PxAbs(axis.magnitude()-1)<1e-5f);
197 PxReal mYMax, mZMax, mPadding;
Definition CmConeLimitHelper.h:139
Definition CmConeLimitHelper.h:75
This is a quaternion class. For more information on quaternion mathematics consult a mathematics sour...
Definition PxQuat.h:50
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getBasisVector0() const
Definition PxQuat.h:261
3 Element vector class.
Definition PxVec3.h:50
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAtan2(float x, float y)
Arctangent of (x/y) with correct sign. Returns angle between -PI and PI in radians Unit: Radians.
Definition PxMath.h:302
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal PxTanHalf(PxReal sin, PxReal cos)
Compute tan(theta/2) given sin(theta) and cos(theta) as inputs.
Definition PxMathUtils.h:160
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAbs(float a)
abs returns the absolute value of its argument.
Definition PxMath.h:109
PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxSqr(const PxF32 a)
square of the argument
Definition PxMath.h:170
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxEllipseClamp(const PxVec3 &point, const PxVec3 &radii)
Compute the closest point on an 2d ellipse to a given 2d point.
Definition PxMathUtils.h:178
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxTan(float a)
Tangent of an angle. Unit: Radians.
Definition PxMath.h:223