示例#1
0
void UDestructibleComponent::SetChunkVisible( int32 ChunkIndex, bool bVisible )
{
#if WITH_APEX
	// Bone 0 is a dummy root bone
	const int32 BoneIndex = ChunkIdxToBoneIdx(ChunkIndex);

	if( bVisible )
	{
		UnHideBone(BoneIndex);

		if (NULL != ApexDestructibleActor)
		{
			physx::PxShape** PShapes;
			const physx::PxU32 PShapeCount = ApexDestructibleActor->getChunkPhysXShapes(PShapes, ChunkIndex);
			if (PShapeCount > 0)
			{
				const physx::PxMat44 ChunkPoseRT = ApexDestructibleActor->getChunkPose(ChunkIndex);	// Unscaled
				const physx::PxTransform Transform(ChunkPoseRT);
				SetChunkWorldRT(ChunkIndex, P2UQuat(Transform.q), P2UVector(Transform.p));
			}
		}
	}
	else
	{
		HideBone(BoneIndex, PBO_None);
	}

	// 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();
#endif
}
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();
}