当前位置: 首页>>代码示例>>C++>>正文


C++ PxCollection类代码示例

本文整理汇总了C++中PxCollection的典型用法代码示例。如果您正苦于以下问题:C++ PxCollection类的具体用法?C++ PxCollection怎么用?C++ PxCollection使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了PxCollection类的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: PxCreateCollection

void PxSerialization::complete(PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* exceptFor, bool followJoints)
{	
	PxCollection* curCollection = PxCreateCollection();
	PX_ASSERT(curCollection);	
	curCollection->add(collection);

	PxCollection* requiresCollection = PxCreateCollection();
	PX_ASSERT(requiresCollection);

	do
	{		
		getRequiresCollection(*requiresCollection, *curCollection, collection, exceptFor, sr, followJoints);		
		
		collection.add(*requiresCollection);
		PxCollection* swap = curCollection;	
		curCollection = requiresCollection;
		requiresCollection = swap;
		(static_cast<Cm::Collection*>(requiresCollection))->mObjects.clear();

	}while(curCollection->getNbObjects() > 0);

	requiresCollection->release();
	curCollection->release();
	
}
开发者ID:flair2005,项目名称:Spacetime-Optimization-of-Articulated-Character-Motion,代码行数:25,代码来源:SnSerialization.cpp

示例2: remove

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]);
}
开发者ID:savant-nz,项目名称:carbon,代码行数:19,代码来源:ExtCollection.cpp

示例3: createSerialObjectIds

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++;
		}
	}
}
开发者ID:Eorgregix,项目名称:Destruction,代码行数:20,代码来源:SnSerialization.cpp

示例4: assert

	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();
	}
开发者ID:franaisa,项目名称:Gloom,代码行数:44,代码来源:Entity.cpp

示例5: PxCreateCollection

PxCollection* PxCollectionExt::createCollection(PxPhysics& physics)
{
	PxCollection* collection = PxCreateCollection();
	if (!collection)
		return NULL;

	// Collect convexes
	{
		shdfnd::Array<PxConvexMesh*> objects(physics.getNbConvexMeshes());
		const PxU32 nb = physics.getConvexMeshes(objects.begin(), objects.size());
		PX_ASSERT(nb == objects.size());
		PX_UNUSED(nb);

		for(PxU32 i=0;i<objects.size();i++)
			collection->add(*objects[i]);
	}

	// Collect triangle meshes
	{
		shdfnd::Array<PxTriangleMesh*> objects(physics.getNbTriangleMeshes());
		const PxU32 nb = physics.getTriangleMeshes(objects.begin(), objects.size());

		PX_ASSERT(nb == objects.size());
		PX_UNUSED(nb);

		for(PxU32 i=0;i<objects.size();i++)
			collection->add(*objects[i]);
	}

	// Collect heightfields
	{
		shdfnd::Array<PxHeightField*> objects(physics.getNbHeightFields());
		const PxU32 nb = physics.getHeightFields(objects.begin(), objects.size());

		PX_ASSERT(nb == objects.size());
		PX_UNUSED(nb);

		for(PxU32 i=0;i<objects.size();i++)
			collection->add(*objects[i]);
	}

	// Collect materials
	{
		shdfnd::Array<PxMaterial*> objects(physics.getNbMaterials());
		const PxU32 nb = physics.getMaterials(objects.begin(), objects.size());

		PX_ASSERT(nb == objects.size());
		PX_UNUSED(nb);

		for(PxU32 i=0;i<objects.size();i++)
			collection->add(*objects[i]);
	}

#if PX_USE_CLOTH_API
	// Collect cloth fabrics
	{
		shdfnd::Array<PxClothFabric*> objects(physics.getNbClothFabrics());
		const PxU32 nb = physics.getClothFabrics(objects.begin(), objects.size());

		PX_ASSERT(nb == objects.size());
		PX_UNUSED(nb);

		for(PxU32 i=0;i<objects.size();i++)
			collection->add(*objects[i]);
	}
#endif

	// Collect shapes
	{
		shdfnd::Array<PxShape*> objects(physics.getNbShapes());
		const PxU32 nb = physics.getShapes(objects.begin(), objects.size());

		PX_ASSERT(nb == objects.size());
		PX_UNUSED(nb);

		for(PxU32 i=0;i<objects.size();i++)
			collection->add(*objects[i]);
	}
	return collection;
}
开发者ID:savant-nz,项目名称:carbon,代码行数:80,代码来源:ExtCollection.cpp

示例6: operator

