1 | // |
2 | // Redistribution and use in source and binary forms, with or without |
3 | // modification, are permitted provided that the following conditions |
4 | // are met: |
5 | // * Redistributions of source code must retain the above copyright |
6 | // notice, this list of conditions and the following disclaimer. |
7 | // * Redistributions in binary form must reproduce the above copyright |
8 | // notice, this list of conditions and the following disclaimer in the |
9 | // documentation and/or other materials provided with the distribution. |
10 | // * Neither the name of NVIDIA CORPORATION nor the names of its |
11 | // contributors may be used to endorse or promote products derived |
12 | // from this software without specific prior written permission. |
13 | // |
14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY |
15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | // |
26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. |
27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
29 | |
30 | #ifndef PX_REVOLUTEJOINT_H |
31 | #define PX_REVOLUTEJOINT_H |
32 | /** \addtogroup extensions |
33 | @{ |
34 | */ |
35 | |
36 | #include "extensions/PxJoint.h" |
37 | #include "extensions/PxJointLimit.h" |
38 | |
39 | #if !PX_DOXYGEN |
40 | namespace physx |
41 | { |
42 | #endif |
43 | |
44 | class PxRevoluteJoint; |
45 | |
46 | /** |
47 | \brief Create a revolute joint. |
48 | |
49 | \param[in] physics The physics SDK |
50 | \param[in] actor0 An actor to which the joint is attached. NULL may be used to attach the joint to a specific point in the world frame |
51 | \param[in] localFrame0 The position and orientation of the joint relative to actor0 |
52 | \param[in] actor1 An actor to which the joint is attached. NULL may be used to attach the joint to a specific point in the world frame |
53 | \param[in] localFrame1 The position and orientation of the joint relative to actor1 |
54 | |
55 | @see PxRevoluteJoint |
56 | */ |
57 | PxRevoluteJoint* PxRevoluteJointCreate(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1); |
58 | |
59 | /** |
60 | \brief Flags specific to the Revolute Joint. |
61 | |
62 | @see PxRevoluteJoint |
63 | */ |
64 | struct PxRevoluteJointFlag |
65 | { |
66 | enum Enum |
67 | { |
68 | eLIMIT_ENABLED = 1<<0, //!< enable the limit |
69 | eDRIVE_ENABLED = 1<<1, //!< enable the drive |
70 | eDRIVE_FREESPIN = 1<<2 //!< if the existing velocity is beyond the drive velocity, do not add force |
71 | }; |
72 | }; |
73 | |
74 | typedef PxFlags<PxRevoluteJointFlag::Enum, PxU16> PxRevoluteJointFlags; |
75 | PX_FLAGS_OPERATORS(PxRevoluteJointFlag::Enum, PxU16) |
76 | |
77 | /** |
78 | |
79 | \brief A joint which behaves in a similar way to a hinge or axle. |
80 | |
81 | A hinge joint removes all but a single rotational degree of freedom from two objects. |
82 | The axis along which the two bodies may rotate is specified with a point and a direction |
83 | vector. |
84 | |
85 | The position of the hinge on each body is specified by the origin of the body's joint frame. |
86 | The axis of the hinge is specified as the direction of the x-axis in the body's joint frame. |
87 | |
88 | \image html revoluteJoint.png |
89 | |
90 | A revolute joint can be given a motor, so that it can apply a force to rotate the attached actors. |
91 | It may also be given a limit, to restrict the revolute motion to within a certain range. In |
92 | addition, the bodies may be projected together if the distance or angle between them exceeds |
93 | a given threshold. |
94 | |
95 | Projection, drive and limits are activated by setting the appropriate flags on the joint. |
96 | |
97 | @see PxRevoluteJointCreate() PxJoint |
98 | */ |
99 | class PxRevoluteJoint : public PxJoint |
100 | { |
101 | public: |
102 | |
103 | /** |
104 | \brief return the angle of the joint, in the range (-2*Pi, 2*Pi] |
105 | */ |
106 | virtual PxReal getAngle() const = 0; |
107 | |
108 | /** |
109 | \brief return the velocity of the joint |
110 | */ |
111 | virtual PxReal getVelocity() const = 0; |
112 | |
113 | /** |
114 | \brief set the joint limit parameters. |
115 | |
116 | The limit is activated using the flag PxRevoluteJointFlag::eLIMIT_ENABLED |
117 | |
118 | The limit angle range is (-2*Pi, 2*Pi). |
119 | |
120 | \param[in] limits The joint limit parameters. |
121 | |
122 | @see PxJointAngularLimitPair getLimit() |
123 | */ |
124 | virtual void setLimit(const PxJointAngularLimitPair& limits) = 0; |
125 | |
126 | /** |
127 | \brief get the joint limit parameters. |
128 | |
129 | \return the joint limit parameters |
130 | |
131 | @see PxJointAngularLimitPair setLimit() |
132 | */ |
133 | virtual PxJointAngularLimitPair getLimit() const = 0; |
134 | |
135 | /** |
136 | \brief set the target velocity for the drive model. |
137 | |
138 | The motor will only be able to reach this velocity if the maxForce is sufficiently large. |
139 | If the joint is spinning faster than this velocity, the motor will actually try to brake |
140 | (see PxRevoluteJointFlag::eDRIVE_FREESPIN.) |
141 | |
142 | If you set this to infinity then the motor will keep speeding up, unless there is some sort |
143 | of resistance on the attached bodies. The sign of this variable determines the rotation direction, |
144 | with positive values going the same way as positive joint angles. |
145 | |
146 | \param[in] velocity the drive target velocity |
147 | \param[in] autowake Whether to wake the joint rigids up if it is asleep. |
148 | |
149 | <b>Range:</b> [0, PX_MAX_F32)<br> |
150 | <b>Default:</b> 0.0 |
151 | |
152 | @see PxRevoluteFlags::eDRIVE_FREESPIN |
153 | */ |
154 | virtual void setDriveVelocity(PxReal velocity, bool autowake = true) = 0; |
155 | |
156 | /** |
157 | \brief gets the target velocity for the drive model. |
158 | |
159 | \return the drive target velocity |
160 | |
161 | @see setDriveVelocity() |
162 | */ |
163 | virtual PxReal getDriveVelocity() const = 0; |
164 | |
165 | /** |
166 | \brief sets the maximum torque the drive can exert. |
167 | |
168 | Setting this to a very large value if velTarget is also very large may cause unexpected results. |
169 | |
170 | The value set here may be used either as an impulse limit or a force limit, depending on the flag PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES |
171 | |
172 | <b>Range:</b> [0, PX_MAX_F32)<br> |
173 | <b>Default:</b> PX_MAX_F32 |
174 | |
175 | @see setDriveVelocity() |
176 | */ |
177 | virtual void setDriveForceLimit(PxReal limit) = 0; |
178 | |
179 | /** |
180 | \brief gets the maximum torque the drive can exert. |
181 | |
182 | \return the torque limit |
183 | |
184 | @see setDriveVelocity() |
185 | */ |
186 | virtual PxReal getDriveForceLimit() const = 0; |
187 | |
188 | /** |
189 | \brief sets the gear ratio for the drive. |
190 | |
191 | When setting up the drive constraint, the velocity of the first actor is scaled by this value, and its response to drive torque is scaled down. |
192 | So if the drive target velocity is zero, the second actor will be driven to the velocity of the first scaled by the gear ratio |
193 | |
194 | <b>Range:</b> [0, PX_MAX_F32)<br> |
195 | <b>Default:</b> 1.0 |
196 | |
197 | \param[in] ratio the drive gear ratio |
198 | |
199 | @see getDriveGearRatio() |
200 | */ |
201 | virtual void setDriveGearRatio(PxReal ratio) = 0; |
202 | |
203 | /** |
204 | \brief gets the gear ratio. |
205 | |
206 | \return the drive gear ratio |
207 | |
208 | @see setDriveGearRatio() |
209 | */ |
210 | virtual PxReal getDriveGearRatio() const = 0; |
211 | |
212 | /** |
213 | \brief sets the flags specific to the Revolute Joint. |
214 | |
215 | <b>Default</b> PxRevoluteJointFlags(0) |
216 | |
217 | \param[in] flags The joint flags. |
218 | |
219 | @see PxRevoluteJointFlag setFlag() getFlags() |
220 | */ |
221 | virtual void setRevoluteJointFlags(PxRevoluteJointFlags flags) = 0; |
222 | |
223 | /** |
224 | \brief sets a single flag specific to a Revolute Joint. |
225 | |
226 | \param[in] flag The flag to set or clear. |
227 | \param[in] value the value to which to set the flag |
228 | |
229 | @see PxRevoluteJointFlag, getFlags() setFlags() |
230 | */ |
231 | virtual void setRevoluteJointFlag(PxRevoluteJointFlag::Enum flag, bool value) = 0; |
232 | |
233 | /** |
234 | \brief gets the flags specific to the Revolute Joint. |
235 | |
236 | \return the joint flags |
237 | |
238 | @see PxRevoluteJoint::flags, PxRevoluteJointFlag setFlag() setFlags() |
239 | */ |
240 | virtual PxRevoluteJointFlags getRevoluteJointFlags() const = 0; |
241 | |
242 | /** |
243 | \brief Set the linear tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION |
244 | is set for the joint. |
245 | |
246 | If the joint separates by more than this distance along its locked degrees of freedom, the solver |
247 | will move the bodies to close the distance. |
248 | |
249 | Setting a very small tolerance may result in simulation jitter or other artifacts. |
250 | |
251 | Sometimes it is not possible to project (for example when the joints form a cycle). |
252 | |
253 | <b>Range:</b> [0, PX_MAX_F32)<br> |
254 | <b>Default:</b> 1e10f |
255 | |
256 | \param[in] tolerance the linear tolerance threshold |
257 | |
258 | @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION |
259 | */ |
260 | virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; |
261 | |
262 | /** |
263 | \brief Get the linear tolerance threshold for projection. |
264 | |
265 | \return the linear tolerance threshold |
266 | |
267 | @see setProjectionLinearTolerance() |
268 | */ |
269 | virtual PxReal getProjectionLinearTolerance() const = 0; |
270 | |
271 | /** |
272 | \brief Set the angular tolerance threshold for projection. Projection is enabled if |
273 | PxConstraintFlag::ePROJECTION is set for the joint. |
274 | |
275 | If the joint deviates by more than this angle around its locked angular degrees of freedom, |
276 | the solver will move the bodies to close the angle. |
277 | |
278 | Setting a very small tolerance may result in simulation jitter or other artifacts. |
279 | |
280 | Sometimes it is not possible to project (for example when the joints form a cycle). |
281 | |
282 | <b>Range:</b> [0,Pi] <br> |
283 | <b>Default:</b> Pi |
284 | |
285 | \param[in] tolerance the angular tolerance threshold in radians |
286 | |
287 | @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION |
288 | */ |
289 | virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; |
290 | |
291 | /** |
292 | \brief gets the angular tolerance threshold for projection. |
293 | |
294 | \return the angular tolerance threshold in radians |
295 | |
296 | @see setProjectionAngularTolerance() |
297 | */ |
298 | virtual PxReal getProjectionAngularTolerance() const = 0; |
299 | |
300 | /** |
301 | \brief Returns string name of PxRevoluteJoint, used for serialization |
302 | */ |
303 | virtual const char* getConcreteTypeName() const { return "PxRevoluteJoint" ; } |
304 | |
305 | protected: |
306 | |
307 | //serialization |
308 | |
309 | /** |
310 | \brief Constructor |
311 | */ |
312 | PX_INLINE PxRevoluteJoint(PxType concreteType, PxBaseFlags baseFlags) : PxJoint(concreteType, baseFlags) {} |
313 | |
314 | /** |
315 | \brief Deserialization constructor |
316 | */ |
317 | PX_INLINE PxRevoluteJoint(PxBaseFlags baseFlags) : PxJoint(baseFlags) {} |
318 | |
319 | /** |
320 | \brief Returns whether a given type name matches with the type of this instance |
321 | */ |
322 | virtual bool isKindOf(const char* name) const { return !::strcmp(s1: "PxRevoluteJoint" , s2: name) || PxJoint::isKindOf(name); } |
323 | |
324 | //~serialization |
325 | }; |
326 | |
327 | #if !PX_DOXYGEN |
328 | } // namespace physx |
329 | #endif |
330 | |
331 | /** @} */ |
332 | #endif |
333 | |