Пример #1
0
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));
}
Пример #2
0
PxRigidActor* CPhysicManager::createFromFile(const std::string &file, int group, const IPhysic *component)
{
    assert(m_scene);

    PxSerializationRegistry* registry = PxSerialization::createSerializationRegistry(*m_physics);
    PxDefaultFileInputData data(file.c_str());
    PxCollection* collection;

    collection = PxSerialization::createCollectionFromXml(data, *m_cooking, *registry);

    m_scene->addCollection(*collection);

    PxRigidActor *actor = nullptr;
    for (unsigned int i=0; (i<collection->getNbObjects()) && !actor; i++) {
        actor = collection->getObject(i).is<PxRigidActor>();
    }
    assert(actor);

    actor->userData = (void*)component;

    PxSetGroup(*actor,group);

    collection->release();
    registry->release();

    return actor;
}
Пример #3
0
PxRigidActor* CServer::createFromFile(const std::string &file, int group, const IPhysics *component)
{
	assert(_scene);

	// Preparar parámetros para deserializar
	PxSerializationRegistry* registry = PxSerialization::createSerializationRegistry(*_physics); 
	PxDefaultFileInputData data(file.c_str());
	PxCollection* collection;

	// Deserializar a partir del fichero RepX
	collection = PxSerialization::createCollectionFromXml(data, *_cooking, *registry);
	
	// Añadir entidades físicas a la escena
	_scene->addCollection(*collection); 
	
	// Buscar una entidad de tipo PxRigidActor. Asumimos que hay exactamente 1 en el fichero.
	PxRigidActor *actor = NULL;
	for (unsigned int i=0; (i<collection->getNbObjects()) && !actor; i++) {
		actor = collection->getObject(i).is<PxRigidActor>();		
	}
	assert(actor);
	
	// Anotar el componente lógico asociado a la entidad física
	actor->userData = (void *) component;

	// Establecer el grupo de colisión
	PxSetGroup(*actor, group);

	// Liberar recursos
	collection->release();
	registry->release();

	return actor;
}
Пример #4
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));
}
Пример #5
0
	void CEntity::deserializeFromRepXFile(const std::string &file, int group, const std::vector<int>& groupList, const Logic::IPhysics* component) {
		// Obtenemos el puntero al servidor de fisicas
		Physics::CServer* physicsServer = Physics::CServer::getSingletonPtr();
		PxScene* scene = physicsServer->getActiveScene();
		PxPhysics* physics = physicsServer->getPhysxSDK();
		PxCooking* cooking = physicsServer->getCooking();
		assert(scene);

		// Preparar parámetros para deserializar
		PxDefaultFileInputData data(file.c_str());
		PxCollection* bufferCollection = physics->createCollection();
		PxCollection* sceneCollection = physics->createCollection(); 
		PxStringTable* stringTable = &PxStringTableExt::createStringTable( CServer::getSingletonPtr()->getFoundation()->getAllocatorCallback() ); 
		PxUserReferences* externalRefs = NULL; 
		PxUserReferences* userRefs = NULL; 

		// Deserializar a partir del fichero RepX
		repx::deserializeFromRepX(data, *physics, *cooking, stringTable, externalRefs, 
								  *bufferCollection, *sceneCollection, userRefs);


		// Añadir entidades físicas a la escena
		physics->addCollection(*sceneCollection, *scene);

		// Buscar una entidad de tipo PxRigidActor. Asumimos que hay exactamente 1 en el fichero.
		_actor = NULL;
		for (unsigned int i = 0; i < sceneCollection->getNbObjects() && !_actor; ++i) {
			PxSerializable* p = sceneCollection->getObject(i);
			_actor = p->is<PxRigidActor>();
		}
		assert(_actor);

		// Anotar el componente lógico asociado a la entidad física
		_actor->userData = (void*)component;

		// Establecer el grupo de colisión
		PxSetGroup(*_actor, group);
		// Establecer los filtros de colisión
		Physics::CServer::getSingletonPtr()->setupFiltering(_actor, group, groupList);

		// Liberar recursos
		bufferCollection->release();
		sceneCollection->release();
	}