void FPhysxSharedData::DumpSharedMemoryUsage(FOutputDevice* Ar)
{
	struct FSharedResourceEntry
	{
		uint64 MemorySize;
		uint64 Count;
	};

	struct FSortBySize
	{
		FORCEINLINE bool operator()( const FSharedResourceEntry& A, const FSharedResourceEntry& B ) const 
		{ 
			// Sort descending
			return B.MemorySize < A.MemorySize;
		}
	};

	TMap<FString, FSharedResourceEntry> AllocationsByType;

	uint64 OverallSize = 0;
	int32 OverallCount = 0;

	TMap<FString, TArray<PxBase*> > ObjectsByType;

	for (int32 i=0; i < (int32)SharedObjects->getNbObjects(); ++i)
	{
		PxBase& Obj = SharedObjects->getObject(i);
		FString TypeName = ANSI_TO_TCHAR(Obj.getConcreteTypeName());

		TArray<PxBase*>* ObjectsArray = ObjectsByType.Find(TypeName);
		if (ObjectsArray == NULL)
		{
			ObjectsByType.Add(TypeName, TArray<PxBase*>());
			ObjectsArray = ObjectsByType.Find(TypeName);
		}

		check(ObjectsArray);
		ObjectsArray->Add(&Obj);
	}

	TArray<FString> TypeNames;
	ObjectsByType.GetKeys(TypeNames);

	for (int32 TypeIdx=0; TypeIdx < TypeNames.Num(); ++TypeIdx)
	{
		const FString& TypeName = TypeNames[TypeIdx];
		
		TArray<PxBase*>* ObjectsArray = ObjectsByType.Find(TypeName);
		check(ObjectsArray);

		PxSerializationRegistry* Sr = PxSerialization::createSerializationRegistry(*GPhysXSDK);
		PxCollection* Collection = PxCreateCollection();
		
		for (int32 i=0; i < ObjectsArray->Num(); ++i)
		{
			Collection->add(*((*ObjectsArray)[i]));;
		}

		PxSerialization::complete(*Collection, *Sr);	// chase all other stuff (shared shaps, materials, etc) needed to serialize this collection

		FPhysXCountMemoryStream Out;
		PxSerialization::serializeCollectionToBinary(Out, *Collection, *Sr);

		Collection->release();
		Sr->release();

		OverallSize += Out.UsedMemory;
		OverallCount += ObjectsArray->Num();

		FSharedResourceEntry NewEntry;
		NewEntry.Count = ObjectsArray->Num();
		NewEntry.MemorySize = Out.UsedMemory;

		AllocationsByType.Add(TypeName, NewEntry);
	}

	Ar->Logf(TEXT(""));
	Ar->Logf(TEXT("Shared Resources:"));
	Ar->Logf(TEXT(""));

	AllocationsByType.ValueSort(FSortBySize());
	
	Ar->Logf(TEXT("%-10d %s (%d)"), OverallSize, TEXT("Overall"), OverallCount );
	
	for( auto It=AllocationsByType.CreateConstIterator(); It; ++It )
	{
		Ar->Logf(TEXT("%-10d %s (%d)"), It.Value().MemorySize, *It.Key(), It.Value().Count );
	}
}
开发者ID:zhaoyizheng0930,项目名称:UnrealEngine,代码行数:89,代码来源:PhysXSupport.cpp

示例7: fs

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;
}
开发者ID:Mateuus,项目名称:newsrcundead,代码行数:80,代码来源:PhysXWorld.cpp

示例8: QUICK_SCOPE_CYCLE_COUNTER

void UPhysicsSerializer::CreatePhysicsData(const TArray<UBodySetup*>& BodySetups, const TArray<UPhysicalMaterial*>& PhysicalMaterials)
{
	if (!FParse::Param(FCommandLine::Get(), TEXT("PhysxSerialization")))
	{
		return;
	}

#if PLATFORM_MAC
	return;	//This is not supported right now
#endif

#if !WITH_EDITOR
	QUICK_SCOPE_CYCLE_COUNTER(STAT_PhysicsSerializer_CreatePhysicsData);

	const FName Format(FPlatformProperties::GetPhysicsFormat());
	if(BinaryFormatData.Contains(Format))
	{
		FByteBulkData& BinaryData = BinaryFormatData.GetFormat(Format);
#if WITH_PHYSX
		// Read serialized physics data
		uint8* SerializedData = (uint8*)BinaryData.Lock(LOCK_READ_ONLY);

		FBufferReader Ar(SerializedData, BinaryData.GetBulkDataSize(), false );
		uint8 bIsLittleEndian;
		uint64 BaseId;	//the starting index of the shared resources we didn't serialize out
		Ar << bIsLittleEndian;
		Ar.SetByteSwapping( PLATFORM_LITTLE_ENDIAN ? !bIsLittleEndian : !!bIsLittleEndian );
		Ar << BaseId;
		//Note that PhysX expects the binary data to be 128-byte aligned. Because of this we've padded so find the next spot in memory
		int32 BytesToPad = PHYSX_SERIALIZATION_ALIGNMENT - (Ar.Tell() % PHYSX_SERIALIZATION_ALIGNMENT);
		
		physx::PxSerializationRegistry* PRegistry =  PxSerialization::createSerializationRegistry(*GPhysXSDK);
		physx::PxCollection* PCollection = nullptr;
		PxCollection* PExternalData = MakePhysXCollection(PhysicalMaterials, BodySetups, BaseId);		
		{
			QUICK_SCOPE_CYCLE_COUNTER(STAT_DeserializePhysics);
			PCollection = PxSerialization::createCollectionFromBinary(SerializedData + Ar.Tell() + BytesToPad, *PRegistry, PExternalData);	
		}

		{
			QUICK_SCOPE_CYCLE_COUNTER(STAT_AddBodiesToMap);
			const uint32 NumObjects = PCollection->getNbObjects();
			for (uint32 ObjectIdx = 0; ObjectIdx < NumObjects; ++ObjectIdx)
			{
				PxBase& PObject = PCollection->getObject(ObjectIdx);
				if (PxRigidActor* PRigidActor = PObject.is<PxRigidActor>())
				{
					const PxSerialObjectId ObjectId = PCollection->getId(PObject);
					ActorsMap.Add(ObjectId, PRigidActor);
				}
				else if (PxShape* PShape = PObject.is<PxShape>())
				{
					PShape->release();	//we do not need to hold on to this reference because our actors always have the reference directly
				}
			}
		}

		PExternalData->release();
		PCollection->release();
		PRegistry->release();
#endif
	}else
	{
#if !WITH_EDITOR
		UE_LOG(LogPhysics, Warning, TEXT("PhysicsSerializer has no binary data. Body instances will fall back to slow creation path."));
#endif
	}
#endif
}
开发者ID:amyvmiwei,项目名称:UnrealEngine4,代码行数:69,代码来源:PhysicsSerializer.cpp

