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