コード例 #1
0
void UDestructibleComponent::SetCollisionResponseForAllActors(const FCollisionResponseContainer& ResponseOverride)
{
#if WITH_APEX
	if (ApexDestructibleActor == NULL)
	{
		return;
	}

	PxRigidDynamic** PActorBuffer = NULL;
	PxU32 PActorCount = 0;
	if (ApexDestructibleActor->acquirePhysXActorBuffer(PActorBuffer, PActorCount))
	{
		PxScene* LockedScene = NULL;

		while (PActorCount--)
		{
			PxRigidDynamic* PActor = *PActorBuffer++;
			if (PActor != NULL)
			{
				FDestructibleChunkInfo* ChunkInfo = FPhysxUserData::Get<FDestructibleChunkInfo>(PActor->userData);
				if (ChunkInfo != NULL)
				{
					if (!LockedScene)
					{
						LockedScene = PActor->getScene();
						LockedScene->lockWrite();
						LockedScene->lockRead();
					}
					SetCollisionResponseForActor(PActor, ChunkInfo->ChunkIndex, &ResponseOverride);	// ChunkIndex is the last chunk made visible.  But SetCollisionResponseForActor already doesn't respect per-chunk collision properties.
				}
			}
		}

		if (LockedScene)
		{
			LockedScene->unlockRead();
			LockedScene->unlockWrite();
			LockedScene = NULL;
		}

		ApexDestructibleActor->releasePhysXActorBuffer();
	}
#endif
}
コード例 #2
0
void UDestructibleComponent::SetChunkVisible( int32 ChunkIndex, bool bVisible )
{
	// Bone 0 is a dummy root bone
	const int32 BoneIndex = ChunkIdxToBoneIdx(ChunkIndex);
	bool bClearActorFromChunkInfo = false;

	if( bVisible )
	{
		UnHideBone(BoneIndex);
#if WITH_APEX
		PxRigidDynamic* PActor = ApexDestructibleActor != NULL ? ApexDestructibleActor->getChunkPhysXActor(ChunkIndex) : NULL;

		UDestructibleMesh* DMesh = GetDestructibleMesh();

		if (PActor != NULL)
		{
			// If actor has already a chunk info and userdata, we just make sure it is valid and update the 
			// physx actor if needed. We do NOT do this for FormExtended structures, as in this case, the shapes/actors
			// are moved to the 1st structure object internally by APEX.
			if(PActor->userData != NULL && !DMesh->DefaultDestructibleParameters.Flags.bFormExtendedStructures)
			{
				FDestructibleChunkInfo* CI = FPhysxUserData::Get<FDestructibleChunkInfo>(PActor->userData);
				checkf(CI, TEXT("If a chunk actor has user data and it is not a DestructibleChunkInfo, something is messed up."));
				//check(CI->OwningComponent == this);

				if (CI->ChunkIndex != ChunkIndex)
				{
					// grab the old actor and clear its user data, as we steal the ChunkInfo here
					if (CI->Actor && CI->Actor != PActor)
					{
						CI->Actor->userData = NULL;
					}
					CI->ChunkIndex = ChunkIndex;
				}

				CI->OwningComponent = this;
				CI->Actor = PActor;
			}
			else if (PActor->userData == NULL)
			{
				// Setup the user data to have a proper chunk - actor mapping 
				int32 InfoIndex = ChunkInfos.AddUninitialized();

				FDestructibleChunkInfo* CI = &ChunkInfos[InfoIndex];
				CI->Index = InfoIndex;
				CI->ChunkIndex = ChunkIndex;
				CI->OwningComponent = this;
				CI->Actor = PActor;

				int32 UserDataIdx = PhysxChunkUserData.Add(FPhysxUserData(CI));
				check(InfoIndex == UserDataIdx);

				PActor->userData = &PhysxChunkUserData[UserDataIdx];

				// Set collision response to non-root chunks
				if (GetDestructibleMesh()->ApexDestructibleAsset->getChunkParentIndex(ChunkIndex) >= 0)
				{
					SetCollisionResponseForActor(ChunkCollisionResponse, PActor, ChunkIndex);
				}
			}
		}
		else
		{
			bClearActorFromChunkInfo = true;
		}
#endif // WITH_APEX
	}
	else
	{
		HideBone(BoneIndex, PBO_None);
		bClearActorFromChunkInfo = true;
	}

#if WITH_APEX
	if (bClearActorFromChunkInfo)
	{
		// Make sure we clear the physx actor pointer of the chunk info as it might (and probably will) be
		// invalid from now on
		for (int32 i=0; i < ChunkInfos.Num(); ++i)
		{
			if (ChunkInfos[i].ChunkIndex == ChunkIndex)
			{
				ChunkInfos[i].Actor = NULL;
				break;
			}
		}
	}
#endif // WITH_APEX

	// Mark the transform as dirty, so the bounds are updated and sent to the render thread
	MarkRenderTransformDirty();

	// New bone positions need to be sent to render thread
	MarkRenderDynamicDataDirty();
}