aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysX/src/NpActor.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysX/src/NpActor.cpp
downloadphysx-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/NpActor.cpp')
-rw-r--r--PhysX_3.4/Source/PhysX/src/NpActor.cpp511
1 files changed, 511 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysX/src/NpActor.cpp b/PhysX_3.4/Source/PhysX/src/NpActor.cpp
new file mode 100644
index 00000000..940c1dc8
--- /dev/null
+++ b/PhysX_3.4/Source/PhysX/src/NpActor.cpp
@@ -0,0 +1,511 @@
+// 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.
+
+
+#include "NpActor.h"
+#include "PxRigidActor.h"
+#include "NpConstraint.h"
+#include "NpFactory.h"
+#include "NpShape.h"
+#include "NpPhysics.h"
+#include "NpAggregate.h"
+#include "NpScene.h"
+#include "NpRigidStatic.h"
+#include "NpRigidDynamic.h"
+#include "NpParticleSystem.h"
+#include "NpParticleFluid.h"
+#include "NpArticulationLink.h"
+#include "NpCloth.h"
+#include "CmTransformUtils.h"
+
+using namespace physx;
+
+///////////////////////////////////////////////////////////////////////////////
+
+NpActor::NpActor(const char* name) :
+ mName(name),
+ mConnectorArray(NULL)
+{
+}
+
+NpActor::~NpActor()
+{
+}
+
+
+typedef Ps::HashMap<NpActor*, NpConnectorArray*> ConnectorMap;
+struct NpActorUserData
+{
+ PxU32 referenceCount;
+ ConnectorMap* tmpOriginalConnectors;
+};
+
+void NpActor::exportExtraData(PxSerializationContext& stream)
+{
+ const PxCollection& collection = stream.getCollection();
+ if(mConnectorArray)
+ {
+ PxU32 connectorSize = mConnectorArray->size();
+ PxU32 missedCount = 0;
+ for(PxU32 i = 0; i < connectorSize; ++i)
+ {
+ NpConnector& c = (*mConnectorArray)[i];
+ PxBase* object = c.mObject;
+ if(!collection.contains(*object))
+ {
+ ++missedCount;
+ }
+ }
+
+ NpConnectorArray* exportConnectorArray = mConnectorArray;
+
+ if(missedCount > 0)
+ {
+ exportConnectorArray = NpFactory::getInstance().acquireConnectorArray();
+ if(missedCount < connectorSize)
+ {
+ exportConnectorArray->reserve(connectorSize - missedCount);
+ for(PxU32 i = 0; i < connectorSize; ++i)
+ {
+ NpConnector& c = (*mConnectorArray)[i];
+ PxBase* object = c.mObject;
+ if(collection.contains(*object))
+ {
+ exportConnectorArray->pushBack(c);
+ }
+ }
+ }
+ }
+
+ stream.alignData(PX_SERIAL_ALIGN);
+ stream.writeData(exportConnectorArray, sizeof(NpConnectorArray));
+ Cm::exportInlineArray(*exportConnectorArray, stream);
+
+ if(missedCount > 0)
+ NpFactory::getInstance().releaseConnectorArray(exportConnectorArray);
+ }
+ stream.writeName(mName);
+}
+
+void NpActor::importExtraData(PxDeserializationContext& context)
+{
+ if(mConnectorArray)
+ {
+ mConnectorArray = context.readExtraData<NpConnectorArray, PX_SERIAL_ALIGN>();
+ new (mConnectorArray) NpConnectorArray(PxEmpty);
+
+ if(mConnectorArray->size() == 0)
+ mConnectorArray = NULL;
+ else
+ Cm::importInlineArray(*mConnectorArray, context);
+ }
+ context.readName(mName);
+}
+
+void NpActor::resolveReferences(PxDeserializationContext& context)
+{
+ // Resolve connector pointers if needed
+ if(mConnectorArray)
+ {
+ const PxU32 nbConnectors = mConnectorArray->size();
+ for(PxU32 i=0; i<nbConnectors; i++)
+ {
+ NpConnector& c = (*mConnectorArray)[i];
+ context.translatePxBase(c.mObject);
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void NpActor::releaseConstraints(PxRigidActor& owner)
+{
+ if(mConnectorArray)
+ {
+ PxU32 nbConnectors = mConnectorArray->size();
+ PxU32 currentIndex = 0;
+ while(nbConnectors--)
+ {
+ NpConnector& connector = (*mConnectorArray)[currentIndex];
+ if (connector.mType == NpConnectorType::eConstraint)
+ {
+ NpConstraint* c = static_cast<NpConstraint*>(connector.mObject);
+ c->actorDeleted(&owner);
+
+ NpScene* s = c->getNpScene();
+ if (s)
+ {
+ s->getScene().removeConstraint(c->getScbConstraint());
+ s->removeFromConstraintList(*c);
+ }
+
+ removeConnector(owner, currentIndex);
+ }
+ else
+ currentIndex++;
+ }
+ }
+}
+
+void NpActor::release(PxActor& owner)
+{
+// PX_AGGREGATE
+ if (mConnectorArray) // Need to test again because the code above might purge the connector array if no element remains
+ {
+ PX_ASSERT(mConnectorArray->size() == 1); // At this point only the aggregate should remain
+ PX_ASSERT((*mConnectorArray)[0].mType == NpConnectorType::eAggregate);
+
+ NpAggregate* a = static_cast<NpAggregate*>((*mConnectorArray)[0].mObject);
+ bool status = a->removeActorAndReinsert(owner, false);
+ PX_ASSERT(status);
+ PX_UNUSED(status);
+ PX_ASSERT(!mConnectorArray); // Remove should happen in aggregate code
+ }
+//~PX_AGGREGATE
+
+ PX_ASSERT(!mConnectorArray); // All the connector objects should have been removed at this point
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+PxU32 NpActor::findConnector(NpConnectorType::Enum type, PxBase* object) const
+{
+ if(!mConnectorArray)
+ return 0xffffffff;
+
+ for(PxU32 i=0; i < mConnectorArray->size(); i++)
+ {
+ NpConnector& c = (*mConnectorArray)[i];
+ if (c.mType == type && c.mObject == object)
+ return i;
+ }
+
+ return 0xffffffff;
+}
+
+void NpActor::addConnector(NpConnectorType::Enum type, PxBase* object, const char* errMsg)
+{
+ if(!mConnectorArray)
+ mConnectorArray = NpFactory::getInstance().acquireConnectorArray();
+
+ PX_CHECK_MSG(findConnector(type, object) == 0xffffffff, errMsg);
+ PX_UNUSED(errMsg);
+
+ if(mConnectorArray->isInUserMemory() && mConnectorArray->size() == mConnectorArray->capacity())
+ {
+ NpConnectorArray* newConnectorArray = NpFactory::getInstance().acquireConnectorArray();
+ newConnectorArray->assign(mConnectorArray->begin(), mConnectorArray->end());
+ mConnectorArray->~NpConnectorArray();
+ mConnectorArray = newConnectorArray;
+ }
+
+ NpConnector c(type, object);
+ mConnectorArray->pushBack(c);
+}
+
+void NpActor::removeConnector(PxActor& /*owner*/, PxU32 index)
+{
+ PX_ASSERT(mConnectorArray);
+ PX_ASSERT(index < mConnectorArray->size());
+
+ mConnectorArray->replaceWithLast(index);
+
+ if(mConnectorArray->size() == 0)
+ {
+ if(!mConnectorArray->isInUserMemory())
+ NpFactory::getInstance().releaseConnectorArray(mConnectorArray);
+ else
+ mConnectorArray->~NpConnectorArray();
+ mConnectorArray = NULL;
+ }
+}
+
+void NpActor::removeConnector(PxActor& owner, NpConnectorType::Enum type, PxBase* object, const char* errorMsg)
+{
+ PX_CHECK_MSG(mConnectorArray, errorMsg);
+ PX_UNUSED(errorMsg);
+
+ if(mConnectorArray)
+ {
+ PxU32 index = findConnector(type, object);
+
+ PX_CHECK_MSG(index != 0xffffffff, errorMsg);
+
+ removeConnector(owner, index);
+ }
+}
+
+PxU32 NpActor::getNbConnectors(NpConnectorType::Enum type) const
+{
+ PxU32 nbConnectors = 0;
+
+ if(mConnectorArray)
+ {
+ for(PxU32 i=0; i < mConnectorArray->size(); i++)
+ {
+ if ((*mConnectorArray)[i].mType == type)
+ nbConnectors++;
+ }
+ }
+
+ return nbConnectors;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+NpAggregate* NpActor::getNpAggregate(PxU32& index) const
+{
+ PX_ASSERT(getNbConnectors(NpConnectorType::eAggregate) <= 1);
+
+ if(mConnectorArray)
+ {
+ // PT: TODO: sort by type to optimize this...
+ for(PxU32 i=0; i < mConnectorArray->size(); i++)
+ {
+ NpConnector& c = (*mConnectorArray)[i];
+ if (c.mType == NpConnectorType::eAggregate)
+ {
+ index = i;
+ return static_cast<NpAggregate*>(c.mObject);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void NpActor::setAggregate(NpAggregate* np, PxActor& owner)
+{
+ PxU32 index = 0xffffffff;
+ NpAggregate* a = getNpAggregate(index);
+
+ if (!a)
+ {
+ PX_ASSERT(np);
+ addConnector(NpConnectorType::eAggregate, np, "NpActor::setAggregate() failed");
+ }
+ else
+ {
+ PX_ASSERT(mConnectorArray);
+ PX_ASSERT(index != 0xffffffff);
+ if (!np)
+ removeConnector(owner, index);
+ else
+ (*mConnectorArray)[index].mObject = np;
+ }
+}
+
+PxAggregate* NpActor::getAggregate() const
+{
+ PxU32 index = 0xffffffff;
+ NpAggregate* a = getNpAggregate(index);
+ return static_cast<PxAggregate*>(a);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+void NpActor::removeConstraintsFromScene()
+{
+ NpConnectorIterator iter = getConnectorIterator(NpConnectorType::eConstraint);
+ while (PxBase* ser = iter.getNext())
+ {
+ NpConstraint* c = static_cast<NpConstraint*>(ser);
+
+ NpScene* s = c->getNpScene();
+
+ if (s)
+ {
+ s->removeFromConstraintList(*c);
+ s->getScene().removeConstraint(c->getScbConstraint());
+ }
+ }
+}
+
+void NpActor::addConstraintsToSceneInternal()
+{
+ if(!mConnectorArray)
+ return;
+
+ NpConnectorIterator iter = getConnectorIterator(NpConnectorType::eConstraint);
+ while (PxBase* ser = iter.getNext())
+ {
+ NpConstraint* c = static_cast<NpConstraint*>(ser);
+ PX_ASSERT(c->getNpScene() == NULL);
+
+ c->markDirty(); // PT: "temp" fix for crash when removing/re-adding jointed actor from/to a scene
+
+ NpScene* s = c->getSceneFromActors();
+ if (s)
+ {
+ s->addToConstraintList(*c);
+ s->getScene().addConstraint(c->getScbConstraint());
+ }
+ }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+NpShapeManager* NpActor::getShapeManager(PxRigidActor& actor)
+{
+ // DS: if the performance here becomes an issue we can use the same kind of offset hack as below
+
+ const PxType actorType = actor.getConcreteType();
+
+ if (actorType == PxConcreteType::eRIGID_DYNAMIC)
+ return &static_cast<NpRigidDynamic&>(actor).getShapeManager();
+ else if(actorType == PxConcreteType::eRIGID_STATIC)
+ return &static_cast<NpRigidStatic&>(actor).getShapeManager();
+ else if (actorType == PxConcreteType::eARTICULATION_LINK)
+ return &static_cast<NpArticulationLink&>(actor).getShapeManager();
+ else
+ {
+ PX_ASSERT(0);
+ return NULL;
+ }
+}
+
+const NpShapeManager* NpActor::getShapeManager(const PxRigidActor& actor)
+{
+ // DS: if the performance here becomes an issue we can use the same kind of offset hack as below
+
+ const PxType actorType = actor.getConcreteType();
+
+ if (actorType == PxConcreteType::eRIGID_DYNAMIC)
+ return &static_cast<const NpRigidDynamic&>(actor).getShapeManager();
+ else if(actorType == PxConcreteType::eRIGID_STATIC)
+ return &static_cast<const NpRigidStatic&>(actor).getShapeManager();
+ else if (actorType == PxConcreteType::eARTICULATION_LINK)
+ return &static_cast<const NpArticulationLink&>(actor).getShapeManager();
+ else
+ {
+ PX_ASSERT(0);
+ return NULL;
+ }
+}
+
+void NpActor::getGlobalPose(PxTransform& globalPose, const NpShape& shape, const PxRigidActor& actor)
+{
+ const Scb::Actor& scbActor = NpActor::getScbFromPxActor(actor);
+ const Scb::Shape& scbShape = shape.getScbShape();
+
+ NpActor::getGlobalPose(globalPose, scbShape, scbActor);
+}
+
+void NpActor::getGlobalPose(PxTransform& globalPose, const Scb::Shape& scbShape, const Scb::Actor& scbActor)
+{
+ const PxTransform& shape2Actor = scbShape.getShape2Actor();
+
+ // PT: TODO: duplicated from SqBounds.cpp. Refactor.
+ const ScbType::Enum actorType = scbActor.getScbType();
+ if(actorType==ScbType::RIGID_STATIC)
+ {
+ Cm::getStaticGlobalPoseAligned(static_cast<const Scb::RigidStatic&>(scbActor).getActor2World(), shape2Actor, globalPose);
+ }
+ else
+ {
+ PX_ASSERT(actorType==ScbType::BODY || actorType == ScbType::BODY_FROM_ARTICULATION_LINK);
+
+ const Scb::Body& body = static_cast<const Scb::Body&>(scbActor);
+ PX_ALIGN(16, PxTransform) kinematicTarget;
+ const PxU16 sqktFlags = PxRigidBodyFlag::eKINEMATIC | PxRigidBodyFlag::eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES;
+ const bool useTarget = (PxU16(body.getFlags()) & sqktFlags) == sqktFlags;
+ const PxTransform& body2World = (useTarget && body.getKinematicTarget(kinematicTarget)) ? kinematicTarget : body.getBody2World();
+ Cm::getDynamicGlobalPoseAligned(body2World, shape2Actor, body.getBody2Actor(), globalPose);
+ }
+}
+
+namespace
+{
+ template <typename N> NpActor* pxToNpActor(PxActor *p)
+ {
+ return static_cast<NpActor*>(static_cast<N*>(p));
+ }
+
+ template <typename N> const NpActor* pxToNpActor(const PxActor *p)
+ {
+ return static_cast<const NpActor*>(static_cast<const N*>(p));
+ }
+}
+
+NpActor::Offsets::Offsets()
+{
+ for(PxU32 i=0;i<PxConcreteType::ePHYSX_CORE_COUNT;i++)
+ pxActorToScbActor[i] = pxActorToNpActor[i] = 0;
+ size_t addr = 0x100; // casting the null ptr takes a special-case code path, which we don't want
+ PxActor* n = reinterpret_cast<PxActor*>(addr);
+ pxActorToNpActor[PxConcreteType::eRIGID_STATIC] = reinterpret_cast<size_t>(pxToNpActor<NpRigidStatic>(n)) - addr;
+ pxActorToNpActor[PxConcreteType::eRIGID_DYNAMIC] = reinterpret_cast<size_t>(pxToNpActor<NpRigidDynamic>(n)) - addr;
+#if PX_USE_PARTICLE_SYSTEM_API
+ pxActorToNpActor[PxConcreteType::ePARTICLE_SYSTEM] = reinterpret_cast<size_t>(pxToNpActor<NpParticleSystem>(n)) - addr;
+ pxActorToNpActor[PxConcreteType::ePARTICLE_FLUID] = reinterpret_cast<size_t>(pxToNpActor<NpParticleFluid>(n)) - addr;
+#endif
+ pxActorToNpActor[PxConcreteType::eARTICULATION_LINK] = reinterpret_cast<size_t>(pxToNpActor<NpArticulationLink>(n)) - addr;
+#if PX_USE_CLOTH_API
+ pxActorToNpActor[PxConcreteType::eCLOTH] = reinterpret_cast<size_t>(pxToNpActor<NpCloth>(n)) - addr;
+#endif
+
+ pxActorToScbActor[PxConcreteType::eRIGID_STATIC] = PX_OFFSET_OF_RT(NpRigidStatic, getScbActorFast());
+ pxActorToScbActor[PxConcreteType::eRIGID_DYNAMIC] = PX_OFFSET_OF_RT(NpRigidDynamic, getScbActorFast());
+#if PX_USE_PARTICLE_SYSTEM_API
+ pxActorToScbActor[PxConcreteType::ePARTICLE_SYSTEM] = PX_OFFSET_OF_RT(NpParticleSystem, getScbActor());
+ pxActorToScbActor[PxConcreteType::ePARTICLE_FLUID] = PX_OFFSET_OF_RT(NpParticleFluid, getScbActor());
+#endif
+ pxActorToScbActor[PxConcreteType::eARTICULATION_LINK] = PX_OFFSET_OF_RT(NpArticulationLink, getScbActorFast());
+#if PX_USE_CLOTH_API
+ pxActorToScbActor[PxConcreteType::eCLOTH] = PX_OFFSET_OF_RT(NpCloth, getScbCloth());
+#endif
+}
+
+const NpActor::Offsets NpActor::sOffsets;
+
+
+NpScene* NpActor::getOwnerScene(const PxActor& actor)
+{
+ const Scb::Actor& scbActor = getScbFromPxActor(actor);
+ Scb::Scene* scbScene = scbActor.getScbScene();
+ return scbScene? static_cast<NpScene*>(scbScene->getPxScene()) : NULL;
+}
+
+NpScene* NpActor::getAPIScene(const PxActor& actor)
+{
+ const Scb::Actor& scbActor = getScbFromPxActor(actor);
+ Scb::Scene* scbScene = scbActor.getScbSceneForAPI();
+ return scbScene? static_cast<NpScene*>(scbScene->getPxScene()) : NULL;
+}
+
+void NpActor::onActorRelease(PxActor* actor)
+{
+ NpFactory::getInstance().onActorRelease(actor);
+}