Пример #6
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]);
}
Пример #7
0
void PxSerialization::createSerialObjectIds(PxCollection& collection, const PxSerialObjectId base)
{
	PxSerialObjectId localBase = base;
	PxU32 nbObjects = collection.getNbObjects();

	for (PxU32 i = 0; i < nbObjects; ++i)
	{
		while(collection.find(localBase))
		{
			localBase++;
		}

		PxBase& s = collection.getObject(i);		
		if(PX_SERIAL_OBJECT_ID_INVALID == collection.getId(s))
		{
			collection.addId(s, localBase);
			localBase++;
		}
	}
}
Пример #8
0
bool PhysXWorld::ExportWholeScene(const char *filename) const
{
	using namespace physx::repx;
	if (!PhysXSDK || !PhysXScene)
		return false;

	PxCollection *cl = PhysXSDK->createCollection();
	if (!cl)
		return false;

	PhysxUserFileWriteStream fs(filename);

	RepXCollection* theCollection = createCollection(PhysXSDK->getTolerancesScale(), PhysXFoundation->getAllocatorCallback());
	RepXIdToRepXObjectMap* theIdMap =  RepXIdToRepXObjectMap::create(PxGetFoundation().getAllocatorCallback());
	addSDKItemsToRepX ( *PhysXSDK, *theIdMap, *theCollection); //add physcis object
	addSceneItemsToRepX ( *PhysXScene, *theIdMap, *theCollection); //add physcis object
//	physx::repx::addObjectsToScene(theCollection, physics, cooking, scene, mStringTable );
	theCollection->save(fs);
	theCollection->destroy();
	theIdMap->destroy();
	return true;


//	PxCollectForExportSDK(*PhysXSDK, *cl);
//	PxCollectForExportScene(*PhysXScene, *cl);
	ObjectIterator iter = GameWorld().GetFirstOfAllObjects();

	while( iter.current )
	{
		GameObject* o = iter.current;

		if (o->PhysicsObject)
		{
			PxActor *a = o->PhysicsObject->getPhysicsActor();
			PxSerialFlags f = a->getSerialFlags();
			a->collectForExport(*cl);
			break;
		}

		iter = GameWorld().GetNextOfAllObjects( iter );
	}
	PxU32 numObjs = cl->getNbObjects();
	numObjs;

	cl->serialize(fs);

	PhysXSDK->releaseCollection(*cl);
	fclose(fs.fpw);

	FILE* fp=NULL;

	if( (fp = fopen(filename, "rb")) )
	{
		fseek(fp, 0, SEEK_END);
		PxU32 fileSize = ftell(fp);
		fseek(fp, 0, SEEK_SET);

		PX_ASSERT(fileSize!=0);
		void* mem = malloc(fileSize+PX_SERIAL_FILE_ALIGN);

		void* mem16 = (void*)((size_t(mem) + PX_SERIAL_FILE_ALIGN)&~(PX_SERIAL_FILE_ALIGN-1));
		fread(mem16, 1, fileSize, fp);
		fclose(fp);

		PxUserReferences* convexRefs = PhysXSDK->createUserReferences();
		PxCollection* collection = PhysXSDK->createCollection();
		collection->deserialize(mem16, convexRefs, NULL);

		PxU32 numObjs = collection->getNbObjects();
		for (PxU32 i = 0; i < numObjs; ++i)
		{
			PxSerializable *o = collection->getObject(i);
			const char * name = o->getConcreteTypeName();
			PX_ASSERT(name);
		}
	}


	return true;
}
Пример #9
0
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;
}
bool PxSerialization::isSerializable(PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* externalReferences) 
{		
	bool bRet = true;	

	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__, 
						"NpCollection::isSerializable: object shares reference name with other object in externalReferences (reference clash).");
					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);
	}
	
	for(PxU32 j = 0; j < subordinateCollection->getNbObjects(); ++j)
	{
		PxBase& subordinate = subordinateCollection->getObject(j);
		bRet = requiresCollection->contains(subordinate);
		if(!bRet)
		{
			requiresCollection->release();
			subordinateCollection->release();
			Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, 
				"NpCollection::isSerializable: object is a subordinate and not required by other objects in the collection (orphan).");
			return false;		
		}
	}
	subordinateCollection->release();

	for(PxU32 j = 0; j < requiresCollection->getNbObjects(); ++j)
	{
		PxBase& s0 = requiresCollection->getObject(j);
		bRet = collection.contains(s0);
		if(!bRet && externalReferences)
		{
			bRet = externalReferences->contains(s0) &&  externalReferences->getId(s0) != PX_SERIAL_OBJECT_ID_INVALID;
		}
		if(!bRet)
		{
			requiresCollection->release();
			Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, 
				"NpCollection::isSerializable: cannot find a required serial object (collection is not complete).");
			return false;
		}
	}
	requiresCollection->release();

	if(externalReferences)
	{
		PxCollection* oppsiteRequiresCollection = PxCreateCollection();
		PX_ASSERT(oppsiteRequiresCollection);

		RequiresCallback requiresCallback(*oppsiteRequiresCollection);

		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);
		}

		for(PxU32 j = 0; j < oppsiteRequiresCollection->getNbObjects(); ++j)
		{
			PxBase& s0 = oppsiteRequiresCollection->getObject(j);

			if(collection.contains(s0))
			{
				oppsiteRequiresCollection->release();
				Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, 
					"NpCollection::isSerializable: object in externalReferences requires an object in collection (circular dependency).");
				return false;
			}
		}
		oppsiteRequiresCollection->release();
	}

	return true;
}