aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysX/src/NpAggregate.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/NpAggregate.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/NpAggregate.cpp')
-rw-r--r--PhysX_3.4/Source/PhysX/src/NpAggregate.cpp394
1 files changed, 394 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysX/src/NpAggregate.cpp b/PhysX_3.4/Source/PhysX/src/NpAggregate.cpp
new file mode 100644
index 00000000..4b6114fa
--- /dev/null
+++ b/PhysX_3.4/Source/PhysX/src/NpAggregate.cpp
@@ -0,0 +1,394 @@
+// 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 "NpAggregate.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "PxActor.h"
+#include "NpRigidStatic.h"
+#include "NpRigidDynamic.h"
+#include "NpParticleSystem.h"
+#include "NpParticleFluid.h"
+#include "NpArticulation.h"
+#include "CmUtils.h"
+
+using namespace physx;
+
+PX_FORCE_INLINE void setAggregate(NpAggregate* aggregate, PxActor& actor)
+{
+ NpActor& np = NpActor::getFromPxActor(actor);
+ np.setAggregate(aggregate, actor);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+NpAggregate::NpAggregate(PxU32 maxActors, bool selfCollisions)
+: PxAggregate(PxConcreteType::eAGGREGATE, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE)
+, mAggregate(this, maxActors, selfCollisions)
+, mNbActors(0)
+{
+ mActors = reinterpret_cast<PxActor**>(PX_ALLOC(sizeof(PxActor*)*maxActors, "PxActor*"));
+}
+
+NpAggregate::~NpAggregate()
+{
+ NpFactory::getInstance().onAggregateRelease(this);
+ if(getBaseFlags()&PxBaseFlag::eOWNS_MEMORY)
+ PX_FREE(mActors);
+}
+
+void NpAggregate::removeAndReinsert(PxActor& actor, bool reinsert)
+{
+ NpActor& np = NpActor::getFromPxActor(actor);
+ Scb::Actor& scb = NpActor::getScbFromPxActor(actor);
+
+ np.setAggregate(NULL, actor);
+
+ mAggregate.removeActor(scb, reinsert);
+}
+
+void NpAggregate::release()
+{
+ NP_WRITE_CHECK(getOwnerScene());
+ PX_SIMD_GUARD;
+
+ NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, NULL);
+
+ /*
+ "An aggregate should be empty when it gets released. If it isn't, the behavior should be: remove the actors from
+ the aggregate, then remove the aggregate from the scene (if any) then delete it. I guess that implies the actors
+ get individually reinserted into the broad phase if the aggregate is in a scene."
+ */
+ for(PxU32 i=0;i<mNbActors;i++)
+ {
+ if (mActors[i]->getType() == PxActorType::eARTICULATION_LINK)
+ static_cast<NpArticulationLink*>(mActors[i])->getRoot().setAggregate(NULL);
+
+ removeAndReinsert(*mActors[i], true);
+ }
+
+ NpScene* s = getAPIScene();
+ if(s)
+ {
+ s->getScene().removeAggregate(getScbAggregate());
+ s->removeFromAggregateList(*this);
+ }
+
+ mAggregate.destroy();
+}
+
+void NpAggregate::addActorInternal(PxActor& actor, NpScene& s)
+{
+ if (actor.getType() != PxActorType::eARTICULATION_LINK)
+ {
+ Scb::Actor& scb = NpActor::getScbFromPxActor(actor);
+
+ mAggregate.addActor(scb);
+
+ s.addActorInternal(actor);
+ }
+ else if (!actor.getScene()) // This check makes sure that a link of an articulation gets only added once.
+ {
+ NpArticulationLink& al = static_cast<NpArticulationLink&>(actor);
+ NpArticulation& npArt = al.getRoot();
+ NpArticulationLink* const* links = npArt.getLinks();
+ for(PxU32 i=0; i < npArt.getNbLinks(); i++)
+ {
+ mAggregate.addActor(links[i]->getScbActorFast());
+ }
+
+ s.addArticulationInternal(npArt);
+ }
+}
+
+bool NpAggregate::addActor(PxActor& actor)
+{
+ NP_WRITE_CHECK(getOwnerScene());
+ PX_SIMD_GUARD;
+
+ if(mNbActors==mAggregate.getMaxActorCount())
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't add actor to aggregate, max number of actors reached");
+ return false;
+ }
+
+ if(actor.getAggregate())
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't add actor to aggregate, actor already belongs to an aggregate");
+ return false;
+ }
+
+ if(actor.getScene())
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't add actor to aggregate, actor already belongs to a scene");
+ return false;
+ }
+
+ if(actor.getType() == PxActorType::eARTICULATION_LINK)
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't add articulation link to aggregate, only whole articulations can be added");
+ return false;
+ }
+
+ setAggregate(this, actor);
+
+ mActors[mNbActors++] = &actor;
+
+ // PT: when an object is added to a aggregate at runtime, i.e. when the aggregate has already been added to the scene,
+ // we need to immediately add the newcomer to the scene as well.
+ NpScene* s = getAPIScene();
+ if(s)
+ {
+ addActorInternal(actor, *s);
+ }
+
+ return true;
+}
+
+bool NpAggregate::removeActorAndReinsert(PxActor& actor, bool reinsert)
+{
+ for(PxU32 i=0;i<mNbActors;i++)
+ {
+ if(mActors[i]==&actor)
+ {
+ mActors[i] = mActors[--mNbActors];
+ removeAndReinsert(actor, reinsert);
+ return true;
+ }
+ }
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't remove actor, actor doesn't belong to aggregate");
+ return false;
+}
+
+bool NpAggregate::removeActor(PxActor& actor)
+{
+ NP_WRITE_CHECK(getOwnerScene());
+ PX_SIMD_GUARD;
+
+ if(actor.getType() == PxActorType::eARTICULATION_LINK)
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't remove articulation link, only whole articulations can be removed");
+ return false;
+ }
+
+ // PT: there are really 2 cases here:
+ // a) the user just wants to remove the actor from the aggregate, but the actor is still alive so if the aggregate has been added to a scene,
+ // we must reinsert the removed actor to that same scene
+ // b) this is called by the framework when releasing an actor, in which case we don't want to reinsert it anywhere.
+ //
+ // We assume that when called by the user, we always want to reinsert. The framework however will call the internal function
+ // without reinsertion.
+ return removeActorAndReinsert(actor, true);
+}
+
+bool NpAggregate::addArticulation(PxArticulation& art)
+{
+ NP_WRITE_CHECK(getOwnerScene());
+ PX_SIMD_GUARD;
+
+ if((mNbActors+art.getNbLinks()) > mAggregate.getMaxActorCount())
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't add articulation links, max number of actors reached");
+ return false;
+ }
+
+ if(art.getAggregate())
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't add articulation to aggregate, articulation already belongs to an aggregate");
+ return false;
+ }
+
+ if(art.getScene())
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't add articulation to aggregate, articulation already belongs to a scene");
+ return false;
+ }
+
+ NpArticulation& npArt = static_cast<NpArticulation&>(art);
+ npArt.setAggregate(this);
+ NpArticulationLink* const* links = npArt.getLinks();
+ for(PxU32 i=0; i < npArt.getNbLinks(); i++)
+ {
+ NpArticulationLink& l = *links[i];
+
+ setAggregate(this, l);
+
+ mActors[mNbActors++] = &l;
+
+ mAggregate.addActor(l.getScbActorFast());
+ }
+
+ // PT: when an object is added to a aggregate at runtime, i.e. when the aggregate has already been added to the scene,
+ // we need to immediately add the newcomer to the scene as well.
+ NpScene* s = getAPIScene();
+ if(s)
+ {
+ s->addArticulationInternal(art);
+ }
+
+ return true;
+}
+
+bool NpAggregate::removeArticulationAndReinsert(PxArticulation& art, bool reinsert)
+{
+ NpArticulation* npArt = static_cast<NpArticulation*>(&art);
+
+ bool found = false;
+ PxU32 idx = 0;
+ while(idx < mNbActors)
+ {
+ if ((mActors[idx]->getType() == PxActorType::eARTICULATION_LINK) && (&static_cast<NpArticulationLink*>(mActors[idx])->getRoot() == npArt))
+ {
+ PxActor* a = mActors[idx];
+ mActors[idx] = mActors[--mNbActors];
+ removeAndReinsert(*a, reinsert);
+ found = true;
+ }
+ else
+ idx++;
+ }
+
+ npArt->setAggregate(NULL);
+
+ if (!found)
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxAggregate: can't remove articulation, articulation doesn't belong to aggregate");
+ return found;
+}
+
+bool NpAggregate::removeArticulation(PxArticulation& art)
+{
+ NP_WRITE_CHECK(getOwnerScene());
+ PX_SIMD_GUARD;
+
+ // see comments in removeActor()
+ return removeArticulationAndReinsert(art, true);
+}
+
+PxU32 NpAggregate::getNbActors() const
+{
+ NP_READ_CHECK(getOwnerScene());
+ return mNbActors;
+}
+
+PxU32 NpAggregate::getMaxNbActors() const
+{
+ NP_READ_CHECK(getOwnerScene());
+ return mAggregate.getMaxActorCount();
+}
+
+PxU32 NpAggregate::getActors(PxActor** userBuffer, PxU32 bufferSize, PxU32 startIndex) const
+{
+ NP_READ_CHECK(getOwnerScene());
+ return Cm::getArrayOfPointers(userBuffer, bufferSize, startIndex, mActors, getCurrentSizeFast());
+}
+
+PxScene* NpAggregate::getScene()
+{
+ return getAPIScene();
+}
+
+NpScene* NpAggregate::getAPIScene() const
+{
+ return mAggregate.getScbSceneForAPI() ? static_cast<NpScene*>(mAggregate.getScbSceneForAPI()->getPxScene()) : NULL;
+}
+
+NpScene* NpAggregate::getOwnerScene() const
+{
+ return mAggregate.getScbScene() ? static_cast<NpScene*>(mAggregate.getScbScene()->getPxScene()) : NULL;
+}
+
+bool NpAggregate::getSelfCollision() const
+{
+ NP_READ_CHECK(getOwnerScene());
+ return mAggregate.getSelfCollide();
+}
+
+// PX_SERIALIZATION
+void NpAggregate::exportExtraData(PxSerializationContext& stream)
+{
+ if(mActors)
+ {
+ stream.alignData(PX_SERIAL_ALIGN);
+ stream.writeData(mActors, mNbActors * sizeof(PxActor*));
+ }
+}
+
+void NpAggregate::importExtraData(PxDeserializationContext& context)
+{
+ if(mActors)
+ mActors = context.readExtraData<PxActor*, PX_SERIAL_ALIGN>(mNbActors);
+}
+
+void NpAggregate::resolveReferences(PxDeserializationContext& context)
+{
+ // Resolve actor pointers if needed
+ for(PxU32 i=0; i < mNbActors; i++)
+ {
+ context.translatePxBase(mActors[i]);
+ {
+ //update aggregate if mActors is in external reference
+ NpActor& np = NpActor::getFromPxActor(*mActors[i]);
+ if(np.getAggregate() == NULL)
+ {
+ np.setAggregate(this, *mActors[i]);
+ }
+ if(mActors[i]->getType() == PxActorType::eARTICULATION_LINK)
+ {
+ NpArticulation& articulation = static_cast<NpArticulationLink*>(mActors[i])->getRoot();
+ if(!articulation.getAggregate())
+ articulation.setAggregate(this);
+ }
+ }
+ }
+}
+
+NpAggregate* NpAggregate::createObject(PxU8*& address, PxDeserializationContext& context)
+{
+ NpAggregate* obj = new (address) NpAggregate(PxBaseFlag::eIS_RELEASABLE);
+ address += sizeof(NpAggregate);
+ obj->importExtraData(context);
+ obj->resolveReferences(context);
+ return obj;
+}
+
+void NpAggregate::requires(PxProcessPxBaseCallback& c)
+{
+ for(PxU32 i=0; i < mNbActors; i++)
+ {
+ PxArticulationLink* link = mActors[i]->is<PxArticulationLink>();
+ if(link)
+ c.process(link->getArticulation());
+ else
+ c.process(*mActors[i]);
+ }
+}
+// ~PX_SERIALIZATION