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 }
void UPrimitiveComponent::SyncComponentToRBPhysics() { if(!IsRegistered()) { UE_LOG(LogPhysics, Log, TEXT("SyncComponentToRBPhysics : Component not registered (%s)"), *GetPathName()); return; } // BodyInstance we are going to sync the component to FBodyInstance* UseBI = GetBodyInstance(); if(UseBI == NULL || !UseBI->IsValidBodyInstance()) { UE_LOG(LogPhysics, Log, TEXT("SyncComponentToRBPhysics : Missing or invalid BodyInstance (%s)"), *GetPathName()); return; } AActor* Owner = GetOwner(); if(Owner != NULL) { if (Owner->IsPendingKill() || !Owner->CheckStillInWorld()) { return; } } if (IsPendingKill() || !IsSimulatingPhysics()) { return; } // See if the transform is actually different, and if so, move the component to match physics const FTransform NewTransform = GetComponentTransformFromBodyInstance(UseBI); if(!NewTransform.EqualsNoScale(ComponentToWorld)) { const FVector MoveBy = NewTransform.GetLocation() - ComponentToWorld.GetLocation(); const FQuat NewRotation = NewTransform.GetRotation(); //@warning: do not reference BodyInstance again after calling MoveComponent() - events from the move could have made it unusable (destroying the actor, SetPhysics(), etc) MoveComponent(MoveBy, NewRotation, false, NULL, MOVECOMP_SkipPhysicsMove); } }
void FPhysScene::SyncComponentsToBodies(uint32 SceneType) { SCOPE_CYCLE_COUNTER(STAT_TotalPhysicsTime); SCOPE_CYCLE_COUNTER(STAT_SyncComponentsToBodies); for (FBodyInstance* BodyInstance : ActiveBodyInstances[SceneType]) { if (BodyInstance == nullptr) { continue; } check(BodyInstance->OwnerComponent->IsRegistered()); // shouldn't have a physics body for a non-registered component! AActor* Owner = BodyInstance->OwnerComponent->GetOwner(); // See if the transform is actually different, and if so, move the component to match physics const FTransform NewTransform = BodyInstance->GetUnrealWorldTransform(); if (!NewTransform.EqualsNoScale(BodyInstance->OwnerComponent->ComponentToWorld)) { const FVector MoveBy = NewTransform.GetLocation() - BodyInstance->OwnerComponent->ComponentToWorld.GetLocation(); const FRotator NewRotation = NewTransform.Rotator(); //@warning: do not reference BodyInstance again after calling MoveComponent() - events from the move could have made it unusable (destroying the actor, SetPhysics(), etc) BodyInstance->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(); } } #if WITH_APEX if (ActiveDestructibleActors[SceneType].Num()) { SCOPED_SCENE_READ_LOCK(GetPhysXScene(SceneType)); UDestructibleComponent::UpdateDestructibleChunkTM(ActiveDestructibleActors[SceneType]); } #endif }