void FPhysScene::SetUpForFrame(const FVector* NewGrav, float InDeltaSeconds, float InMaxPhysicsDeltaTime) { DeltaSeconds = InDeltaSeconds; MaxPhysicsDeltaTime = InMaxPhysicsDeltaTime; #if WITH_PHYSX if (NewGrav) { // Loop through scene types to get all scenes for (uint32 SceneType = 0; SceneType < NumPhysScenes; ++SceneType) { PxScene* PScene = GetPhysXScene(SceneType); if (PScene != NULL) { //@todo phys_thread don't do this if gravity changes //@todo, to me it looks like we should avoid this if the gravity has not changed, the lock is probably expensive // Lock scene lock, in case it is required SCENE_LOCK_WRITE(PScene); PScene->setGravity(U2PVector(*NewGrav)); // Unlock scene lock, in case it is required SCENE_UNLOCK_WRITE(PScene); } } } #endif }
void FPhysSubstepTask::SubstepInterpolation(float InAlpha) { #if WITH_PHYSX #if WITH_APEX PxScene * PScene = PAScene->getPhysXScene(); #else PxScene * PScene = PAScene; #endif PhysTargetMap & Targets = PhysTargetBuffers[!External]; /** Note: We lock the entire scene before iterating. The assumption is that removing an FBodyInstance from the map will also be wrapped by this lock */ SCENE_LOCK_WRITE(PScene); for (PhysTargetMap::TIterator Itr = Targets.CreateIterator(); Itr; ++Itr) { FPhysTarget & PhysTarget = Itr.Value(); FBodyInstance* BodyInstance = Itr.Key(); PxRigidDynamic * PRigidDynamic = BodyInstance->GetPxRigidDynamic(); if (PRigidDynamic == NULL) { continue; } //We should only be iterating over actors that belong to this scene check(PRigidDynamic->getScene() == PScene); ApplyForces(PhysTarget, BodyInstance); ApplyTorques(PhysTarget, BodyInstance); InterpolateKinematicActor(PhysTarget, BodyInstance, InAlpha); } /** Final substep */ if (InAlpha >= 1.f) { Targets.Empty(Targets.Num()); } SCENE_UNLOCK_WRITE(PScene); #endif }
void FPhysScene::ApplyWorldOffset(FVector InOffset) { #if WITH_PHYSX // Loop through scene types to get all scenes for (uint32 SceneType = 0; SceneType < NumPhysScenes; ++SceneType) { PxScene* PScene = GetPhysXScene(SceneType); if (PScene != NULL) { // Lock scene lock, in case it is required SCENE_LOCK_WRITE(PScene); PScene->shiftOrigin(U2PVector(-InOffset)); // Unlock scene lock, in case it is required SCENE_UNLOCK_WRITE(PScene); } } #endif }
void FPhysScene::SetIsStaticLoading(bool bStaticLoading) { #if WITH_PHYSX // Loop through scene types to get all scenes for (uint32 SceneType = 0; SceneType < NumPhysScenes; ++SceneType) { PxScene* PScene = GetPhysXScene(SceneType); if (PScene != NULL) { // Lock scene lock, in case it is required SCENE_LOCK_WRITE(PScene); // Sets the rebuild rate hint, to 1 frame if static loading PScene->setDynamicTreeRebuildRateHint(bStaticLoading ? 5 : PhysXSlowRebuildRate); // Unlock scene lock, in case it is required SCENE_UNLOCK_WRITE(PScene); } } #endif }
void FPhysScene::InitPhysScene(uint32 SceneType) { check(SceneType < NumPhysScenes); #if WITH_PHYSX PhysxUserData = FPhysxUserData(this); // Include scene descriptor in loop, so that we might vary it with scene type PxSceneDesc PSceneDesc(GPhysXSDK->getTolerancesScale()); PSceneDesc.cpuDispatcher = CPUDispatcher; FPhysSceneShaderInfo PhysSceneShaderInfo; PhysSceneShaderInfo.PhysScene = this; PSceneDesc.filterShaderData = &PhysSceneShaderInfo; PSceneDesc.filterShaderDataSize = sizeof(PhysSceneShaderInfo); PSceneDesc.filterShader = PhysXSimFilterShader; PSceneDesc.simulationEventCallback = SimEventCallback; if(UPhysicsSettings::Get()->bEnablePCM) { PSceneDesc.flags |= PxSceneFlag::eENABLE_PCM; } //LOC_MOD enable kinematic vs kinematic for APEX destructibles. This is for the kinematic cube moving horizontally in QA-Destructible map to collide with the destructible. // Was this flag turned off in UE4? Do we want to turn it on for both sync and async scenes? PSceneDesc.flags |= PxSceneFlag::eENABLE_KINEMATIC_PAIRS; // Set bounce threshold PSceneDesc.bounceThresholdVelocity = UPhysicsSettings::Get()->BounceThresholdVelocity; // Possibly set flags in async scene for better behavior with piles #if USE_ADAPTIVE_FORCES_FOR_ASYNC_SCENE if (SceneType == PST_Async) { PSceneDesc.flags |= PxSceneFlag::eADAPTIVE_FORCE; } #endif #if USE_SPECIAL_FRICTION_MODEL_FOR_ASYNC_SCENE if (SceneType == PST_Async) { PSceneDesc.flags |= PxSceneFlag::eENABLE_ONE_DIRECTIONAL_FRICTION; } #endif // If we're frame lagging the async scene (truly running it async) then use the scene lock #if USE_SCENE_LOCK if(UPhysicsSettings::Get()->bWarnMissingLocks) { PSceneDesc.flags |= PxSceneFlag::eREQUIRE_RW_LOCK; } #endif // We want to use 'active transforms' PSceneDesc.flags |= PxSceneFlag::eENABLE_ACTIVETRANSFORMS; // @TODO Should we set up PSceneDesc.limits? How? // Do this to improve loading times, esp. for streaming in sublevels PSceneDesc.staticStructure = PxPruningStructure::eDYNAMIC_AABB_TREE; // Default to rebuilding tree slowly PSceneDesc.dynamicTreeRebuildRateHint = PhysXSlowRebuildRate; bool bIsValid = PSceneDesc.isValid(); if (!bIsValid) { UE_LOG(LogPhysics, Log, TEXT("Invalid PSceneDesc")); } // Create scene, and add to map PxScene* PScene = GPhysXSDK->createScene(PSceneDesc); #if WITH_APEX // Build the APEX scene descriptor for the PhysX scene NxApexSceneDesc ApexSceneDesc; ApexSceneDesc.scene = PScene; // This interface allows us to modify the PhysX simulation filter shader data with contact pair flags ApexSceneDesc.physX3Interface = &GApexPhysX3Interface; // Create the APEX scene from our descriptor NxApexScene* ApexScene = GApexSDK->createScene(ApexSceneDesc); // This enables debug rendering using the "legacy" method, not using the APEX render API ApexScene->setUseDebugRenderable(true); // Allocate a view matrix for APEX scene LOD ApexScene->allocViewMatrix(physx::ViewMatrixType::LOOK_AT_RH); // Add the APEX scene to the map instead of the PhysX scene, since we can access the latter through the former GPhysXSceneMap.Add(PhysXSceneCount, ApexScene); #else // #if WITH_APEX GPhysXSceneMap.Add(PhysXSceneCount, PScene); #endif // #if WITH_APEX // Lock scene lock, in case it is required SCENE_LOCK_WRITE(PScene); // enable CCD at scene level if (bGlobalCCD) { PScene->setFlag(PxSceneFlag::eENABLE_CCD, true); } // Need to turn this on to consider kinematics turning into dynamic. Otherwise, you'll need to call resetFiltering to do the expensive broadphase reinserting PScene->setFlag(PxSceneFlag::eENABLE_KINEMATIC_STATIC_PAIRS, true); // Unlock scene lock, in case it is required SCENE_UNLOCK_WRITE(PScene); // Save pointer to FPhysScene in userdata PScene->userData = &PhysxUserData; #if WITH_APEX ApexScene->userData = &PhysxUserData; #endif // Store index of PhysX Scene in this FPhysScene this->PhysXSceneIndex[SceneType] = PhysXSceneCount; DeferredSceneData[SceneType].SceneIndex = PhysXSceneCount; // Increment scene count PhysXSceneCount++; #if WITH_VEHICLE // Only create PhysXVehicleManager in the sync scene if (SceneType == PST_Sync) { check(VehicleManager == NULL); VehicleManager = new FPhysXVehicleManager(PScene); } #endif #if WITH_SUBSTEPPING //Initialize substeppers //we don't bother sub-stepping cloth #if WITH_PHYSX #if WITH_APEX PhysSubSteppers[SceneType] = SceneType == PST_Cloth ? NULL : new FPhysSubstepTask(ApexScene); #else PhysSubSteppers[SceneType] = SceneType == PST_Cloth ? NULL : new FPhysSubstepTask(PScene); #endif #endif #if WITH_VEHICLE if (SceneType == PST_Sync) { PhysSubSteppers[SceneType]->SetVehicleManager(VehicleManager); } #endif #endif #endif // WITH_PHYSX }