// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of NVIDIA CORPORATION nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Copyright (c) 2008-2018 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_FSACTOR #define PX_PHYSICS_SCB_FSACTOR #include "ScActorCore.h" #include "PsUtilities.h" #include "ScbBase.h" #include "ScbDefs.h" #include "PxClient.h" namespace physx { namespace Scb { struct ActorBuffer { template struct Fns {}; typedef Sc::ActorCore Core; typedef ActorBuffer Buf; SCB_REGULAR_ATTRIBUTE (0, PxActorFlags, ActorFlags) SCB_REGULAR_ATTRIBUTE (1, PxDominanceGroup, DominanceGroup) SCB_REGULAR_ATTRIBUTE (2, PxActorClientBehaviorFlags, ClientBehaviorFlags) enum { AttrCount = 3 }; protected: ~ActorBuffer(){} }; class Actor : 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 ActorBuffer Buf; typedef Sc::ActorCore Core; public: // PX_SERIALIZATION Actor(const PxEMPTY) : Base(PxEmpty) {} static void getBinaryMetaData(PxOutputStream& stream); //~PX_SERIALIZATION PX_INLINE Actor() {} //--------------------------------------------------------------------------------- // Wrapper for Sc::Actor interface //--------------------------------------------------------------------------------- PX_INLINE PxActorFlags getActorFlags() const { return read(); } PX_INLINE void setActorFlags(PxActorFlags v); PX_INLINE PxDominanceGroup getDominanceGroup() const { return read(); } PX_INLINE void setDominanceGroup(PxDominanceGroup v) { write(v); } PX_INLINE PxActorClientBehaviorFlags getClientBehaviorFlags() const { return read(); } PX_INLINE void setClientBehaviorFlags(PxActorClientBehaviorFlags v){ write(v); } PX_INLINE void setOwnerClient( PxClientID inId ); PX_INLINE PxClientID getOwnerClient() const { return getActorCore().getOwnerClient(); } //immutable, so this should be fine. //--------------------------------------------------------------------------------- // Miscellaneous //--------------------------------------------------------------------------------- PX_FORCE_INLINE const Core& getActorCore() const { return *reinterpret_cast(reinterpret_cast(this) + sOffsets.scbToSc[getScbType()]); } PX_FORCE_INLINE Core& getActorCore() { return *reinterpret_cast(reinterpret_cast(this) + sOffsets.scbToSc[getScbType()]); } PX_FORCE_INLINE static const Actor& fromSc(const Core& a) { return *reinterpret_cast(reinterpret_cast(&a) - sOffsets.scToScb[a.getActorCoreType()]); } PX_FORCE_INLINE static Actor& fromSc(Core &a) { return *reinterpret_cast(reinterpret_cast(&a) - sOffsets.scToScb[a.getActorCoreType()]); } PX_FORCE_INLINE PxActorType::Enum getActorType() const { return getActorCore().getActorCoreType(); } protected: PX_INLINE void syncState(); //--------------------------------------------------------------------------------- // Infrastructure for regular attributes //--------------------------------------------------------------------------------- struct Access: public BufferedAccess {}; template PX_FORCE_INLINE typename Buf::Fns::Arg read() const { return Access::read >(*this, getActorCore()); } template PX_FORCE_INLINE void write(typename Buf::Fns::Arg v) { Access::write >(*this, getActorCore(), v); } template PX_FORCE_INLINE void flush(Core& core, const Buf& buf) { Access::flush >(*this, core, buf); } protected: ~Actor() {} struct Offsets { size_t scToScb[PxActorType::eACTOR_COUNT]; size_t scbToSc[ScbType::eTYPE_COUNT]; Offsets(); }; static const Offsets sOffsets; }; PX_INLINE void Actor::setActorFlags(PxActorFlags v) { #if PX_CHECKED PxActorFlags aFlags = getActorFlags(); PxActorType::Enum aType = getActorType(); if((!aFlags.isSet(PxActorFlag::eDISABLE_SIMULATION)) && v.isSet(PxActorFlag::eDISABLE_SIMULATION) && (aType != PxActorType::eRIGID_DYNAMIC) && (aType != PxActorType::eRIGID_STATIC)) { Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxActor::setActorFlag: PxActorFlag::eDISABLE_SIMULATION is only supported by PxRigidDynamic and PxRigidStatic objects."); } #endif write(v); } PX_INLINE void Actor::setOwnerClient(PxClientID inId) { //This call is only valid if we aren't in a scene. //Thus we can't be buffering yet if(!isBuffering()) { getActorCore().setOwnerClient( inId ); UPDATE_PVD_PROPERTIES_OBJECT() } else { Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Attempt to set the client id when an actor is buffering"); } } PX_INLINE void Actor::syncState() { //this should be called from syncState() of derived classes const PxU32 flags = getBufferFlags(); if(flags & (Buf::BF_ActorFlags|Buf::BF_DominanceGroup|Buf::BF_ClientBehaviorFlags)) { Core& core = getActorCore(); const Buf& buffer = *reinterpret_cast(getStream()); flush(core, buffer); flush(core, buffer); flush(core, buffer); } } } // namespace Scb } #endif