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
}
FTransform P2UTransform(const PxTransform& PTM)
{
	FQuat UQuat = P2UQuat(PTM.q);
	FVector UPos = P2UVector(PTM.p);

	FTransform Result = FTransform(UQuat, UPos);

	return Result;
}
FMatrix PTransform2UMatrix(const PxTransform& PTM)
{
	FQuat UQuat = P2UQuat(PTM.q);
	FVector UPos = P2UVector(PTM.p);

	FMatrix Result = FQuatRotationTranslationMatrix(UQuat, UPos);

	return Result;
}
void UDestructibleComponent::RefreshBoneTransforms()
{
#if WITH_APEX
	if(ApexDestructibleActor != NULL && SkeletalMesh)
	{
		UDestructibleMesh* TheDestructibleMesh = GetDestructibleMesh();

		// Save a pointer to the APEX NxDestructibleAsset
		physx::NxDestructibleAsset* ApexDestructibleAsset = TheDestructibleMesh->ApexDestructibleAsset;
		check(ApexDestructibleAsset);

		{
			// Lock here so we don't encounter race conditions with the destruction processing
			FPhysScene* PhysScene = World->GetPhysicsScene();
			check(PhysScene);
			const uint32 SceneType = (BodyInstance.bUseAsyncScene && PhysScene->HasAsyncScene()) ? PST_Async : PST_Sync;
			PxScene* PScene = PhysScene->GetPhysXScene(SceneType);
			check(PScene);
			SCOPED_SCENE_WRITE_LOCK(PScene);
			SCOPED_SCENE_READ_LOCK(PScene);

			// Try to acquire event buffer
			const physx::NxDestructibleChunkEvent* EventBuffer;
			physx::PxU32 EventBufferSize;
			if (ApexDestructibleActor->acquireChunkEventBuffer(EventBuffer, EventBufferSize))
			{
				// Buffer acquired
				while (EventBufferSize--)
				{
					const physx::NxDestructibleChunkEvent& Event = *EventBuffer++;
					// Right now the only events are visibility changes.  So as an optimization we won't check for the event type.
	//				if (Event.event & physx::NxDestructibleChunkEvent::VisibilityChanged)
					const bool bVisible = (Event.event & physx::NxDestructibleChunkEvent::ChunkVisible) != 0;
					SetChunkVisible(Event.chunkIndex, bVisible);
				}
				// Release buffer (will be cleared)
				ApexDestructibleActor->releaseChunkEventBuffer();
			}
		}

		// Update poses for visible chunks
		const physx::PxU16* VisibleChunks = ApexDestructibleActor->getVisibleChunks();
		physx::PxU16 VisibleChunkCount = ApexDestructibleActor->getNumVisibleChunks();
		while (VisibleChunkCount--)
		{
			const physx::PxU16 ChunkIndex = *VisibleChunks++;
			// BRGTODO : Make a direct method to access the Px objects' quats
			const physx::PxMat44 ChunkPoseRT = ApexDestructibleActor->getChunkPose(ChunkIndex);	// Unscaled
			const physx::PxTransform Transform(ChunkPoseRT);
			SetChunkWorldRT(ChunkIndex, P2UQuat(Transform.q), P2UVector(Transform.p));
		}

		// Send bones to render thread at end of frame
		MarkRenderDynamicDataDirty();
}
#endif	// #if WITH_APEX
}