示例9: PxCreateCollection

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 "
//.........这里部分代码省略.........
开发者ID:Eorgregix,项目名称:Destruction,代码行数:101,代码来源:SnSerialization.cpp

示例10: SerializeActors

	virtual bool SerializeActors(FName Format, const TArray<FBodyInstance*>& Bodies, const TArray<UBodySetup*>& BodySetups, const TArray<UPhysicalMaterial*>& PhysicalMaterials, TArray<uint8>& OutBuffer) const override
	{
#if WITH_PHYSX
		PxSerializationRegistry* PRegistry = PxSerialization::createSerializationRegistry(*GPhysXSDK);
		PxCollection* PCollection = PxCreateCollection();

		PxBase* PLastObject = nullptr;

		for(FBodyInstance* BodyInstance : Bodies)
		{
			if(BodyInstance->RigidActorSync)
			{
				PCollection->add(*BodyInstance->RigidActorSync, BodyInstance->RigidActorSyncId);
				PLastObject = BodyInstance->RigidActorSync;
			}

			if(BodyInstance->RigidActorAsync)
			{
				PCollection->add(*BodyInstance->RigidActorAsync,  BodyInstance->RigidActorAsyncId);
				PLastObject = BodyInstance->RigidActorAsync;
			}
		}

		PxSerialization::createSerialObjectIds(*PCollection, PxSerialObjectId(1));	//we get physx to assign an id for each actor

		//Note that rigid bodies may have assigned ids. It's important to let them go first because we rely on that id for deserialization.
		//One this is done we must find out the next available ID, and use that for naming the shared resources. We have to save this for deserialization
		uint64 BaseId = PLastObject ? (PCollection->getId(*PLastObject) + 1) : 1;

		PxCollection* PExceptFor = MakePhysXCollection(PhysicalMaterials, BodySetups, BaseId);
		
		for (FBodyInstance* BodyInstance : Bodies)	//and then we mark that id back into the bodyinstance so we can pair the two later
		{
			if (BodyInstance->RigidActorSync)
			{
				BodyInstance->RigidActorSyncId = PCollection->getId(*BodyInstance->RigidActorSync);
			}

			if (BodyInstance->RigidActorAsync)
			{
				BodyInstance->RigidActorAsyncId = PCollection->getId(*BodyInstance->RigidActorAsync);
			}
		}

		//We must store the BaseId for shared resources.
		FMemoryWriter Ar(OutBuffer);
		uint8 bIsLittleEndian = PLATFORM_LITTLE_ENDIAN; //TODO: We should pass the target platform into this function and write it. Then swap the endian on the writer so the reader doesn't have to do it at runtime
		Ar << bIsLittleEndian;
		Ar << BaseId;
		//Note that PhysX expects the binary data to be 128-byte aligned. Because of this we must pad
		int32 BytesToPad = PHYSX_SERIALIZATION_ALIGNMENT - (Ar.Tell() % PHYSX_SERIALIZATION_ALIGNMENT);
		OutBuffer.AddZeroed(BytesToPad);

		FPhysXOutputStream Buffer(&OutBuffer);
		PxSerialization::complete(*PCollection, *PRegistry, PExceptFor);
		PxSerialization::serializeCollectionToBinary(Buffer, *PCollection, *PRegistry, PExceptFor);

#if PHYSX_MEMORY_VALIDATION
		GPhysXAllocator->ValidateHeaders();
#endif
		PCollection->release();
		PExceptFor->release();
		PRegistry->release();

#if PHYSX_MEMORY_VALIDATION
		GPhysXAllocator->ValidateHeaders();
#endif
		return true;
#endif
		return false;
	}
开发者ID:RandomDeveloperM,项目名称:UE4_Hairworks,代码行数:71,代码来源:PhysXFormats.cpp


注:本文中的PxCollection类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。