2013-12-23 97 views
1

我仍在工作物理系統模擬流體。我重寫了我的應用程序使用PhysX 3.3.0,並更客觀,現在我有一個問題,我無法解決像一個星期或兩個。PhysX - 模擬()永遠不會結束,如果GPU使用

這是我的PhysX上下文開始:

void PhysXSPH::initContext(void){ 
    static LogPxErrorCallback gLogPxErrorCallback; 
    static PxDefaultAllocator gDefaultAllocatorCallback; 

    mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gLogPxErrorCallback); 
    check(mFoundation, "PxFoundation creating failed!"); 

    static PxProfileZoneManager *mProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(mFoundation); 
    check(mProfileZoneManager, "PxProfileZoneManager creation failed!"); 

    bool recordMemoryAllocations = true; 
    mPhysics = PxCreateBasePhysics(PX_PHYSICS_VERSION, *mFoundation, 
     PxTolerancesScale(), recordMemoryAllocations, mProfileZoneManager); 
    check(mPhysics, "PxPhysics creating failed!"); 

    PxRegisterParticles(*mPhysics); 
    if(!PxInitExtensions(*mPhysics)){ 
     check(NULL, "PxInitExtensions failed!"); 
    } 

    static PxSimulationFilterShader gDefaultFilterShader = PxDefaultSimulationFilterShader; 
    PxSceneDesc sceneDesc(mPhysics->getTolerancesScale()); 

    sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); 

    if(!sceneDesc.cpuDispatcher){ 
     mCpuDispatcher = PxDefaultCpuDispatcherCreate(4); 
     check(mCpuDispatcher, "PxDefaultCpuDispatcherCreate failed!"); 
     sceneDesc.cpuDispatcher = mCpuDispatcher; 
    } 
    if(!sceneDesc.filterShader){ 
     sceneDesc.filterShader = gDefaultFilterShader; 
    } 

#ifdef PX_WINDOWS 

    PxCudaContextManagerDesc cudaContextManagerDesc; 
    mCudaContextManager = PxCreateCudaContextManager(*mFoundation, cudaContextManagerDesc, mProfileZoneManager); 
    if(mCudaContextManager){ 
     if(!mCudaContextManager->contextIsValid()){ 
      mCudaContextManager->release(); 
      mCudaContextManager = NULL; 
      CLOG(ERROR, "physX")<<"Invalid CUDA context."; 
      exit(EXIT_FAILURE); 
     } 

     if(!sceneDesc.gpuDispatcher){ 
      sceneDesc.gpuDispatcher = mCudaContextManager->getGpuDispatcher(); 
     } 
     CLOG(INFO, "physX")<<"CUDA context created."; 
    } else { 
     CLOG(ERROR, "physX")<<"Creating CUDA context manager failed."; 
     exit(EXIT_FAILURE); 
    } 

#endif 

    mScene = mPhysics->createScene(sceneDesc); 
    check(mScene, "createScene failed!"); 

    createScene(mScene); 
} 

和起始的PhysX物理場景,但問題一個空的場景甚至occures:

void PhysXSPH::createScene(PxScene *mScene){ 
    mScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1.0); 
    mScene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1.0f); 
    createPlanes(mScene); 
    createParticles(mScene); 
    CLOG(INFO, "physX") << "PhysX scene created."; 
} 

void PhysXSPH::createPlanes(PxScene *mScene){ 
    PxMaterial* mMaterial = mPhysics->createMaterial(0.5,0.5,0.5); 

    //Create actors 
    //1) Create ground plane 
    PxReal d = 0.0f;  
    PxTransform pose = PxTransform(PxVec3(0.0f, 0, 0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f))); 

    PxRigidStatic* plane = mPhysics->createRigidStatic(pose); 
    check(plane, "Creating plane failed!"); 

    //create 4 more planes for aquarium 

    PxRigidStatic* plane2 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(-4.0f, 0.0, 0.0), PxVec3(1.0, 0.0, 0.0)), *mMaterial); 

    PxRigidStatic* plane3 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(4.0f, 0.0, 0.0), PxVec3(-1.0, 0.0, 0.0)), *mMaterial); 

    PxRigidStatic* plane4 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(0.0f, 0.0, -4.0f), PxVec3(0.0, 0.0, 1.0)), *mMaterial); 

    PxRigidStatic* plane5 = PxCreatePlane(*mPhysics, PxPlane(PxVec3(0.0f, 0.0, 4.0f), PxVec3(0.0, 0.0, -1.0)), *mMaterial); 

    // create shape 
    PxShape* shape = plane->createShape(PxPlaneGeometry(), *mMaterial); 
    check(shape, "Creating shape failed!"); 

    mScene->addActor(*plane); 

    PxShape* shape2 = plane2->createShape(PxPlaneGeometry(), *mMaterial); 
    check(shape2, "Creating shape failed!"); 
    mScene->addActor(*plane2); 


    PxShape* shape3 = plane3->createShape(PxPlaneGeometry(), *mMaterial); 
    check(shape3, "Creating shape failed!"); 
    mScene->addActor(*plane3); 

    PxShape* shape4 = plane4->createShape(PxPlaneGeometry(), *mMaterial); 
    check(shape4, "Creating shape failed!"); 
    mScene->addActor(*plane4); 

    PxShape* shape5 = plane5->createShape(PxPlaneGeometry(), *mMaterial); 
    check(shape5, "Creating shape failed!"); 
    mScene->addActor(*plane5); 
} 

