1

私はまだ流体をシミュレートするための物理システムに取り組んでいます。PhysX 3.3.0 を使用してより客観的になるようにアプリケーションを書き直しましたが、1、2 週間ほど解決できない問題があります。

これは私の PhysX Context の開始です。

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 シーンの開始が、空のシーンでも問題が発生します。

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() 呼び出しでアプリケーションがフリーズします (simulate() メソッドがそのジョブを終了しません)。エラーログはありません。フリーズするだけです。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 を使用して、アプリケーションが必要とする .dlls を追加しようとしましたが、すべてのセットが fetchResult() でフリーズしてしまいました。

間違いを探す場所がわかりません。すべてがうまく見えます。どんな助けにも感謝します!

4

1 に答える 1