void PxCollectionExt::releaseObjects(PxCollection& collection, bool releaseExclusiveShapes) { shdfnd::Array<PxBase*> releasableObjects; for (PxU32 i = 0; i < collection.getNbObjects(); ++i) { PxBase* s = &collection.getObject(i); // pruning structure must be released before its actors if(s->is<PxPruningStructure>()) { if(!releasableObjects.empty()) { PxBase* first = releasableObjects[0]; releasableObjects.pushBack(first); releasableObjects[0] = s; } } else { if (s->isReleasable() && (releaseExclusiveShapes || !s->is<PxShape>() || !s->is<PxShape>()->isExclusive())) releasableObjects.pushBack(s); } } for (PxU32 i = 0; i < releasableObjects.size(); ++i) releasableObjects[i]->release(); while (collection.getNbObjects() > 0) collection.remove(collection.getObject(0)); }
void PxCollectionExt::releaseObjects(PxCollection& collection) { shdfnd::Array<PxBase*> releasableObjects; for (PxU32 i = 0; i < collection.getNbObjects(); ++i) { PxBase* s = &collection.getObject(i); if(s->isReleasable()) releasableObjects.pushBack(s); } for (PxU32 i = 0; i < releasableObjects.size(); ++i) releasableObjects[i]->release(); while (collection.getNbObjects() > 0) collection.remove(collection.getObject(0)); }
void PxCollectionExt::remove(PxCollection& collection, PxType concreteType, PxCollection* to) { shdfnd::Array<PxBase*> removeObjects; for (PxU32 i = 0; i < collection.getNbObjects(); i++) { PxBase& object = collection.getObject(i); if(concreteType == object.getConcreteType()) { if(to) to->add(object); removeObjects.pushBack(&object); } } for (PxU32 i = 0; i < removeObjects.size(); ++i) collection.remove(*removeObjects[i]); }
bool PxSerialization::isSerializable(PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* externalReferences) { PxCollection* subordinateCollection = PxCreateCollection(); PX_ASSERT(subordinateCollection); for(PxU32 i = 0; i < collection.getNbObjects(); ++i) { PxBase& s = collection.getObject(i); const PxSerializer* serializer = sr.getSerializer(s.getConcreteType()); PX_ASSERT(serializer); if(serializer->isSubordinate()) subordinateCollection->add(s); if(externalReferences) { PxSerialObjectId id = collection.getId(s); if(id != PX_SERIAL_OBJECT_ID_INVALID) { PxBase* object = externalReferences->find(id); if(object && (object != &s)) { subordinateCollection->release(); Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::isSerializable: Reference id %llu used both in current collection and in externalReferences. " "Please use unique identifiers.", id); return false; } } } } PxCollection* requiresCollection = PxCreateCollection(); PX_ASSERT(requiresCollection); RequiresCallback requiresCallback0(*requiresCollection); for (PxU32 i = 0; i < collection.getNbObjects(); ++i) { PxBase& s = collection.getObject(i); const PxSerializer* serializer = sr.getSerializer(s.getConcreteType()); PX_ASSERT(serializer); serializer->requires(s, requiresCallback0); Cm::Collection* cmRequiresCollection = static_cast<Cm::Collection*>(requiresCollection); for(PxU32 j = 0; j < cmRequiresCollection->getNbObjects(); ++j) { PxBase& s0 = cmRequiresCollection->getObject(j); if(subordinateCollection->contains(s0)) { subordinateCollection->remove(s0); continue; } bool requiredIsInCollection = collection.contains(s0); if(!requiredIsInCollection) { if(externalReferences) { if(!externalReferences->contains(s0)) { Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::isSerializable: Object of type %s references a missing object of type %s. " "The missing object needs to be added to either the current collection or the externalReferences collection.", s.getConcreteTypeName(), s0.getConcreteTypeName()); } else if(externalReferences->getId(s0) == PX_SERIAL_OBJECT_ID_INVALID) { Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::isSerializable: Object of type %s in externalReferences collection requires an id.", s0.getConcreteTypeName()); } else continue; } else { Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::isSerializable: Object of type %s references a missing serial object of type %s. " "Please completed the collection or specify an externalReferences collection containing the object.", s.getConcreteTypeName(), s0.getConcreteTypeName()); } subordinateCollection->release(); requiresCollection->release(); return false; } } cmRequiresCollection->mObjects.clear(); } requiresCollection->release(); PxU32 numOrphans = subordinateCollection->getNbObjects(); for(PxU32 j = 0; j < numOrphans; ++j) { PxBase& subordinate = subordinateCollection->getObject(j); Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::isSerializable: An object of type %s is subordinate but not required " "by other objects in the collection (orphan). Please remove the object from the collection or add its owner.", subordinate.getConcreteTypeName()); } subordinateCollection->release(); if(numOrphans>0) return false; if(externalReferences) { PxCollection* oppositeRequiresCollection = PxCreateCollection(); PX_ASSERT(oppositeRequiresCollection); RequiresCallback requiresCallback(*oppositeRequiresCollection); for (PxU32 i = 0; i < externalReferences->getNbObjects(); ++i) { PxBase& s = externalReferences->getObject(i); const PxSerializer* serializer = sr.getSerializer(s.getConcreteType()); PX_ASSERT(serializer); serializer->requires(s, requiresCallback); Cm::Collection* cmCollection = static_cast<Cm::Collection*>(oppositeRequiresCollection); for(PxU32 j = 0; j < cmCollection->getNbObjects(); ++j) { PxBase& s0 = cmCollection->getObject(j); if(collection.contains(s0)) { oppositeRequiresCollection->release(); Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::isSerializable: Object of type %s in externalReferences references an object " "of type %s in collection (circular dependency).", s.getConcreteTypeName(), s0.getConcreteTypeName()); return false; } } cmCollection->mObjects.clear(); } oppositeRequiresCollection->release(); } return true; }