| 1 | /* | 
| 2 |  * Copyright (c) 2008-2015, NVIDIA CORPORATION.  All rights reserved. | 
| 3 |  * | 
| 4 |  * NVIDIA CORPORATION and its licensors retain all intellectual property | 
| 5 |  * and proprietary rights in and to this software, related documentation | 
| 6 |  * and any modifications thereto.  Any use, reproduction, disclosure or | 
| 7 |  * distribution of this software and related documentation without an express | 
| 8 |  * license agreement from NVIDIA CORPORATION is strictly prohibited. | 
| 9 |  */ | 
| 10 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. | 
| 11 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved.   | 
| 12 |  | 
| 13 |  | 
| 14 | #ifndef PX_EXTENSIONS_JOINT_LIMIT | 
| 15 | #define PX_EXTENSIONS_JOINT_LIMIT | 
| 16 | /** \addtogroup extensions | 
| 17 |   @{ | 
| 18 | */ | 
| 19 |  | 
| 20 | #include "foundation/PxMath.h" | 
| 21 | #include "PxPhysXConfig.h" | 
| 22 | #include "common/PxTolerancesScale.h" | 
| 23 | #include "PxJoint.h" | 
| 24 |  | 
| 25 | #ifndef PX_DOXYGEN | 
| 26 | namespace physx | 
| 27 | { | 
| 28 | #endif | 
| 29 |  | 
| 30 | /** | 
| 31 | \brief Describes the parameters for a joint limit.  | 
| 32 |  | 
| 33 | Limits are enabled or disabled by setting flags or other configuration parameters joints, see the | 
| 34 | documentation for specific joint types for details. | 
| 35 |  | 
| 36 | @see  | 
| 37 | */ | 
| 38 |  | 
| 39 | class PxJointLimitParameters | 
| 40 | { | 
| 41 | //= ATTENTION! ===================================================================================== | 
| 42 | // Changing the data layout of this class breaks the binary serialization format.  See comments for  | 
| 43 | // PX_BINARY_SERIAL_VERSION.  If a modification is required, please adjust the getBinaryMetaData  | 
| 44 | // function.  If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION | 
| 45 | // accordingly. | 
| 46 | //================================================================================================== | 
| 47 | public: | 
| 48 | 	/** | 
| 49 | 	\brief Controls the amount of bounce when the joint hits a limit. | 
| 50 |  | 
| 51 | 	A restitution value of 1.0 causes the joint to bounce back with the velocity which it hit the limit. | 
| 52 | 	A value of zero causes the joint to stop dead. | 
| 53 |  | 
| 54 | 	In situations where the joint has many locked DOFs (e.g. 5) the restitution may not be applied  | 
| 55 | 	correctly. This is due to a limitation in the solver which causes the restitution velocity to become zero  | 
| 56 | 	as the solver enforces constraints on the other DOFs. | 
| 57 |  | 
| 58 | 	This limitation applies to both angular and linear limits, however it is generally most apparent with limited | 
| 59 | 	angular DOFs. Disabling joint projection and increasing the solver iteration count may improve this behavior  | 
| 60 | 	to some extent. | 
| 61 |  | 
| 62 | 	Also, combining soft joint limits with joint drives driving against those limits may affect stability. | 
| 63 |  | 
| 64 | 	<b>Range:</b> [0,1]<br> | 
| 65 | 	<b>Default:</b> 0.0 | 
| 66 | 	*/ | 
| 67 | 	PxReal restitution; | 
| 68 |  | 
| 69 |  | 
| 70 | 	/** | 
| 71 | 	determines the minimum impact velocity which will cause the joint to bounce | 
| 72 | 	*/ | 
| 73 |  | 
| 74 | 	PxReal bounceThreshold; | 
| 75 | 	/** | 
| 76 | 	\brief if greater than zero, the limit is soft, i.e. a spring pulls the joint back to the limit | 
| 77 |  | 
| 78 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 79 | 	<b>Default:</b> 0.0 | 
| 80 | 	*/ | 
| 81 | 	PxReal stiffness; | 
| 82 |  | 
| 83 | 	/** | 
| 84 | 	\brief if spring is greater than zero, this is the damping of the limit spring | 
| 85 |  | 
| 86 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 87 | 	<b>Default:</b> 0.0 | 
| 88 | 	*/ | 
| 89 | 	PxReal damping; | 
| 90 |  | 
| 91 | 	/** | 
| 92 | 	\brief the distance inside the limit value at which the limit will be considered to be active by the | 
| 93 | 	solver.  As this value is made larger, the limit becomes active more quickly. It thus becomes less  | 
| 94 | 	likely to violate the extents of the limit, but more expensive. | 
| 95 | 	 | 
| 96 | 	The contact distance should be less than the limit angle or distance, and in the case of a pair limit, | 
| 97 | 	less than half the distance between the upper and lower bounds. Exceeding this value will result in | 
| 98 | 	the limit being active all the time. | 
| 99 |  | 
| 100 | 	Making this value too small can result in jitter around the limit. | 
| 101 |  | 
| 102 | 	<b>Default:</b> depends on the joint | 
| 103 |  | 
| 104 | 	@see PxPhysics::getTolerancesScale() | 
| 105 | 	*/ | 
| 106 |  | 
| 107 | 	PxReal contactDistance; | 
| 108 |  | 
| 109 |  | 
| 110 |  | 
| 111 | 	PxJointLimitParameters() | 
| 112 | 	: restitution(0) | 
| 113 | 	, bounceThreshold(0) | 
| 114 | 	, stiffness(0) | 
| 115 | 	, damping(0) | 
| 116 | 	, contactDistance(0) | 
| 117 | 	{ | 
| 118 | 	}	 | 
| 119 |  | 
| 120 | 	/** | 
| 121 | 	\brief Returns true if the current settings are valid. | 
| 122 |  | 
| 123 | 	\return true if the current settings are valid | 
| 124 | 	*/ | 
| 125 | 	PX_INLINE bool isValid() const | 
| 126 | 	{ | 
| 127 | 		return	PxIsFinite(restitution) && restitution >= 0 && restitution <= 1 &&  | 
| 128 | 			    PxIsFinite(stiffness) && stiffness >= 0 &&  | 
| 129 | 			    PxIsFinite(damping) && damping >= 0 && | 
| 130 | 				PxIsFinite(bounceThreshold) && bounceThreshold >= 0 && | 
| 131 | 				PxIsFinite(contactDistance) && contactDistance >= 0; | 
| 132 | 	} | 
| 133 |  | 
| 134 | 	PX_INLINE bool isSoft() const | 
| 135 | 	{ | 
| 136 | 		return damping>0 || stiffness>0; | 
| 137 | 	} | 
| 138 |  | 
| 139 | protected: | 
| 140 | 	~PxJointLimitParameters() {} | 
| 141 | }; | 
| 142 |  | 
| 143 |  | 
| 144 | /** | 
| 145 | \brief Describes a one-sided linear limit. | 
| 146 | */ | 
| 147 | class PxJointLinearLimit : public PxJointLimitParameters | 
| 148 | { | 
| 149 | //= ATTENTION! ===================================================================================== | 
| 150 | // Changing the data layout of this class breaks the binary serialization format.  See comments for  | 
| 151 | // PX_BINARY_SERIAL_VERSION.  If a modification is required, please adjust the getBinaryMetaData  | 
| 152 | // function.  If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION | 
| 153 | // accordingly. | 
| 154 | //================================================================================================== | 
| 155 | public: | 
| 156 | 	/** | 
| 157 | 	\brief the extent of the limit.  | 
| 158 |  | 
| 159 | 	<b>Range:</b> (0, PX_MAX_F32) <br> | 
| 160 | 	<b>Default:</b> PX_MAX_F32 | 
| 161 | 	*/ | 
| 162 | 	PxReal value; | 
| 163 |  | 
| 164 | 	/** | 
| 165 | 	\brief construct a linear hard limit | 
| 166 |  | 
| 167 | 	\param[in] scale a PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object. | 
| 168 | 	\param[in] extent the extent of the limit | 
| 169 | 	\param[in] contactDist the distance from the limit at which it becomes active. Default is 0.01f scaled by the tolerance length scale | 
| 170 |  | 
| 171 | 	@see PxJointLimitParameters PxTolerancesScale | 
| 172 | 	*/ | 
| 173 |  | 
| 174 | 	PxJointLinearLimit(const PxTolerancesScale& scale, PxReal extent, PxReal contactDist = -1) | 
| 175 | 	: value(extent) | 
| 176 | 	{ | 
| 177 | 		PxJointLimitParameters::contactDistance = contactDist == -1 ? 0.01f*scale.length : contactDist;  | 
| 178 | 	} | 
| 179 |  | 
| 180 |  | 
| 181 | 	/** | 
| 182 | 	\brief construct a linear soft limit  | 
| 183 |  | 
| 184 | 	\param[in] extent the extent of the limit | 
| 185 | 	\param[in] spring the stiffness and damping parameters for the limit spring | 
| 186 |  | 
| 187 | 	@see PxJointLimitParameters PxTolerancesScale | 
| 188 | 	*/ | 
| 189 |  | 
| 190 | 	PxJointLinearLimit(PxReal extent, const PxSpring& spring) | 
| 191 | 	: value(extent) | 
| 192 | 	{ | 
| 193 | 		stiffness = spring.stiffness; | 
| 194 | 		damping = spring.damping; | 
| 195 | 	} | 
| 196 |  | 
| 197 |  | 
| 198 |  | 
| 199 | 	/** | 
| 200 | 	\brief Returns true if the limit is valid | 
| 201 |  | 
| 202 | 	\return true if the current settings are valid | 
| 203 | 	*/ | 
| 204 | 	PX_INLINE bool isValid() const | 
| 205 | 	{ | 
| 206 | 		return PxJointLimitParameters::isValid() && | 
| 207 | 			   PxIsFinite(value) &&  | 
| 208 | 			   value > 0; | 
| 209 | 	} | 
| 210 | }; | 
| 211 |  | 
| 212 |  | 
| 213 | /** | 
| 214 | \brief Describes a two-sided limit. | 
| 215 | */ | 
| 216 |  | 
| 217 | class PxJointLinearLimitPair : public PxJointLimitParameters | 
| 218 | { | 
| 219 | //= ATTENTION! ===================================================================================== | 
| 220 | // Changing the data layout of this class breaks the binary serialization format.  See comments for  | 
| 221 | // PX_BINARY_SERIAL_VERSION.  If a modification is required, please adjust the getBinaryMetaData  | 
| 222 | // function.  If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION | 
| 223 | // accordingly. | 
| 224 | //================================================================================================== | 
| 225 | public: | 
| 226 | 	/** | 
| 227 | 	\brief the range of the limit. The upper limit must be no lower than the | 
| 228 | 	lower limit, and if they are equal the limited degree of freedom will be treated as locked. | 
| 229 |  | 
| 230 | 	<b>Unit:</b> Angular: Radians | 
| 231 | 	<b>Range:</b> See the joint on which the limit is used for details<br> | 
| 232 | 	<b>Default:</b> 0.0 | 
| 233 | 	*/ | 
| 234 | 	PxReal upper, lower; | 
| 235 |  | 
| 236 |  | 
| 237 | 	/** | 
| 238 | 	\brief Construct a linear hard limit pair. The lower distance value must be less than the upper distance value.  | 
| 239 |  | 
| 240 | 	\param[in] scale a PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object. | 
| 241 | 	\param[in] lowerLimit the lower distance of the limit | 
| 242 | 	\param[in] upperLimit the upper distance of the limit | 
| 243 | 	\param[in] contactDist the distance from the limit at which it becomes active. Default is the lesser of 0.01f scaled by the tolerance length scale, and 0.49 * (upperLimit - lowerLimit) | 
| 244 |  | 
| 245 | 	@see PxJointLimitParameters PxTolerancesScale | 
| 246 | 	*/ | 
| 247 |  | 
| 248 | 	PxJointLinearLimitPair(const PxTolerancesScale& scale, PxReal lowerLimit, PxReal upperLimit, PxReal contactDist = -1) | 
| 249 | 	: upper(upperLimit) | 
| 250 | 	, lower(lowerLimit) | 
| 251 | 	{ | 
| 252 | 		PxJointLimitParameters::contactDistance = contactDist == -1 ? PxMin(scale.length * 0.01f, (upperLimit*0.49f-lowerLimit*0.49f)) : contactDist;  | 
| 253 | 		bounceThreshold = 2*scale.length; | 
| 254 | 	} | 
| 255 |  | 
| 256 |  | 
| 257 | 	/** | 
| 258 | 	\brief construct a linear soft limit pair | 
| 259 |  | 
| 260 | 	\param[in] lowerLimit the lower distance of the limit | 
| 261 | 	\param[in] upperLimit the upper distance of the limit | 
| 262 | 	\param[in] spring the stiffness and damping parameters of the limit spring | 
| 263 |  | 
| 264 | 	@see PxJointLimitParameters PxTolerancesScale | 
| 265 | 	*/ | 
| 266 |  | 
| 267 | 	PxJointLinearLimitPair(PxReal lowerLimit, PxReal upperLimit, const PxSpring& spring) | 
| 268 | 	: upper(upperLimit) | 
| 269 | 	, lower(lowerLimit) | 
| 270 | 	{ | 
| 271 | 		stiffness = spring.stiffness; | 
| 272 | 		damping = spring.damping; | 
| 273 | 	} | 
| 274 |  | 
| 275 |  | 
| 276 | 	/** | 
| 277 | 	\brief Returns true if the limit is valid. | 
| 278 |  | 
| 279 | 	\return true if the current settings are valid | 
| 280 | 	*/ | 
| 281 | 	PX_INLINE bool isValid() const | 
| 282 | 	{ | 
| 283 | 		return PxJointLimitParameters::isValid() && | 
| 284 | 			   PxIsFinite(upper) && PxIsFinite(lower) && upper >= lower && | 
| 285 | 			   PxIsFinite(upper - lower) &&  | 
| 286 | 			   PxIsFinite(contactDistance) && contactDistance <= upper - lower; | 
| 287 | 	} | 
| 288 | }; | 
| 289 |  | 
| 290 |  | 
| 291 | class PxJointAngularLimitPair : public PxJointLimitParameters | 
| 292 | { | 
| 293 | //= ATTENTION! ===================================================================================== | 
| 294 | // Changing the data layout of this class breaks the binary serialization format.  See comments for  | 
| 295 | // PX_BINARY_SERIAL_VERSION.  If a modification is required, please adjust the getBinaryMetaData  | 
| 296 | // function.  If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION | 
| 297 | // accordingly. | 
| 298 | //================================================================================================== | 
| 299 | public: | 
| 300 | 	/** | 
| 301 | 	\brief the range of the limit. The upper limit must be no lower than the lower limit. | 
| 302 |  | 
| 303 | 	<b>Unit:</b> Angular: Radians | 
| 304 | 	<b>Range:</b> See the joint on which the limit is used for details<br> | 
| 305 | 	<b>Default:</b> 0.0 | 
| 306 | 	*/ | 
| 307 | 	PxReal upper, lower; | 
| 308 |  | 
| 309 |  | 
| 310 | 	/** | 
| 311 | 	\brief construct an angular hard limit pair.  | 
| 312 | 	 | 
| 313 | 	The lower value must be less than the upper value.  | 
| 314 |  | 
| 315 | 	\param[in] lowerLimit the lower angle of the limit | 
| 316 | 	\param[in] upperLimit the upper angle of the limit | 
| 317 | 	\param[in] contactDist the distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * (upperLimit - lowerLimit) | 
| 318 |  | 
| 319 | 	@see PxJointLimitParameters | 
| 320 | 	*/ | 
| 321 |  | 
| 322 | 	PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit, PxReal contactDist = -1) | 
| 323 | 	: upper(upperLimit) | 
| 324 | 	, lower(lowerLimit) | 
| 325 | 	{ | 
| 326 | 		PxJointLimitParameters::contactDistance = contactDist ==-1 ? PxMin(0.1f, 0.49f*(upperLimit-lowerLimit)) : contactDist; | 
| 327 | 		bounceThreshold = 0.5f; | 
| 328 | 	} | 
| 329 |  | 
| 330 |  | 
| 331 | 	/** | 
| 332 | 	\brief construct an angular soft limit pair.  | 
| 333 | 	 | 
| 334 | 	The lower value must be less than the upper value.  | 
| 335 |  | 
| 336 | 	\param[in] lowerLimit the lower angle of the limit | 
| 337 | 	\param[in] upperLimit the upper angle of the limit | 
| 338 | 	\param[in] spring the stiffness and damping of the limit spring | 
| 339 |  | 
| 340 | 	@see PxJointLimitParameters | 
| 341 | 	*/ | 
| 342 |  | 
| 343 | 	PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit, const PxSpring& spring) | 
| 344 | 	: upper(upperLimit) | 
| 345 | 	, lower(lowerLimit) | 
| 346 | 	{ | 
| 347 | 		stiffness = spring.stiffness; | 
| 348 | 		damping = spring.damping; | 
| 349 | 	} | 
| 350 |  | 
| 351 |  | 
| 352 | 	/** | 
| 353 | 	\brief Returns true if the limit is valid. | 
| 354 |  | 
| 355 | 	\return true if the current settings are valid | 
| 356 | 	*/ | 
| 357 | 	PX_INLINE bool isValid() const | 
| 358 | 	{ | 
| 359 | 		return PxJointLimitParameters::isValid() && | 
| 360 | 			   PxIsFinite(upper) && PxIsFinite(lower) && upper >= lower && | 
| 361 | 			   PxIsFinite(contactDistance) && contactDistance <= upper - lower; | 
| 362 | 	} | 
| 363 | }; | 
| 364 |  | 
| 365 |  | 
| 366 |  | 
| 367 | /** | 
| 368 | \brief Describes an elliptical conical joint limit. Note that very small or highly elliptical limit cones may  | 
| 369 | result in jitter. | 
| 370 |  | 
| 371 | @see PxD6Joint PxSphericalJoint | 
| 372 | */ | 
| 373 |  | 
| 374 | class PxJointLimitCone : public PxJointLimitParameters | 
| 375 | { | 
| 376 | //= ATTENTION! ===================================================================================== | 
| 377 | // Changing the data layout of this class breaks the binary serialization format.  See comments for  | 
| 378 | // PX_BINARY_SERIAL_VERSION.  If a modification is required, please adjust the getBinaryMetaData  | 
| 379 | // function.  If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION | 
| 380 | // accordingly. | 
| 381 | //================================================================================================== | 
| 382 | public: | 
| 383 | 	/** | 
| 384 | 	\brief the maximum angle from the Y axis of the constraint frame. | 
| 385 |  | 
| 386 | 	<b>Unit:</b> Angular: Radians | 
| 387 | 	<b>Range:</b> Angular: (0,PI)<br> | 
| 388 | 	<b>Default:</b> PI/2 | 
| 389 | 	*/ | 
| 390 | 	PxReal yAngle; | 
| 391 |  | 
| 392 |  | 
| 393 | 	/** | 
| 394 | 	\brief the maximum angle from the Z-axis of the constraint frame. | 
| 395 |  | 
| 396 | 	<b>Unit:</b> Angular: Radians | 
| 397 | 	<b>Range:</b> Angular: (0,PI)<br> | 
| 398 | 	<b>Default:</b> PI/2 | 
| 399 | 	*/ | 
| 400 | 	PxReal zAngle; | 
| 401 |  | 
| 402 | 	/** | 
| 403 | 	\brief Construct a cone hard limit.  | 
| 404 |  | 
| 405 | 	\param[in] yLimitAngle the limit angle from the Y-axis of the constraint frame | 
| 406 | 	\param[in] zLimitAngle the limit angle from the Z-axis of the constraint frame | 
| 407 | 	\param[in] contactDist the distance from the limit at which it becomes active. 	Default is the lesser of 0.1 radians, and 0.49 * the lower of the limit angles | 
| 408 |  | 
| 409 | 	@see PxJointLimitParameters | 
| 410 | 	*/ | 
| 411 |  | 
| 412 | 	PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, PxReal contactDist = -1): | 
| 413 | 	  yAngle(yLimitAngle), | 
| 414 | 	  zAngle(zLimitAngle) | 
| 415 | 	  { | 
| 416 | 			PxJointLimitParameters::contactDistance = contactDist == -1 ? PxMin(0.1f, PxMin(yLimitAngle, zLimitAngle)*0.49f) : contactDist; | 
| 417 | 			bounceThreshold = 0.5f; | 
| 418 | 	  } | 
| 419 |  | 
| 420 |  | 
| 421 | 	 | 
| 422 | 	/** | 
| 423 | 	\brief Construct a cone soft limit.  | 
| 424 |  | 
| 425 | 	\param[in] yLimitAngle the limit angle from the Y-axis of the constraint frame | 
| 426 | 	\param[in] zLimitAngle the limit angle from the Z-axis of the constraint frame | 
| 427 | 	\param[in] spring the stiffness and damping of the limit spring | 
| 428 |  | 
| 429 | 	@see PxJointLimitParameters | 
| 430 | 	*/ | 
| 431 |  | 
| 432 | 	  PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, const PxSpring& spring): | 
| 433 | 	  yAngle(yLimitAngle), | 
| 434 | 	  zAngle(zLimitAngle) | 
| 435 | 	  { | 
| 436 | 		  stiffness = spring.stiffness; | 
| 437 | 		  damping = spring.damping; | 
| 438 | 	  } | 
| 439 |  | 
| 440 |  | 
| 441 | 	/** | 
| 442 | 	\brief Returns true if the limit is valid. | 
| 443 |  | 
| 444 | 	\return true if the current settings are valid | 
| 445 | 	*/ | 
| 446 | 	PX_INLINE bool isValid() const | 
| 447 | 	{ | 
| 448 | 		return PxJointLimitParameters::isValid() && | 
| 449 | 			   PxIsFinite(yAngle) && yAngle>0 && yAngle<PxPi &&  | 
| 450 | 			   PxIsFinite(zAngle) && zAngle>0 && zAngle<PxPi; | 
| 451 | 	} | 
| 452 | }; | 
| 453 |  | 
| 454 | #ifndef PX_DOXYGEN | 
| 455 | } // namespace physx | 
| 456 | #endif | 
| 457 |  | 
| 458 | /** @} */ | 
| 459 | #endif | 
| 460 |  |