RavEngine
Loading...
Searching...
No Matches
ExtJoint.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef EXT_JOINT_H
30#define EXT_JOINT_H
31
32#include "PxPhysics.h"
33#include "extensions/PxConstraintExt.h"
34#include "PxRigidStatic.h"
35#include "PxRigidDynamic.h"
36#include "PxArticulationLink.h"
37#include "PxArticulationReducedCoordinate.h"
38#include "PxScene.h"
39
40#include "foundation/PxAllocator.h"
41#include "foundation/PxMathUtils.h"
42#include "CmUtils.h"
43#include "ExtJointData.h"
44
45#if PX_SUPPORT_PVD
46 #include "pvd/PxPvdSceneClient.h"
47 #include "ExtPvd.h"
48 #include "PxPvdClient.h"
49#endif
50
51#if PX_SUPPORT_OMNI_PVD
52# include "omnipvd/OmniPvdPxExtensionsSampler.h"
53#endif
54
55namespace physx
56{
57// PX_SERIALIZATION
58 class PxDeserializationContext;
59
60PxConstraint* resolveConstraintPtr(PxDeserializationContext& v, PxConstraint* old, PxConstraintConnector* connector, PxConstraintShaderTable& shaders);
61
62// ~PX_SERIALIZATION
63
64namespace Ext
65{
66 PX_FORCE_INLINE float computeSwingAngle(float swingYZ, float swingW)
67 {
68 return 4.0f * PxAtan2(swingYZ, 1.0f + swingW); // tan (t/2) = sin(t)/(1+cos t), so this is the quarter angle
69 }
70
71 template<class JointType, class DataType>
72 PX_FORCE_INLINE JointType* createJointT(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1, const PxConstraintShaderTable& shaders)
73 {
74 JointType* j;
75 PX_NEW_SERIALIZED(j, JointType)(physics.getTolerancesScale(), actor0, localFrame0, actor1, localFrame1);
76
77 if(!physics.createConstraint(actor0, actor1, *j, shaders, sizeof(DataType)))
78 PX_DELETE(j);
79
80#if PX_SUPPORT_OMNI_PVD
81 if (j)
82 {
83 omniPvdCreateJoint(j);
84 omniPvdInitJoint(j);
85 }
86#endif
87
88 return j;
89 }
90
91// PX_SERIALIZATION
92 template<class JointType>
93 PX_FORCE_INLINE JointType* createJointObject(PxU8*& address, PxDeserializationContext& context)
94 {
95 JointType* obj = PX_PLACEMENT_NEW(address, JointType(PxBaseFlag::eIS_RELEASABLE));
96 address += sizeof(JointType);
97 obj->importExtraData(context);
98 obj->resolveReferences(context);
99 return obj;
100 }
101//~PX_SERIALIZATION
102
103 template <class Base, class DataClass, class ValueStruct>
104 class JointT : public Base, public PxConstraintConnector, public PxUserAllocated
105 {
106 public:
107// PX_SERIALIZATION
108 JointT(PxBaseFlags baseFlags) : Base(baseFlags) {}
109
110 void exportExtraData(PxSerializationContext& stream)
111 {
112 if(mData)
113 {
114 stream.alignData(PX_SERIAL_ALIGN);
115 stream.writeData(mData, sizeof(DataClass));
116 }
117 stream.writeName(mName);
118 }
119
120 void importExtraData(PxDeserializationContext& context)
121 {
122 if(mData)
123 mData = context.readExtraData<DataClass, PX_SERIAL_ALIGN>();
124 context.readName(mName);
125 }
126
127 virtual void preExportDataReset(){}
128 virtual void requiresObjects(PxProcessPxBaseCallback& c)
129 {
130 c.process(*mPxConstraint);
131
132 {
133 PxRigidActor* a0 = NULL;
134 PxRigidActor* a1 = NULL;
135 mPxConstraint->getActors(a0,a1);
136
137 if (a0)
138 {
139 c.process(*a0);
140 }
141 if (a1)
142 {
143 c.process(*a1);
144 }
145 }
146 }
147//~PX_SERIALIZATION
148
149#if PX_SUPPORT_PVD
150 // PxConstraintConnector
151 virtual bool updatePvdProperties(physx::pvdsdk::PvdDataStream& pvdConnection, const PxConstraint* c, PxPvdUpdateType::Enum updateType) const PX_OVERRIDE
152 {
154 {
155 Ext::Pvd::simUpdate<Base>(pvdConnection, *this);
156 return true;
157 }
158 else if(updateType == PxPvdUpdateType::UPDATE_ALL_PROPERTIES)
159 {
160 Ext::Pvd::updatePvdProperties<Base, ValueStruct>(pvdConnection, *this);
161 return true;
162 }
163 else if(updateType == PxPvdUpdateType::CREATE_INSTANCE)
164 {
165 Ext::Pvd::createPvdInstance<Base>(pvdConnection, *c, *this);
166 return true;
167 }
168 else if(updateType == PxPvdUpdateType::RELEASE_INSTANCE)
169 {
170 Ext::Pvd::releasePvdInstance(pvdConnection, *c, *this);
171 return true;
172 }
173 return false;
174 }
175#else
177 {
178 return false;
179 }
180#endif
181
182 // PxConstraintConnector
184 {
185 }
186
187 // PxJoint
188 virtual void setActors(PxRigidActor* actor0, PxRigidActor* actor1) PX_OVERRIDE
189 {
190 //TODO SDK-DEV
191 //You can get the debugger stream from the NpScene
192 //Ext::Pvd::setActors( stream, this, mPxConstraint, actor0, actor1 );
193 PX_CHECK_AND_RETURN(actor0 != actor1, "PxJoint::setActors: actors must be different");
194 PX_CHECK_AND_RETURN((actor0 && !actor0->is<PxRigidStatic>()) || (actor1 && !actor1->is<PxRigidStatic>()), "PxJoint::setActors: at least one actor must be non-static");
195
196#if PX_SUPPORT_PVD
197 PxScene* scene = getScene();
198 if(scene)
199 {
200 //if pvd not connect data stream is NULL
201 physx::pvdsdk::PvdDataStream* conn = scene->getScenePvdClient()->getClientInternal()->getDataStream();
202 if( conn != NULL )
203 Ext::Pvd::setActors(
204 *conn,
205 *this,
206 *mPxConstraint,
207 actor0,
208 actor1
209 );
210 }
211#endif
212 mPxConstraint->setActors(actor0, actor1);
213 mData->c2b[0] = getCom(actor0).transformInv(mLocalPose[0]);
214 mData->c2b[1] = getCom(actor1).transformInv(mLocalPose[1]);
215 mPxConstraint->markDirty();
216
217#if PX_SUPPORT_OMNI_PVD
218 OMNI_PVD_SET(joint, actor0, static_cast<PxJoint&>(*this), actor0)
219 OMNI_PVD_SET(joint, actor1, static_cast<PxJoint&>(*this), actor1)
220#endif
221 }
222
223 // PxJoint
224 virtual void getActors(PxRigidActor*& actor0, PxRigidActor*& actor1) const PX_OVERRIDE
225 {
226 if(mPxConstraint)
227 mPxConstraint->getActors(actor0,actor1);
228 else
229 {
230 actor0 = NULL;
231 actor1 = NULL;
232 }
233 }
234
235 // this is the local pose relative to the actor, and we store internally the local
236 // pose relative to the body
237
238 // PxJoint
239 virtual void setLocalPose(PxJointActorIndex::Enum actor, const PxTransform& pose) PX_OVERRIDE
240 {
241 PX_CHECK_AND_RETURN(pose.isSane(), "PxJoint::setLocalPose: transform is invalid");
242 const PxTransform p = pose.getNormalized();
243 mLocalPose[actor] = p;
244 mData->c2b[actor] = getCom(actor).transformInv(p);
245 mPxConstraint->markDirty();
246
247#if PX_SUPPORT_OMNI_PVD
248 OMNI_PVD_SET(joint, actor0LocalPose, static_cast<PxJoint&>(*this), mLocalPose[0])
249 OMNI_PVD_SET(joint, actor1LocalPose, static_cast<PxJoint&>(*this), mLocalPose[1])
250#endif
251 }
252
253 // PxJoint
254 virtual PxTransform getLocalPose(PxJointActorIndex::Enum actor) const PX_OVERRIDE
255 {
256 return mLocalPose[actor];
257 }
258
259 static PxTransform getGlobalPose(const PxRigidActor* actor)
260 {
261 if(!actor)
262 return PxTransform(PxIdentity);
263 return actor->getGlobalPose();
264 }
265
266 static void getActorVelocity(const PxRigidActor* actor, PxVec3& linear, PxVec3& angular)
267 {
268 if(!actor || actor->is<PxRigidStatic>())
269 {
270 linear = angular = PxVec3(0.0f);
271 return;
272 }
273
274 linear = static_cast<const PxRigidBody*>(actor)->getLinearVelocity();
275 angular = static_cast<const PxRigidBody*>(actor)->getAngularVelocity();
276 }
277
278 // PxJoint
279 virtual PxTransform getRelativeTransform() const PX_OVERRIDE
280 {
281 PxRigidActor* actor0, * actor1;
282 mPxConstraint->getActors(actor0, actor1);
283 const PxTransform t0 = getGlobalPose(actor0) * mLocalPose[0];
284 const PxTransform t1 = getGlobalPose(actor1) * mLocalPose[1];
285 return t0.transformInv(t1);
286 }
287
288 // PxJoint
289 virtual PxVec3 getRelativeLinearVelocity() const PX_OVERRIDE
290 {
291 PxRigidActor* actor0, * actor1;
292 PxVec3 l0, a0, l1, a1;
293 mPxConstraint->getActors(actor0, actor1);
294
295 PxTransform t0 = getCom(actor0), t1 = getCom(actor1);
296 getActorVelocity(actor0, l0, a0);
297 getActorVelocity(actor1, l1, a1);
298
299 PxVec3 p0 = t0.q.rotate(mLocalPose[0].p),
300 p1 = t1.q.rotate(mLocalPose[1].p);
301 return t0.transformInv(l1 - a1.cross(p1) - l0 + a0.cross(p0));
302 }
303
304 // PxJoint
305 virtual PxVec3 getRelativeAngularVelocity() const PX_OVERRIDE
306 {
307 PxRigidActor* actor0, * actor1;
308 PxVec3 l0, a0, l1, a1;
309 mPxConstraint->getActors(actor0, actor1);
310
311 PxTransform t0 = getCom(actor0);
312 getActorVelocity(actor0, l0, a0);
313 getActorVelocity(actor1, l1, a1);
314
315 return t0.transformInv(a1 - a0);
316 }
317
318 // PxJoint
319 virtual void setBreakForce(PxReal force, PxReal torque) PX_OVERRIDE
320 {
321 PX_CHECK_AND_RETURN(PxIsFinite(force) && PxIsFinite(torque), "PxJoint::setBreakForce: invalid float");
322 mPxConstraint->setBreakForce(force,torque);
323#if PX_SUPPORT_OMNI_PVD
324 OMNI_PVD_SET(joint, breakForce, static_cast<PxJoint&>(*this), force)
325 OMNI_PVD_SET(joint, breakTorque, static_cast<PxJoint&>(*this), torque)
326#endif
327 }
328
329 // PxJoint
330 virtual void getBreakForce(PxReal& force, PxReal& torque) const PX_OVERRIDE
331 {
332 mPxConstraint->getBreakForce(force,torque);
333 }
334
335 // PxJoint
336 virtual void setConstraintFlags(PxConstraintFlags flags) PX_OVERRIDE
337 {
338 mPxConstraint->setFlags(flags);
339#if PX_SUPPORT_OMNI_PVD
340 OMNI_PVD_SET(joint, constraintFlags, static_cast<PxJoint&>(*this), flags)
341#endif
342 }
343
344 // PxJoint
345 virtual void setConstraintFlag(PxConstraintFlag::Enum flag, bool value) PX_OVERRIDE
346 {
347 mPxConstraint->setFlag(flag, value);
348#if PX_SUPPORT_OMNI_PVD
349 OMNI_PVD_SET(joint, constraintFlags, static_cast<PxJoint&>(*this), getConstraintFlags())
350#endif
351 }
352
353 // PxJoint
354 virtual PxConstraintFlags getConstraintFlags() const PX_OVERRIDE
355 {
356 return mPxConstraint->getFlags();
357 }
358
359 // PxJoint
360 virtual void setInvMassScale0(PxReal invMassScale) PX_OVERRIDE
361 {
362 PX_CHECK_AND_RETURN(PxIsFinite(invMassScale) && invMassScale>=0, "PxJoint::setInvMassScale0: scale must be non-negative");
363 mData->invMassScale.linear0 = invMassScale;
364 mPxConstraint->markDirty();
365#if PX_SUPPORT_OMNI_PVD
366 OMNI_PVD_SET(joint, invMassScale0, static_cast<PxJoint&>(*this), invMassScale)
367#endif
368 }
369
370 // PxJoint
371 virtual PxReal getInvMassScale0() const PX_OVERRIDE
372 {
373 return mData->invMassScale.linear0;
374 }
375
376 // PxJoint
377 virtual void setInvInertiaScale0(PxReal invInertiaScale) PX_OVERRIDE
378 {
379 PX_CHECK_AND_RETURN(PxIsFinite(invInertiaScale) && invInertiaScale>=0, "PxJoint::setInvInertiaScale0: scale must be non-negative");
380 mData->invMassScale.angular0 = invInertiaScale;
381 mPxConstraint->markDirty();
382#if PX_SUPPORT_OMNI_PVD
383 OMNI_PVD_SET(joint, invInertiaScale0, static_cast<PxJoint&>(*this), invInertiaScale)
384#endif
385 }
386
387 // PxJoint
388 virtual PxReal getInvInertiaScale0() const PX_OVERRIDE
389 {
390 return mData->invMassScale.angular0;
391 }
392
393 // PxJoint
394 virtual void setInvMassScale1(PxReal invMassScale) PX_OVERRIDE
395 {
396 PX_CHECK_AND_RETURN(PxIsFinite(invMassScale) && invMassScale>=0, "PxJoint::setInvMassScale1: scale must be non-negative");
397 mData->invMassScale.linear1 = invMassScale;
398 mPxConstraint->markDirty();
399#if PX_SUPPORT_OMNI_PVD
400 OMNI_PVD_SET(joint, invMassScale1, static_cast<PxJoint&>(*this), invMassScale)
401#endif
402 }
403
404 // PxJoint
405 virtual PxReal getInvMassScale1() const PX_OVERRIDE
406 {
407 return mData->invMassScale.linear1;
408 }
409
410 // PxJoint
411 virtual void setInvInertiaScale1(PxReal invInertiaScale) PX_OVERRIDE
412 {
413 PX_CHECK_AND_RETURN(PxIsFinite(invInertiaScale) && invInertiaScale>=0, "PxJoint::setInvInertiaScale: scale must be non-negative");
414 mData->invMassScale.angular1 = invInertiaScale;
415 mPxConstraint->markDirty();
416#if PX_SUPPORT_OMNI_PVD
417 OMNI_PVD_SET(joint, invInertiaScale1, static_cast<PxJoint&>(*this), invInertiaScale)
418#endif
419 }
420
421 // PxJoint
422 virtual PxReal getInvInertiaScale1() const PX_OVERRIDE
423 {
424 return mData->invMassScale.angular1;
425 }
426
427 // PxJoint
428 virtual PxConstraint* getConstraint() const PX_OVERRIDE
429 {
430 return mPxConstraint;
431 }
432
433 // PxJoint
434 virtual void setName(const char* name) PX_OVERRIDE
435 {
436 mName = name;
437#if PX_SUPPORT_OMNI_PVD
438 const char* n = name ? name : "";
439 PxU32 nLen = PxU32(strlen(n)) + 1;
440 OMNI_PVD_SETB(joint, name, static_cast<PxJoint&>(*this), n, nLen)
441#endif
442 }
443
444 // PxJoint
445 virtual const char* getName() const PX_OVERRIDE
446 {
447 return mName;
448 }
449
450 // PxJoint
451 virtual void release() PX_OVERRIDE
452 {
453 mPxConstraint->release();
454 }
455
456 // PxJoint
457 virtual PxScene* getScene() const PX_OVERRIDE
458 {
459 return mPxConstraint ? mPxConstraint->getScene() : NULL;
460 }
461
462 // PxConstraintConnector
463 virtual void onComShift(PxU32 actor) PX_OVERRIDE
464 {
465 mData->c2b[actor] = getCom(actor).transformInv(mLocalPose[actor]);
466 markDirty();
467 }
468
469 // PxConstraintConnector
470 virtual void onOriginShift(const PxVec3& shift) PX_OVERRIDE
471 {
472 PxRigidActor* a[2];
473 mPxConstraint->getActors(a[0], a[1]);
474
475 if (!a[0])
476 {
477 mLocalPose[0].p -= shift;
478 mData->c2b[0].p -= shift;
479 markDirty();
480 }
481 else if (!a[1])
482 {
483 mLocalPose[1].p -= shift;
484 mData->c2b[1].p -= shift;
485 markDirty();
486 }
487 }
488
489 // PxConstraintConnector
490 virtual void* prepareData() PX_OVERRIDE
491 {
492 return mData;
493 }
494
495 // PxConstraintConnector
496 virtual void* getExternalReference(PxU32& typeID) PX_OVERRIDE
497 {
498 typeID = PxConstraintExtIDs::eJOINT;
499 return static_cast<PxJoint*>( this );
500 }
501
502 // PxConstraintConnector
504 {
505 return this;
506 }
507
508 // PxConstraintConnector
510 {
511 PX_FREE(mData);
512 PX_DELETE_THIS;
513 }
514
515 // PxConstraintConnector
516 virtual const void* getConstantBlock() const PX_OVERRIDE
517 {
518 return mData;
519 }
520
522 {
523 mPxConstraint = c;
524 }
525
526 private:
527 PxTransform getCom(PxU32 index) const
528 {
529 PxRigidActor* a[2];
530 mPxConstraint->getActors(a[0],a[1]);
531 return getCom(a[index]);
532 }
533
534 PxTransform getCom(PxRigidActor* actor) const
535 {
536 if (!actor)
537 return PxTransform(PxIdentity);
538 else if (actor->getType() == PxActorType::eRIGID_DYNAMIC || actor->getType() == PxActorType::eARTICULATION_LINK)
539 return static_cast<PxRigidBody*>(actor)->getCMassLocalPose();
540 else
541 {
542 PX_ASSERT(actor->getType() == PxActorType::eRIGID_STATIC);
543 return static_cast<PxRigidStatic*>(actor)->getGlobalPose().getInverse();
544 }
545 }
546
547 protected:
548
549 JointT(PxType concreteType, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1, const char* name) :
550 Base (concreteType, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE),
551 mName (NULL),
552 mPxConstraint (NULL)
553 {
554 PX_UNUSED(name);
555 Base::userData = NULL;
556
557 const PxU32 size = sizeof(DataClass);
558 JointData* data = reinterpret_cast<JointData*>(PX_ALLOC(size, name));
559 PxMarkSerializedMemory(data, size);
560
561 mLocalPose[0] = localFrame0.getNormalized();
562 mLocalPose[1] = localFrame1.getNormalized();
563 data->c2b[0] = getCom(actor0).transformInv(mLocalPose[0]);
564 data->c2b[1] = getCom(actor1).transformInv(mLocalPose[1]);
565 data->invMassScale.linear0 = 1.0f;
566 data->invMassScale.angular0 = 1.0f;
567 data->invMassScale.linear1 = 1.0f;
568 data->invMassScale.angular1 = 1.0f;
569
570 mData = data;
571 }
572
573 virtual ~JointT()
574 {
575 if(Base::getBaseFlags() & PxBaseFlag::eOWNS_MEMORY)
576 PX_FREE(mData);
577
578#if PX_SUPPORT_OMNI_PVD
579 OMNI_PVD_DESTROY(joint, static_cast<PxJoint&>(*this))
580#endif
581 }
582
583 PX_FORCE_INLINE DataClass& data() const
584 {
585 return *static_cast<DataClass*>(mData);
586 }
587
588 PX_FORCE_INLINE void markDirty()
589 {
590 mPxConstraint->markDirty();
591 }
592
593 void wakeUpActors()
594 {
595 PxRigidActor* a[2];
596 mPxConstraint->getActors(a[0], a[1]);
597 for(PxU32 i = 0; i < 2; i++)
598 {
599 if(a[i] && a[i]->getScene())
600 {
601 if(a[i]->getType() == PxActorType::eRIGID_DYNAMIC)
602 {
603 PxRigidDynamic* rd = static_cast<PxRigidDynamic*>(a[i]);
604 if(!(rd->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC))
605 {
606 const PxScene* scene = rd->getScene();
607 const PxReal wakeCounterResetValue = scene->getWakeCounterResetValue();
608 const PxReal wakeCounter = rd->getWakeCounter();
609 if(wakeCounter < wakeCounterResetValue)
610 {
611 rd->wakeUp();
612 }
613 }
614 }
615 else if(a[i]->getType() == PxActorType::eARTICULATION_LINK)
616 {
617 PxArticulationLink* link = reinterpret_cast<PxArticulationLink*>(a[i]);
618 PxArticulationReducedCoordinate& articulation = link->getArticulation();
619 const PxReal wakeCounter = articulation.getWakeCounter();
620 const PxScene* scene = link->getScene();
621 const PxReal wakeCounterResetValue = scene->getWakeCounterResetValue();
622 if(wakeCounter < wakeCounterResetValue)
623 {
624 articulation.wakeUp();
625 }
626 }
627 }
628 }
629 }
630
631 PX_FORCE_INLINE PxQuat getTwistOrSwing(bool needTwist) const
632 {
633 const PxQuat q = getRelativeTransform().q;
634 // PT: TODO: we don't need to compute both quats here
635 PxQuat swing, twist;
636 PxSeparateSwingTwist(q, swing, twist);
637 return needTwist ? twist : swing;
638 }
639
640 PxReal getTwistAngle_Internal() const
641 {
642 const PxQuat twist = getTwistOrSwing(true);
643
644 // PT: the angle-axis formulation creates the quat like this:
645 //
646 // const float a = angleRadians * 0.5f;
647 // const float s = PxSin(a);
648 // w = PxCos(a);
649 // x = unitAxis.x * s;
650 // y = unitAxis.y * s;
651 // z = unitAxis.z * s;
652 //
653 // With the twist axis = (1;0;0) this gives:
654 //
655 // w = PxCos(angleRadians * 0.5f);
656 // x = PxSin(angleRadians * 0.5f);
657 // y = 0.0f;
658 // z = 0.0f;
659 //
660 // Thus the quat's "getAngle" function returns:
661 //
662 // angle = PxAcos(w) * 2.0f;
663 //
664 // PxAcos will return an angle between 0 and PI in radians, so "getAngle" will return an angle between 0 and PI*2.
665
666 PxReal angle = twist.getAngle();
667
668 if(twist.x<0.0f)
669 angle = -angle;
670
671 return angle;
672 }
673
674 PxReal getSwingYAngle_Internal() const
675 {
676 PxQuat swing = getTwistOrSwing(false);
677
678 if(swing.w < 0.0f) // choose the shortest rotation
679 swing = -swing;
680
681 const PxReal angle = computeSwingAngle(swing.y, swing.w);
682 PX_ASSERT(angle>-PxPi && angle<=PxPi); // since |y| < w+1, the atan magnitude is < PI/4
683 return angle;
684 }
685
686 PxReal getSwingZAngle_Internal() const
687 {
688 PxQuat swing = getTwistOrSwing(false);
689
690 if(swing.w < 0.0f) // choose the shortest rotation
691 swing = -swing;
692
693 const PxReal angle = computeSwingAngle(swing.z, swing.w);
694 PX_ASSERT(angle>-PxPi && angle <= PxPi); // since |y| < w+1, the atan magnitude is < PI/4
695 return angle;
696 }
697
698 const char* mName;
699 PxTransform mLocalPose[2];
700 PxConstraint* mPxConstraint;
701 JointData* mData;
702 };
703
704 PX_FORCE_INLINE bool isLimitActive(const PxJointLimitParameters& limit, PxReal pad, PxReal angle, PxReal low, PxReal high)
705 {
706 PX_ASSERT(low<high);
707 if(limit.isSoft())
708 pad = 0.0f;
709 bool active = false;
710 if(angle < low + pad)
711 active = true;
712 if(angle > high - pad)
713 active = true;
714 return active;
715 }
716
717#if PX_SUPPORT_OMNI_PVD
718 void omniPvdCreateJoint(PxJoint* joint);
719 template<typename JointType> void omniPvdInitJoint(JointType* joint);
720#endif
721
722} // namespace Ext
723
724}
725
726#endif
Definition base.h:1940
Definition ExtJoint.h:105
virtual void updateOmniPvdProperties() const PX_OVERRIDE
this function is called by the SDK to update OmniPVD's view of it
Definition ExtJoint.h:183
virtual bool updatePvdProperties(physx::pvdsdk::PvdDataStream &, const PxConstraint *, PxPvdUpdateType::Enum) const PX_OVERRIDE
this function is called by the SDK to update PVD's view of it
Definition ExtJoint.h:176
virtual PxBase * getSerializable() PX_OVERRIDE
Obtain a reference to a PxBase interface if the constraint has one.
Definition ExtJoint.h:503
virtual void connectToConstraint(PxConstraint *c) PX_OVERRIDE
Let the connector know it has been connected to a constraint.
Definition ExtJoint.h:521
virtual const void * getConstantBlock() const PX_OVERRIDE
Obtain the pointer to the constraint's constant data.
Definition ExtJoint.h:516
virtual void * prepareData() PX_OVERRIDE
Pre-simulation data preparation when the constraint is marked dirty, this function is called at the s...
Definition ExtJoint.h:490
virtual void onOriginShift(const PxVec3 &shift) PX_OVERRIDE
Origin shift callback.
Definition ExtJoint.h:470
virtual void onConstraintRelease() PX_OVERRIDE
Constraint release callback.
Definition ExtJoint.h:509
virtual void onComShift(PxU32 actor) PX_OVERRIDE
Center-of-mass shift callback.
Definition ExtJoint.h:463
virtual void * getExternalReference(PxU32 &typeID) PX_OVERRIDE
Fetches external data for a constraint.
Definition ExtJoint.h:496
Base class for objects that can be members of a PxCollection.
Definition PxBase.h:73
This class connects a custom constraint to the SDK.
Definition PxConstraintDesc.h:354
A plugin class for implementing constraints.
Definition PxConstraint.h:100
virtual void getBreakForce(PxReal &linear, PxReal &angular) const =0
Retrieve the constraint break force and torque thresholds.
virtual void setFlag(PxConstraintFlag::Enum flag, bool value)=0
Set a flag for this constraint.
virtual void setFlags(PxConstraintFlags flags)=0
Set the flags for this constraint.
virtual PxConstraintFlags getFlags() const =0
Retrieve the flags for this constraint.
virtual void setActors(PxRigidActor *actor0, PxRigidActor *actor1)=0
Sets the actors for this constraint.
virtual PxScene * getScene() const =0
Retrieves the scene which this constraint belongs to.
virtual void release()=0
Releases a PxConstraint instance.
virtual void setBreakForce(PxReal linear, PxReal angular)=0
Set the break force and torque thresholds for this constraint.
virtual void markDirty()=0
Notify the scene that the constraint shader data has been updated by the application.
virtual void getActors(PxRigidActor *&actor0, PxRigidActor *&actor1) const =0
Retrieves the actors for this constraint.
Binary deserialization context class.
Definition PxSerialFramework.h:174
a base interface providing common functionality for PhysX joints
Definition PxJoint.h:105
Callback class used to process PxBase objects.
Definition PxSerialFramework.h:81
virtual physx::pvdsdk::PvdClient * getClientInternal()=0
PxRigidActor represents a base class shared between dynamic and static rigid bodies in the physics SD...
Definition PxRigidActor.h:53
PxRigidBody is a base class shared between dynamic rigid body objects.
Definition PxRigidBody.h:199
PxRigidStatic represents a static rigid body simulation object in the physics SDK.
Definition PxRigidStatic.h:58
A scene is a collection of bodies and constraints which can interact.
Definition PxScene.h:178
virtual PxPvdSceneClient * getScenePvdClient()=0
Returns the Pvd client associated with the scene.
Binary serialization context class.
Definition PxSerialFramework.h:99
virtual void alignData(PxU32 alignment=PX_SERIAL_ALIGN)=0
Aligns the serialized data.
virtual void writeData(const void *data, PxU32 size)=0
Serializes object data and object extra data.
virtual void writeName(const char *name)=0
Helper function to write a name to the extraData if serialization is configured to save names.
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform getNormalized() const
return a normalized transform (i.e. one in which the quaternion has unit magnitude)
Definition PxTransform.h:204
Definition PxUserAllocated.h:43
3 Element vector class.
Definition PxVec3.h:50
Definition PxPvdDataStream.h:241
GLM_FUNC_DECL T angle(qua< T, Q > const &x)
Definition quaternion_trigonometric.inl:6
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#define PX_OVERRIDE
Definition PxPreprocessor.h:375
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 void PxSeparateSwingTwist(const PxQuat &q, PxQuat &swing, PxQuat &twist)
Compute from an input quaternion q a pair of quaternions (swing, twist) such that q = swing * twist w...
Definition PxMathUtils.h:246
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 bool PxIsFinite(float f)
returns true if the passed number is a finite floating point number as opposed to INF,...
Definition PxMath.h:326
PX_INLINE void PxMarkSerializedMemory(void *ptr, PxU32 byteSize)
Definition PxMemory.h:111
PxFlags< PxConstraintFlag::Enum, PxU16 > PxConstraintFlags
constraint flags
Definition PxConstraint.h:78
@ eARTICULATION_LINK
An articulation link.
Definition PxActor.h:138
@ eRIGID_STATIC
A static rigid body.
Definition PxActor.h:126
@ eRIGID_DYNAMIC
A dynamic rigid body.
Definition PxActor.h:132
Enum
Definition PxConstraint.h:57
PxReal angular1
multiplier for inverse MoI of body1
Definition PxConstraintDesc.h:195
PxReal linear0
multiplier for inverse mass of body0
Definition PxConstraintDesc.h:192
PxReal angular0
multiplier for inverse MoI of body0
Definition PxConstraintDesc.h:193
PxReal linear1
multiplier for inverse mass of body1
Definition PxConstraintDesc.h:194
Enum
Definition PxConstraintDesc.h:337
@ RELEASE_INSTANCE
triggers releasePvdInstance call, releases an instance of a constraint
Definition PxConstraintDesc.h:339
@ UPDATE_ALL_PROPERTIES
triggers updatePvdProperties call, updates all properties of a constraint
Definition PxConstraintDesc.h:340
@ CREATE_INSTANCE
triggers createPvdInstance call, creates an instance of a constraint
Definition PxConstraintDesc.h:338
@ UPDATE_SIM_PROPERTIES
triggers simUpdate call, updates all simulation properties of a constraint
Definition PxConstraintDesc.h:341
@ eKINEMATIC
Enables kinematic mode for the actor.
Definition PxRigidBody.h:74