diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysX/src/buffering/ScbArticulation.h | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/PhysX/src/buffering/ScbArticulation.h')
| -rw-r--r-- | PhysX_3.4/Source/PhysX/src/buffering/ScbArticulation.h | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysX/src/buffering/ScbArticulation.h b/PhysX_3.4/Source/PhysX/src/buffering/ScbArticulation.h new file mode 100644 index 00000000..424cf34b --- /dev/null +++ b/PhysX_3.4/Source/PhysX/src/buffering/ScbArticulation.h @@ -0,0 +1,353 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 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 PX_PHYSICS_SCB_ARTICULATION +#define PX_PHYSICS_SCB_ARTICULATION + +#include "ScArticulationCore.h" +#include "ScbBase.h" +#include "ScbDefs.h" + +namespace physx +{ + +namespace Scb +{ + +struct ArticulationBuffer +{ + template <PxU32 I, PxU32 Dummy> struct Fns {}; + typedef Sc::ArticulationCore Core; + typedef ArticulationBuffer Buf; + + SCB_REGULAR_ATTRIBUTE(0, PxU32, InternalDriveIterations) + SCB_REGULAR_ATTRIBUTE(1, PxU32, ExternalDriveIterations) + SCB_REGULAR_ATTRIBUTE(2, PxU32, MaxProjectionIterations) + SCB_REGULAR_ATTRIBUTE(3, PxReal, SeparationTolerance) + SCB_REGULAR_ATTRIBUTE(4, PxReal, SleepThreshold) + SCB_REGULAR_ATTRIBUTE(5, PxU16, SolverIterationCounts) + SCB_REGULAR_ATTRIBUTE(6, PxReal, FreezeThreshold) + + enum { BF_WakeCounter = 1<<7 }; + enum { BF_PutToSleep = 1<<8 }; + enum { BF_WakeUp = 1<<9 }; + +}; + +class Articulation : public Base +{ +//= ATTENTION! ===================================================================================== +// Changing the data layout of this class breaks the binary serialization format. See comments for +// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData +// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION +// accordingly. +//================================================================================================== + + typedef ArticulationBuffer Buf; + typedef Sc::ArticulationCore Core; + +// PX_SERIALIZATION +public: + Articulation(const PxEMPTY) : Base(PxEmpty), mArticulation(PxEmpty), mBufferedIsSleeping(1) {} + static void getBinaryMetaData(PxOutputStream& stream); +//~PX_SERIALIZATION + +private: + +public: + PX_INLINE Articulation(); + PX_INLINE ~Articulation() {} + + //--------------------------------------------------------------------------------- + // Wrapper for Sc::Articulation interface + //--------------------------------------------------------------------------------- + + PX_INLINE PxU32 getInternalDriveIterations() const { return read<Buf::BF_InternalDriveIterations>(); } + PX_INLINE void setInternalDriveIterations(const PxU32 v) { write<Buf::BF_InternalDriveIterations>(v); } + + PX_INLINE PxU32 getExternalDriveIterations() const { return read<Buf::BF_ExternalDriveIterations>(); } + PX_INLINE void setExternalDriveIterations(const PxU32 v) { write<Buf::BF_ExternalDriveIterations>(v); } + + PX_INLINE PxU32 getMaxProjectionIterations() const { return read<Buf::BF_MaxProjectionIterations>(); } + PX_INLINE void setMaxProjectionIterations(const PxU32 v) { write<Buf::BF_MaxProjectionIterations>(v); } + + PX_INLINE PxU16 getSolverIterationCounts() const { return read<Buf::BF_SolverIterationCounts>(); } + PX_INLINE void setSolverIterationCounts(PxU16 v) { write<Buf::BF_SolverIterationCounts>(v); } + + PX_INLINE PxReal getSeparationTolerance() const { return read<Buf::BF_SeparationTolerance>(); } + PX_INLINE void setSeparationTolerance(const PxReal v) { write<Buf::BF_SeparationTolerance>(v); } + + PX_INLINE PxReal getSleepThreshold() const { return read<Buf::BF_SleepThreshold>(); } + PX_INLINE void setSleepThreshold(const PxReal v) { write<Buf::BF_SleepThreshold>(v); } + + PX_INLINE PxReal getFreezeThreshold() const { return read<Buf::BF_SleepThreshold>(); } + PX_INLINE void setFreezeThreshold(const PxReal v) { write<Buf::BF_SleepThreshold>(v); } + + PX_INLINE PxReal getWakeCounter() const { return mBufferedWakeCounter; } + PX_INLINE void setWakeCounter(const PxReal v); + + PX_FORCE_INLINE void wakeUp(); + PX_FORCE_INLINE void putToSleep(); + PX_FORCE_INLINE bool isSleeping() const { return (mBufferedIsSleeping != 0); } + + //--------------------------------------------------------------------------------- + // Data synchronization + //--------------------------------------------------------------------------------- + PX_INLINE void syncState(); + + PX_FORCE_INLINE const Sc::ArticulationCore& getScArticulation() const { return mArticulation; } // Only use if you know what you're doing! + PX_FORCE_INLINE Sc::ArticulationCore& getScArticulation() { return mArticulation; } // Only use if you know what you're doing! + + PX_FORCE_INLINE static Articulation& fromSc(Core &a) { return *reinterpret_cast<Articulation*>(reinterpret_cast<PxU8*>(&a)-getScOffset()); } + PX_FORCE_INLINE static const Articulation& fromSc(const Core &a) { return *reinterpret_cast<const Articulation*>(reinterpret_cast<const PxU8*>(&a)-getScOffset()); } + static size_t getScOffset() + { + return reinterpret_cast<size_t>(&reinterpret_cast<Articulation*>(0)->mArticulation); + } + + PX_FORCE_INLINE void wakeUpInternal(PxReal wakeCounter); + + PX_FORCE_INLINE void initBufferedState(); + PX_FORCE_INLINE void clearBufferedState(); + PX_FORCE_INLINE void clearBufferedSleepStateChange(); + +private: + Sc::ArticulationCore mArticulation; + PxReal mBufferedWakeCounter; + PxU8 mBufferedIsSleeping; + + PX_FORCE_INLINE const Buf* getArticulationBuffer() const { return reinterpret_cast<const Buf*>(getStream()); } + PX_FORCE_INLINE Buf* getArticulationBuffer() { return reinterpret_cast<Buf*>(getStream()); } + + + //--------------------------------------------------------------------------------- + // Infrastructure for regular attributes + //--------------------------------------------------------------------------------- + + struct Access: public BufferedAccess<Buf, Core, Articulation> {}; + template<PxU32 f> PX_FORCE_INLINE typename Buf::Fns<f,0>::Arg read() const { return Access::read<Buf::Fns<f,0> >(*this, mArticulation); } + template<PxU32 f> PX_FORCE_INLINE void write(typename Buf::Fns<f,0>::Arg v) { Access::write<Buf::Fns<f,0> >(*this, mArticulation, v); } + template<PxU32 f> PX_FORCE_INLINE void flush(const Buf& buf) { Access::flush<Buf::Fns<f,0> >(*this, mArticulation, buf); } + +}; + + +Articulation::Articulation() +{ + setScbType(ScbType::ARTICULATION); + mBufferedWakeCounter = getScArticulation().getWakeCounter(); + mBufferedIsSleeping = 1; // this is the specified value for free standing objects +} + + +PX_INLINE void Articulation::setWakeCounter(PxReal counter) +{ + mBufferedWakeCounter = counter; + + if (!isBuffering()) + { + if (getScbScene() && (counter > 0.0f)) + mBufferedIsSleeping = 0; + + getScArticulation().setWakeCounter(counter); + UPDATE_PVD_PROPERTIES_OBJECT() + } + else + { + if (counter > 0.0f) + { + mBufferedIsSleeping = 0; + markUpdated(Buf::BF_WakeUp | Buf::BF_WakeCounter); + resetBufferFlag(Buf::BF_PutToSleep); + } + else + markUpdated(Buf::BF_WakeCounter); + } +} + + +PX_FORCE_INLINE void Articulation::wakeUp() +{ + Scene* scene = getScbScene(); + PX_ASSERT(scene); // only allowed for an object in a scene + + wakeUpInternal(scene->getWakeCounterResetValue()); +} + + +PX_FORCE_INLINE void Articulation::wakeUpInternal(PxReal wakeCounter) +{ + PX_ASSERT(getScbScene()); + + mBufferedWakeCounter = wakeCounter; + + mBufferedIsSleeping = 0; + if (!isBuffering()) + { + getScArticulation().wakeUp(wakeCounter); + } + else + { + markUpdated(Buf::BF_WakeUp | Buf::BF_WakeCounter); + resetBufferFlag(Buf::BF_PutToSleep); + } +} + + +PX_FORCE_INLINE void Articulation::putToSleep() +{ + mBufferedWakeCounter = 0.0f; + + mBufferedIsSleeping = 1; + if (!isBuffering()) + { + getScArticulation().putToSleep(); + } + else + { + markUpdated(Buf::BF_PutToSleep | Buf::BF_WakeCounter); + resetBufferFlag(Buf::BF_WakeUp); + } +} + + +PX_FORCE_INLINE void Articulation::initBufferedState() +{ + PX_ASSERT(mBufferedIsSleeping); // this method is only meant to get called when an object is added to the scene + + if (getWakeCounter() == 0.0f) + mBufferedIsSleeping = 1; + else + mBufferedIsSleeping = 0; + // note: to really know whether the articulation is awake/asleep on insertion, we need to go through every link and check whether any of them has + // a parameter setup that keeps it alive. However, the links get added after the articulation, so we do not test those here. After the links + // are added, an additional check will wake the articulation up if necessary. +} + + +PX_FORCE_INLINE void Articulation::clearBufferedState() +{ + mBufferedIsSleeping = 1; // the expected state when an object gets removed from the scene +} + + +PX_FORCE_INLINE void Articulation::clearBufferedSleepStateChange() +{ + resetBufferFlag(Buf::BF_WakeUp | Buf::BF_PutToSleep); +} + +//-------------------------------------------------------------- +// +// Data synchronization +// +//-------------------------------------------------------------- + +PX_INLINE void Articulation::syncState() +{ + // see comments in Body::syncState + PX_ASSERT( (getControlState() != ControlState::eREMOVE_PENDING) || + (mBufferedIsSleeping && (!isBuffered(Buf::BF_WakeUp | Buf::BF_PutToSleep))) ); + + PxU32 flags = getBufferFlags(); + + //---- + + if ((flags & Buf::BF_WakeCounter) == 0) + mBufferedWakeCounter = getScArticulation().getWakeCounter(); + else if (!(flags & (Buf::BF_WakeUp | Buf::BF_PutToSleep))) // if there has been at least one buffered sleep state transition, then there is no use in adjusting the wake counter separately because it will + // get done in the sleep state update. + { + PX_ASSERT(mBufferedWakeCounter == 0.0f); // a wake counter change is always connected to a sleep state change, except one case: if setWakeCounter(0.0f) was called + + getScArticulation().setWakeCounter(mBufferedWakeCounter); + } + + //---- + + bool isSimObjectSleeping = getScArticulation().isSleeping(); + if ((flags & (Buf::BF_WakeUp | Buf::BF_PutToSleep)) == 0) + { + if (getControlState() != ControlState::eREMOVE_PENDING) // we do not want the simulation sleep state to take effect if the object was removed (free standing objects have buffered state sleeping) + mBufferedIsSleeping = PxU8(isSimObjectSleeping); + else + PX_ASSERT(mBufferedIsSleeping); // this must get set immediately at remove + } + else + { + PX_ASSERT(flags & Buf::BF_WakeCounter); // sleep state transitions always mark the wake counter dirty + PX_ASSERT(getControlState() != ControlState::eREMOVE_PENDING); // removing an object should clear pending wakeUp/putToSleep operations since the state for a free standing object gets set according to specification. + + if (flags & Buf::BF_PutToSleep) + { + PX_ASSERT(mBufferedIsSleeping); + PX_ASSERT(!(flags & Buf::BF_WakeUp)); + PX_ASSERT(mBufferedWakeCounter == 0.0f); + getScArticulation().putToSleep(); + } + else + { + PX_ASSERT(!mBufferedIsSleeping); + PX_ASSERT(flags & Buf::BF_WakeUp); + + getScArticulation().wakeUp(mBufferedWakeCounter); + } + } + + //---- + + if(flags&~(Buf::BF_WakeCounter|Buf::BF_WakeUp|Buf::BF_PutToSleep)) // Optimization to avoid all the if-statements below if possible + { + const Buf* PX_RESTRICT buffer = getArticulationBuffer(); + + flush<Buf::BF_ExternalDriveIterations>(*buffer); + flush<Buf::BF_InternalDriveIterations>(*buffer); + flush<Buf::BF_MaxProjectionIterations>(*buffer); + flush<Buf::BF_SeparationTolerance>(*buffer); + flush<Buf::BF_SleepThreshold>(*buffer); + flush<Buf::BF_SolverIterationCounts>(*buffer); + flush<Buf::BF_FreezeThreshold>(*buffer); + } + + // -------------- + // postconditions + // + PX_ASSERT((getControlState() != ControlState::eREMOVE_PENDING) || mBufferedIsSleeping); // nothing in this method should change this + // + // postconditions + // -------------- + + postSyncState(); +} + +} // namespace Scb + +} + +#endif |