void ControlledActor::tryStandup() { // overlap with upper part if(mType==PxControllerShapeType::eBOX) { } else if(mType==PxControllerShapeType::eCAPSULE) { PxCapsuleController* capsuleCtrl = static_cast<PxCapsuleController*>(mController); PxReal r = capsuleCtrl->getRadius(); PxReal dh = mStandingSize - mCrouchingSize-2*r; PxCapsuleGeometry geom(r, dh*.5f); PxExtendedVec3 position = mController->getPosition(); PxVec3 pos((float)position.x,(float)position.y+mStandingSize*.5f+r,(float)position.z); PxQuat orientation(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f)); PxShape* hit; PxScene* scene = mController->getScene(); if(scene->overlapMultiple(geom, PxTransform(pos,orientation),&hit,1) != 0) return; } // if no hit, we can stand up resizeStanding(); mDoStandup = false; mIsCrouching = false; }
void ControlledActor::tryStandup() { // overlap with upper part if(mType==PxControllerShapeType::eBOX) { } else if(mType==PxControllerShapeType::eCAPSULE) { PxScene* scene = mController->getScene(); PxSceneReadLock scopedLock(*scene); PxCapsuleController* capsuleCtrl = static_cast<PxCapsuleController*>(mController); PxReal r = capsuleCtrl->getRadius(); PxReal dh = mStandingSize - mCrouchingSize-2*r; PxCapsuleGeometry geom(r, dh*.5f); PxExtendedVec3 position = mController->getPosition(); PxVec3 pos((float)position.x,(float)position.y+mStandingSize*.5f+r,(float)position.z); PxQuat orientation(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f)); PxOverlapBuffer hit; if(scene->overlap(geom, PxTransform(pos,orientation), hit, PxQueryFilterData(PxQueryFlag::eANY_HIT|PxQueryFlag::eSTATIC|PxQueryFlag::eDYNAMIC))) return; } // if no hit, we can stand up resizeStanding(); mDoStandup = false; mIsCrouching = false; }
PxU32 Cct::getSceneTimestamp(const InternalCBData_FindTouchedGeom* userData) { PX_ASSERT(userData); const PxInternalCBData_FindTouchedGeom* internalData = static_cast<const PxInternalCBData_FindTouchedGeom*>(userData); PxScene* scene = internalData->scene; return scene->getSceneQueryStaticTimestamp(); }
PxScene* createScene( const osg::Vec3& gravity, const PxSimulationFilterShader& filter, physx::PxSceneFlags flags, unsigned int numThreads, bool useGPU ) { PxSceneDesc sceneDesc( SDK_OBJ->getTolerancesScale() ); sceneDesc.gravity = PxVec3(gravity[0], gravity[1], gravity[2]); sceneDesc.filterShader = filter; sceneDesc.flags |= flags; #if USE_PHYSX_33 if ( useGPU ) { PxCudaContextManager* cudaManager = Engine::instance()->getOrCreateCudaContextManager(); if ( cudaManager ) sceneDesc.gpuDispatcher = cudaManager->getGpuDispatcher(); } #endif if ( !sceneDesc.gpuDispatcher && !sceneDesc.cpuDispatcher ) { PxDefaultCpuDispatcher* defCpuDispatcher = PxDefaultCpuDispatcherCreate(numThreads); if ( !defCpuDispatcher ) OSG_WARN << "Failed to create default Cpu dispatcher." << std::endl; sceneDesc.cpuDispatcher = defCpuDispatcher; } PxScene* scene = SDK_OBJ->createScene( sceneDesc ); if ( !scene ) { OSG_WARN << "Failed to create the physics world." << std::endl; return NULL; } scene->setVisualizationParameter( PxVisualizationParameter::eSCALE, 1.0f ); scene->setVisualizationParameter( PxVisualizationParameter::eCOLLISION_SHAPES, 1.0f ); return scene; }
bool FPhysScene::SubstepSimulation(uint32 SceneType, FGraphEventRef &InOutCompletionEvent) { #if WITH_PHYSX check(SceneType != PST_Cloth); //we don't bother sub-stepping cloth float UseDelta = UseSyncTime(SceneType)? SyncDeltaSeconds : DeltaSeconds; float SubTime = PhysSubSteppers[SceneType]->UpdateTime(UseDelta); PxScene* PScene = GetPhysXScene(SceneType); if(SubTime <= 0.f) { return false; }else { //we have valid scene and subtime so enqueue task PhysXCompletionTask* Task = new PhysXCompletionTask(InOutCompletionEvent, PScene->getTaskManager()); ENamedThreads::Type NamedThread = PhysSingleThreadedMode() ? ENamedThreads::GameThread : ENamedThreads::AnyThread; DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.SubstepSimulationImp"), STAT_FSimpleDelegateGraphTask_SubstepSimulationImp, STATGROUP_TaskGraphTasks); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateRaw(PhysSubSteppers[SceneType], &FPhysSubstepTask::StepSimulation, Task), GET_STATID(STAT_FSimpleDelegateGraphTask_SubstepSimulationImp), NULL, NamedThread ); return true; } #endif }
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::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 }
std::shared_ptr<Terrain> TerrainGenerator::generate() const { if (!levelForElement) levelForElement = initElementTerrainLevels(); std::shared_ptr<Terrain> terrain = std::make_shared<Terrain>(m_settings); assert(PxGetPhysics().getNbScenes() == 1); PxScene * pxScene; PxGetPhysics().getScenes(&pxScene, 1); // The tileID determines the position of the current tile in the grid of tiles. // Tiles get shifted by -(numTilesPerAxis + 1)/2 so that we have the Tile(0,0,0) in the origin. int maxxID = m_settings.tilesX - int((m_settings.tilesX + 1) * 0.5); int minxID = maxxID - m_settings.tilesX + 1; int maxzID = m_settings.tilesZ - int((m_settings.tilesZ + 1) * 0.5); int minzID = maxzID - m_settings.tilesZ + 1; terrain->minTileXID = minxID; terrain->minTileZID = minzID; for (int xID = minxID; xID <= maxxID; ++xID) for (int zID = minzID; zID <= maxzID; ++zID) { TileID tileIDBase(TerrainLevel::BaseLevel, xID, zID); std::initializer_list<std::string> baseElements = { "bedrock", "sand", "grassland" }; /** create terrain object and pass terrain data */ BaseTile * baseTile = new BaseTile(*terrain, tileIDBase, baseElements); // create the terrain using diamond square algorithm diamondSquare(*baseTile); // and apply the elements to the landscape applyElementsByHeight(*baseTile); /** same thing for the liquid level, just that we do not add a terrain type texture */ TileID tileIDLiquid(TerrainLevel::WaterLevel, xID, zID); LiquidTile * liquidTile = new LiquidTile(*terrain, tileIDLiquid); /** Create physx objects: an actor with its transformed shapes * move tile according to its id, and by one half tile size, so the center of Tile(0,0,0) is in the origin */ PxTransform pxTerrainTransform = PxTransform(PxVec3(m_settings.tileBorderLength() * (xID - 0.5f), 0.0f, m_settings.tileBorderLength() * (zID - 0.5f))); PxRigidStatic * actor = PxGetPhysics().createRigidStatic(pxTerrainTransform); terrain->m_pxActors.emplace(tileIDBase, actor); baseTile->createPxObjects(*actor); liquidTile->createPxObjects(*actor); pxScene->addActor(*actor); TileID temperatureID(TerrainLevel::TemperatureLevel, xID, zID); // the tile registers itself in the terrain new TemperatureTile(*terrain, temperatureID, *baseTile, *liquidTile); } return terrain; }
bool Engine::addActor( const std::string& s, PxActor* actor ) { PxScene* scene = getScene(s); if ( !scene || !actor ) return false; scene->addActor( *actor ); _actorMap[scene].push_back( actor ); return true; }
void Engine::update( double step ) { for ( SceneMap::iterator itr=_sceneMap.begin(); itr!=_sceneMap.end(); ++itr ) { PxScene* scene = itr->second; scene->simulate( step ); while( !scene->fetchResults() ) { /* do nothing but wait */ } } }
void FPhysScene::ProcessPhysScene(uint32 SceneType) { SCOPE_CYCLE_COUNTER(STAT_TotalPhysicsTime); SCOPE_CYCLE_COUNTER(STAT_PhysicsFetchDynamicsTime); check(SceneType < NumPhysScenes); if (bPhysXSceneExecuting[SceneType] == 0) { // Not executing this scene, must call TickPhysScene before calling this function again. UE_LOG(LogPhysics, Log, TEXT("WaitPhysScene`: Not executing this scene (%d) - aborting."), SceneType); return; } if (FrameLagAsync()) { static_assert(PST_MAX == 3, "Physics scene static test failed."); // Here we assume the PST_Sync is the master and never fame lagged if (SceneType == PST_Sync) { // the one frame lagged one should be done by now. check(!FrameLaggedPhysicsSubsceneCompletion[PST_Async].GetReference() || FrameLaggedPhysicsSubsceneCompletion[PST_Async]->IsComplete()); } else if (SceneType == PST_Async) { FrameLaggedPhysicsSubsceneCompletion[PST_Async] = NULL; } } // Reset execution flag //This fetches and gets active transforms. It's important that the function that calls this locks because getting the transforms and using the data must be an atomic operation #if WITH_PHYSX PxScene* PScene = GetPhysXScene(SceneType); check(PScene); PxU32 OutErrorCode = 0; #if !WITH_APEX PScene->lockWrite(); PScene->fetchResults(true, &OutErrorCode); PScene->unlockWrite(); #else // #if !WITH_APEX // The APEX scene calls the fetchResults function for the PhysX scene, so we only call ApexScene->fetchResults(). NxApexScene* ApexScene = GetApexScene(SceneType); check(ApexScene); ApexScene->fetchResults(true, &OutErrorCode); #endif // #if !WITH_APEX UpdateActiveTransforms(SceneType); if (OutErrorCode != 0) { UE_LOG(LogPhysics, Log, TEXT("PHYSX FETCHRESULTS ERROR: %d"), OutErrorCode); } #endif // WITH_PHYSX PhysicsSubsceneCompletion[SceneType] = NULL; bPhysXSceneExecuting[SceneType] = false; }
void Engine::clear() { for ( SceneMap::iterator itr=_sceneMap.begin(); itr!=_sceneMap.end(); ++itr ) { PxScene* scene = itr->second; releaseActors( scene ); scene->release(); } _sceneMap.clear(); _actorMap.clear(); }
uint32_t Physx::createScene( const PxSceneDesc& desc ) { CI_ASSERT( mPhysics != nullptr ); PxScene* scene = mPhysics->createScene( desc ); PxBroadPhaseRegion broadPhaseRegion; broadPhaseRegion.bounds = to( AxisAlignedBox( vec3( -100.0f ), vec3( 100.0f ) ) ); scene->addBroadPhaseRegion( broadPhaseRegion ); CI_ASSERT( scene != nullptr ); uint32_t id = mScenes.empty() ? 0 : mScenes.rbegin()->first + 1; mScenes[ id ] = scene; return id; }
void FPhysScene::ProcessPhysScene(uint32 SceneType) { SCOPE_CYCLE_COUNTER(STAT_TotalPhysicsTime); SCOPE_CYCLE_COUNTER(STAT_PhysicsFetchDynamicsTime); check(SceneType < NumPhysScenes); if( bPhysXSceneExecuting[SceneType] == 0 ) { // Not executing this scene, must call TickPhysScene before calling this function again. UE_LOG(LogPhysics, Log, TEXT("WaitPhysScene`: Not executing this scene (%d) - aborting."), SceneType); return; } PhysicsSubsceneCompletion[SceneType] = NULL; if (FrameLagAsync()) { checkAtCompileTime(PST_MAX == 2, Assumtiopns_about_physics_scenes); // Here we assume the PST_Sync is the master and never fame lagged if (SceneType == PST_Sync) { // the one frame lagged one should be done by now. check(!FrameLaggedPhysicsSubsceneCompletion[PST_Async].GetReference() || FrameLaggedPhysicsSubsceneCompletion[PST_Async]->IsComplete()); } else { FrameLaggedPhysicsSubsceneCompletion[PST_Async] = NULL; } } #if WITH_PHYSX PxScene* PScene = GetPhysXScene(SceneType); check(PScene); PxU32 OutErrorCode = 0; #if !WITH_APEX PScene->lockWrite(); PScene->fetchResults( true, &OutErrorCode ); PScene->unlockWrite(); #else // #if !WITH_APEX // The APEX scene calls the fetchResults function for the PhysX scene, so we only call ApexScene->fetchResults(). NxApexScene* ApexScene = GetApexScene(SceneType); check(ApexScene); ApexScene->fetchResults( true, &OutErrorCode ); #endif // #if !WITH_APEX if(OutErrorCode != 0) { UE_LOG(LogPhysics, Log, TEXT("PHYSX FETCHRESULTS ERROR: %d"), OutErrorCode); } #endif // WITH_PHYSX // Reset execution flag bPhysXSceneExecuting[SceneType] = false; }
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 renderScene(int iteration) { RenderUtil::startRender(sCamera->getEye(), sCamera->getDir()); PxScene* scene; PxGetPhysics().getScenes(&scene,1); PxU32 nbActors = scene->getNbActors(PxActorTypeSelectionFlag::eRIGID_DYNAMIC); if(nbActors) { std::vector<PxRigidActor*> actors(nbActors); scene->getActors(PxActorTypeSelectionFlag::eRIGID_DYNAMIC, (PxActor**)&actors[0], nbActors); for (PxU32 i = 0; i < nbActors; i++) RenderUtil::renderActors(&actors[i], 1, false, PxVec3(0.3,0.3,0.3)); } if (iteration == 0) { char* result = "Initial Guess"; glRasterPos2i(20,-25); for(int i = 0; i < strlen(result); i++) glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, result[i]); } else { char* label = "Iteration #"; char buffer[10]; itoa(iteration, buffer, 10); char* result = new char[strlen(label)+strlen(buffer)]; sprintf(result,"%s%s",label,buffer); glRasterPos2i(20,-25); for(int i = 0; i < strlen(result); i++) glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, result[i]); } std::string buffer, result; matrix<double> state = render_system->getState(); std::string theta1 = "theta1 = " + to_string((long double) state(0,0)); std::string theta2 = "theta2 = " + to_string((long double) state(1,0)); std::string thetaDot1 = "thetaDot1 = " + to_string((long double) state(2,0)); std::string thetaDot2 = "thetaDot1 = " + to_string((long double) state(3,0)); glRasterPos2i(-35,38); for(int i = 0; i < theta1.length(); i++) glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, theta1[i]); glRasterPos2i(-37,33); for(int i = 0; i < theta2.length(); i++) glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, theta2[i]); glRasterPos2i(-39,28); for(int i = 0; i < thetaDot1.length(); i++) glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, thetaDot1[i]); glRasterPos2i(-41,23); for(int i = 0; i < thetaDot2.length(); i++) glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, thetaDot2[i]); RenderUtil::finishRender(); }
void MirrorActor::createActor(PxScene &scene) { if ( mMirrorActor ) { scene.addActor(*mMirrorActor); } }
//================================================================================= // Single closest hit compound sweep bool PxRigidBodyExt::linearSweepSingle( PxRigidBody& body, PxScene& scene, const PxVec3& unitDir, const PxReal distance, PxHitFlags outputFlags, PxSweepHit& closestHit, PxU32& shapeIndex, const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall, const PxQueryCache* cache, const PxReal inflation) { shapeIndex = 0xFFFFffff; PxReal closestDist = distance; PxU32 nbShapes = body.getNbShapes(); for(PxU32 i=0; i < nbShapes; i++) { PxShape* shape = NULL; body.getShapes(&shape, 1, i); PX_ASSERT(shape != NULL); PxTransform pose = PxShapeExt::getGlobalPose(*shape, body); PxQueryFilterData fd; fd.flags = filterData.flags; PxU32 or4 = (filterData.data.word0 | filterData.data.word1 | filterData.data.word2 | filterData.data.word3); fd.data = or4 ? filterData.data : shape->getSimulationFilterData(); PxGeometryHolder anyGeom = shape->getGeometry(); PxSweepBuffer subHit; // touching hits are not allowed to be returned from the filters scene.sweep(anyGeom.any(), pose, unitDir, distance, subHit, outputFlags, fd, filterCall, cache, inflation); if (subHit.hasBlock && subHit.block.distance < closestDist) { closestDist = subHit.block.distance; closestHit = subHit.block; shapeIndex = i; } } return (shapeIndex != 0xFFFFffff); }
bool Collider::Init(bool isDynamic) { bool ret = false; const Transform& transform = mOwner.GetTransform(); mTransform.position = transform.position; mTransform.rotation = transform.rotation; PxVec3 pos = ConvertPxVec3(transform.position); PxQuat rot = ConvertPxQuat(transform.rotation); PxScene* scene = mOwner.GetScene().GetPxScene(); CHECK(scene); if (isDynamic) { PxRigidDynamic* dyn = gPhysics->createRigidDynamic(PxTransform(pos, rot)); dyn->setLinearDamping(0.25); dyn->setAngularDamping(0.25); mActor = dyn; mRigidBody = new RigidBody(*dyn); } else { mActor = gPhysics->createRigidStatic(PxTransform(pos, rot)); } CHECK(mActor); mActor->userData = &mOwner; OnInitShape(); CHECK(mGizmo); mOwner.GetScene().AddGizmo(mGizmo); mGizmo->SetColor(Color(0, 1, 0, 1)); scene->addActor(*mActor); SetLocalPose(Vector3(), Quat()); ret = true; Exit0: return ret; }
void UDestructibleComponent::AddRadialForce(FVector Origin, float Radius, float Strength, ERadialImpulseFalloff Falloff, bool bAccelChange /* = false */) { #if WITH_APEX if(bIgnoreRadialForce) { return; } if (ApexDestructibleActor == NULL) { return; } PxRigidDynamic** PActorBuffer = NULL; PxU32 PActorCount = 0; if (ApexDestructibleActor->acquirePhysXActorBuffer(PActorBuffer, PActorCount, NxDestructiblePhysXActorQueryFlags::Dynamic)) { PxScene* LockedScene = NULL; while (PActorCount--) { PxRigidDynamic* PActor = *PActorBuffer++; if (PActor != NULL) { if (!LockedScene) { LockedScene = PActor->getScene(); LockedScene->lockWrite(); LockedScene->lockRead(); } AddRadialForceToPxRigidBody_AssumesLocked(*PActor, Origin, Radius, Strength, Falloff, bAccelChange); } if (LockedScene) { LockedScene->unlockRead(); LockedScene->unlockWrite(); LockedScene = NULL; } } ApexDestructibleActor->releasePhysXActorBuffer(); } #endif // #if WITH_APEX }
bool Engine::removeActor( const std::string& s, PxActor* actor ) { PxScene* scene = getScene(s); if ( !scene || !actor ) return false; ActorMap::iterator itr = _actorMap.find( scene ); if ( itr==_actorMap.end() ) return false; ActorList& actors = itr->second; ActorList::iterator fitr = std::find( actors.begin(), actors.end(), actor ); if ( fitr==actors.end() ) return false; scene->removeActor( *actor ); actors.erase( fitr ); if ( !actors.size() ) _actorMap.erase( itr ); return true; }
void FPhysScene::FDeferredSceneData::FlushDeferredActors() { check(AddInstances.Num() == AddActors.Num()); if (AddInstances.Num() > 0) { PxScene* Scene = GetPhysXSceneFromIndex(SceneIndex); SCOPED_SCENE_WRITE_LOCK(Scene); Scene->addActors(AddActors.GetData(), AddActors.Num()); int32 Idx = -1; for (FBodyInstance* Instance : AddInstances) { ++Idx; Instance->CurrentSceneState = BodyInstanceSceneState::Added; if(Instance->GetPxRigidDynamic_AssumesLocked()) { // Extra setup necessary for dynamic objects. Instance->InitDynamicProperties_AssumesLocked(); } } AddInstances.Empty(); AddActors.Empty(); } check(RemoveInstances.Num() == RemoveActors.Num()); if (RemoveInstances.Num() > 0) { PxScene* Scene = GetPhysXSceneFromIndex(SceneIndex); SCOPED_SCENE_WRITE_LOCK(Scene); Scene->removeActors(RemoveActors.GetData(), RemoveActors.Num()); for (FBodyInstance* Instance : AddInstances) { Instance->CurrentSceneState = BodyInstanceSceneState::Removed; } RemoveInstances.Empty(); RemoveActors.Empty(); } }
void renderCallback() { simulatePhysics(true); gGlutRenderer->startRender(sCamera->getEye(), sCamera->getDir()); PxScene* scene; PxGetPhysics().getScenes(&scene, 1); PxU32 nbActors = scene->getNbActors(PxActorTypeSelectionFlag::eRIGID_DYNAMIC | PxActorTypeSelectionFlag::eRIGID_STATIC); if (nbActors) { std::vector<PxRigidActor*> actors(nbActors); scene->getActors(PxActorTypeSelectionFlag::eRIGID_DYNAMIC | PxActorTypeSelectionFlag::eRIGID_STATIC, (PxActor**)&actors[0], nbActors); gGlutRenderer->renderActors(&actors[0], (PxU32)actors.size(), true); } gGlutRenderer->finishRender(); }
void UDestructibleComponent::SetCollisionResponseForAllActors(const FCollisionResponseContainer& ResponseOverride) { #if WITH_APEX if (ApexDestructibleActor == NULL) { return; } PxRigidDynamic** PActorBuffer = NULL; PxU32 PActorCount = 0; if (ApexDestructibleActor->acquirePhysXActorBuffer(PActorBuffer, PActorCount)) { PxScene* LockedScene = NULL; while (PActorCount--) { PxRigidDynamic* PActor = *PActorBuffer++; if (PActor != NULL) { FDestructibleChunkInfo* ChunkInfo = FPhysxUserData::Get<FDestructibleChunkInfo>(PActor->userData); if (ChunkInfo != NULL) { if (!LockedScene) { LockedScene = PActor->getScene(); LockedScene->lockWrite(); LockedScene->lockRead(); } SetCollisionResponseForActor(PActor, ChunkInfo->ChunkIndex, &ResponseOverride); // ChunkIndex is the last chunk made visible. But SetCollisionResponseForActor already doesn't respect per-chunk collision properties. } } } if (LockedScene) { LockedScene->unlockRead(); LockedScene->unlockWrite(); LockedScene = NULL; } ApexDestructibleActor->releasePhysXActorBuffer(); } #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 }
bool FPhysScene::SubstepSimulation(uint32 SceneType, FGraphEventRef &InOutCompletionEvent) { float UseDelta = UseSyncTime(SceneType)? SyncDeltaSeconds : DeltaSeconds; float SubTime = PhysSubSteppers[SceneType]->UpdateTime(UseDelta); PxScene* PScene = GetPhysXScene(SceneType); #if WITH_APEX NxApexScene* ApexScene = GetApexScene(SceneType); if(!ApexScene || SubTime <= 0.f) { return false; }else { //we have valid scene and subtime so enqueue task PhysXCompletionTask* Task = new PhysXCompletionTask(InOutCompletionEvent, PScene->getTaskManager()); FSimpleDelegateGraphTask::CreateAndDispatchWhenReady(FSimpleDelegateGraphTask::FDelegate::CreateRaw(PhysSubSteppers[SceneType], &FPhysSubstepTask::StepSimulation, ApexScene, Task), TEXT("SubstepSimulationImp")); return true; } #endif }
void InitPhysX() { gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback); gPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale() ); if(gPhysicsSDK == NULL) { cerr<<"Error create PhysX."<<endl; } PxSceneDesc sceneDesc(gPhysicsSDK->getTolerancesScale()); sceneDesc.gravity = PxVec3(0.0f, -9.8f, 0.0f); sceneDesc.cpuDispatcher = PxDefaultCpuDispatcherCreate(1); sceneDesc.filterShader = PxDefaultSimulationFilterShader; gScene = gPhysicsSDK->createScene(sceneDesc); PxMaterial* material = gPhysicsSDK->createMaterial(0.5,0.5,0.5); PxTransform planePos = PxTransform(PxVec3(0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f))); PxRigidStatic* plane = gPhysicsSDK->createRigidStatic(planePos); plane->createShape(PxPlaneGeometry(), *material); gScene->addActor(*plane); PxTransform boxPos(PxVec3(0.0f, 10.0f, 0.0f)); PxBoxGeometry boxGeometry(PxVec3(2,2,2)); gBox = PxCreateDynamic(*gPhysicsSDK, boxPos, boxGeometry, *material, 1.0f); gScene->addActor(*gBox); }
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 }
RenderParticleSystemActor::RenderParticleSystemActor(SampleRenderer::Renderer& renderer, ParticleSystem* ps, bool _mesh_instancing, bool _fading, PxReal fadingPeriod, PxReal debriScaleFactor) : mRenderer(renderer), mPS(ps), mUseMeshInstancing(_mesh_instancing), mFading(_fading) { pxtask::CudaContextManager* ctxMgr = NULL; #if defined(RENDERER_ENABLE_CUDA_INTEROP) PxScene* scene = ps->getPxParticleBase()->getScene(); if (scene) { pxtask::GpuDispatcher* dispatcher = scene->getTaskManager()->getGpuDispatcher(); // contxt must be created in at least one valid interop mode if (dispatcher && (ctxMgr = dispatcher->getCudaContextManager()) && ctxMgr->getInteropMode() != pxtask::CudaInteropMode::D3D9_INTEROP && ctxMgr->getInteropMode() != pxtask::CudaInteropMode::D3D10_INTEROP && ctxMgr->getInteropMode() != pxtask::CudaInteropMode::D3D11_INTEROP) { ctxMgr = NULL; } } #endif RendererShape* rs = new SampleRenderer::RendererParticleSystemShape(mRenderer, mPS->getPxParticleBase()->getMaxParticles(), mUseMeshInstancing, mFading, fadingPeriod, debriScaleFactor, ctxMgr); setRenderShape(rs); }
void PhysXBetweenStepsTask::run() { PX_ASSERT(mSubStepSize > 0.0f); PX_ASSERT(mNumSubSteps > 0); #if PX_PHYSICS_VERSION_MAJOR == 3 PxScene* scene = mScene.getPhysXScene(); if (scene != NULL) { while (mSubStepNumber < mNumSubSteps) { PX_PROFILE_ZONE("ApexSceneManualSubstep", GetInternalApexSDK()->getContextId()); // fetch the first substep uint32_t errorState = 0; { SCOPED_PHYSX_LOCK_WRITE(&mScene); scene->fetchResults(true, &errorState); } PX_ASSERT(errorState == 0); for (uint32_t i = 0; i < mScene.mModuleScenes.size(); i++) { PX_PROFILE_ZONE("ModuleSceneManualSubstep", GetInternalApexSDK()->getContextId()); mScene.mModuleScenes[i]->interStep(mSubStepNumber, mNumSubSteps); } // run the next substep { SCOPED_PHYSX_LOCK_WRITE(&mScene); scene->simulate(mSubStepSize); } mSubStepNumber++; } } #endif mLast->removeReference(); // decrement artificially high ref count that prevented checkresults from being executed }