void FPhysScene::UpdateActiveTransforms(uint32 SceneType) { if (SceneType == PST_Cloth) //cloth doesn't bother with updating components to bodies so we don't need to store any transforms { return; } PxScene* PScene = GetPhysXScene(SceneType); check(PScene); SCOPED_SCENE_READ_LOCK(PScene); PxU32 NumTransforms = 0; const PxActiveTransform* PActiveTransforms = PScene->getActiveTransforms(NumTransforms); ActiveBodyInstances[SceneType].Empty(NumTransforms); ActiveDestructibleActors[SceneType].Empty(NumTransforms); for (PxU32 TransformIdx = 0; TransformIdx < NumTransforms; ++TransformIdx) { const PxActiveTransform& PActiveTransform = PActiveTransforms[TransformIdx]; PxRigidActor* RigidActor = PActiveTransform.actor->isRigidActor(); ensure(!RigidActor->userData || !FPhysxUserData::IsGarbage(RigidActor->userData)); if (FBodyInstance* BodyInstance = FPhysxUserData::Get<FBodyInstance>(RigidActor->userData)) { if (BodyInstance->InstanceBodyIndex == INDEX_NONE && BodyInstance->OwnerComponent.IsValid() && BodyInstance->IsInstanceSimulatingPhysics()) { ActiveBodyInstances[SceneType].Add(BodyInstance); } } else if (const FDestructibleChunkInfo* DestructibleChunkInfo = FPhysxUserData::Get<FDestructibleChunkInfo>(RigidActor->userData)) { ActiveDestructibleActors[SceneType].Add(RigidActor); } } }
void FPhysScene::SyncComponentsToBodies(uint32 SceneType) { #if WITH_PHYSX PxScene* PScene = GetPhysXScene(SceneType); check(PScene); SCENE_LOCK_READ(PScene); PxU32 NumTransforms = 0; const PxActiveTransform* PActiveTransforms = PScene->getActiveTransforms(NumTransforms); SCENE_UNLOCK_READ(PScene); for(PxU32 TransformIdx=0; TransformIdx<NumTransforms; TransformIdx++) { const PxActiveTransform& PActiveTransform = PActiveTransforms[TransformIdx]; FBodyInstance* BodyInst = FPhysxUserData::Get<FBodyInstance>(PActiveTransform.userData); if( BodyInst != NULL && BodyInst->InstanceBodyIndex == INDEX_NONE && BodyInst->OwnerComponent != NULL && BodyInst->IsInstanceSimulatingPhysics() ) { check(BodyInst->OwnerComponent->IsRegistered()); // shouldn't have a physics body for a non-registered component! AActor* Owner = BodyInst->OwnerComponent->GetOwner(); // See if the transform is actually different, and if so, move the component to match physics const FTransform NewTransform = BodyInst->GetUnrealWorldTransform(); if(!NewTransform.EqualsNoScale(BodyInst->OwnerComponent->ComponentToWorld)) { const FVector MoveBy = NewTransform.GetLocation() - BodyInst->OwnerComponent->ComponentToWorld.GetLocation(); const FRotator NewRotation = NewTransform.Rotator(); //UE_LOG(LogTemp, Log, TEXT("MOVING: %s"), *BodyInst->OwnerComponent->GetPathName()); //@warning: do not reference BodyInstance again after calling MoveComponent() - events from the move could have made it unusable (destroying the actor, SetPhysics(), etc) BodyInst->OwnerComponent->MoveComponent(MoveBy, NewRotation, false, NULL, MOVECOMP_SkipPhysicsMove); } // Check if we didn't fall out of the world if(Owner != NULL && !Owner->IsPendingKill()) { Owner->CheckStillInWorld(); } } } #endif }