void PhysXSPH::createParticles(PxScene *mScene){ 
    // set immutable properties. 
    bool perParticleRestOffset = false; 

    //get data from scene model 
    int maxParticles = scene->getMaxParticles(); 
    int xDim = scene->getXDim(); 
    int yDim = scene->getYDim(); 
    int zDim = scene->getZDim(); 

    // create particle system in PhysX SDK 
    particleSystem = mPhysics->createParticleFluid(maxParticles, perParticleRestOffset); 
    check(particleSystem, "Creating particle system failed!"); 

    particleSystem->setRestOffset(particleRadius); 
    particleSystem->setRestParticleDistance(particleRadius); 
    particleSystem->setParticleBaseFlag(PxParticleBaseFlag::eGPU,true); 
    // TODO set fluid parameters 


    // add particle system to scene, in case creation was successful 
    if (particleSystem) 
     mScene->addActor(*particleSystem); 

    indexes = new PxU32[maxParticles]; 
    particle_positions = new PxVec3[maxParticles]; 

    int index=0; 
    for(int x=0; x<xDim ;x++){ 
     for(int y=0; y<yDim ;y++){ 
      for(int z=0; z<zDim; z++){ 
       indexes[index]=(PxU32)index; 
       int v=3*index; 

       particle_positions[index]=PxVec3((physx::PxReal)(scene->m_vPos[v]), (physx::PxReal)(scene->m_vPos[v+1]), (physx::PxReal)(scene->m_vPos[v+2])); 

       //CLOG(INFO, "physX")<<index<<"["<<particle_positions[index].x<<"; "<<particle_positions[index].y<<"; "<<particle_positions[index].z<<"]"; 
       index++; 
      } 
     } 
    } 

    PxParticleCreationData particleCreationData; 
    particleCreationData.numParticles = maxParticles; 
    particleCreationData.indexBuffer = PxStrideIterator<const PxU32>(indexes); 
    particleCreationData.positionBuffer = PxStrideIterator<const PxVec3>(particle_positions); 

    // create particles in *PxParticleSystem* ps 
    bool success = particleSystem->createParticles(particleCreationData); 
    if(!success){ 
     CLOG(ERROR, "physX")<<"Creating particles failed."; 
     exit(EXIT_FAILURE); 
    } 
} 

如果#ifdef來PX_WINDOWS代碼被註釋掉,一切正常。流體流動像它應該。但是當我嘗試使用我的GPU時,應用程序在第一次fetchResult()調用(模擬()方法永遠不會完成其作業)時凍結。我沒有錯誤日誌,它只是凍結。無論它的DEBUG還是RELEASE,它都會發生,如果它是32或64版本的話。

我有一個GeForce 560Ti。我使用Physx SDK 3.3.0。我鏈接(如Win64上調試版本。)VS:

opengl32.lib glew32.lib glfw3.lib PhysX3DEBUG_x64.lib PhysX3CommonDEBUG_x64.lib PxTaskDEBUG.lib PhysX3ExtensionsDEBUG.lib PhysXProfileSDKDEBUG.lib

使用:

nvToolsExt64_1.dll PhysX3XHECKED_x64.dll PhysX3CommonCHECKED_x64.dll PhysX3GpuCHECKED_x64.dll PhysX3GpuDEBUG_x64.dll

我試圖使用不同版本的.libs並添加應用程序想.DLL文件,但每一組結束了一個冰凍的fetchResult()。

我不知道在哪裏尋找錯誤。一切都很美好。我會很感激任何幫助!

+0

我遷移到了PhysX 3.2.5,它在api更改後很有用。我猜可能是PhysX中的一個錯誤。 oO – aerion

回答

1

我知道這是一個古老的線程,但我有完全相同的問題,當我從3.2.5切換到3.3.0。

我確實找到了解決方案。問題是你在這裏初始化擴展兩次。您正在使用PxCreateBasePhysics來創建您的SDK對象,它在後臺執行一些額外的工作。如果我沒有弄錯的話,它叫PxInitExtensions

解決方法是隻需更改PxCreateBasePhysics功能標準PxCreatePhysics調用具有完全相同的參數。這個人在場景後面不做任何額外的設置。只留下撥打InitExtensions的電話也可以,但我只嘗試了第一個想法。

這是一個奇怪的事情,這不僅會導致凍結,如果GPU是在使用中,也許應該nVidia的看它。

+0

有趣的是,我很確定PxCreatePhysics初始化了所有的擴展,而PxCreateBasePhysix可以讓你自己選擇它。從SDK文檔: '如果你的應用需要這個功能的一個子集,建議您致電PxCreateBasePhysics而不是PxCreatePhysics,然後手動註冊您從3.3 require.' – aerion

+0

代碼的元件庫。0: 'PX_INLINE PhysX物理:: PxPhysics * PxCreatePhysics(...) { \t PhysX物理:: PxPhysics *物理= PxCreateBasePhysics(版本,基礎,規模,trackOutstandingAllocations,profileZoneManager); \t if(!physics) \t \t return NULL; \t PxRegisterArticulations(* physics); \t PxRegisterHeightFields(* physics); \t PxRegisterCloth(* physics); \t PxRegisterParticles(* physics); \t return physics; }' – aerion

相關問題