Я все еще работаю над системой физики для моделирования жидкостей. Я переписал свое приложение, чтобы использовать PhysX 3.3.0 и быть более объективным, и теперь у меня есть проблема, которую я не могу решить в течение недели или двух.
Это мое начало 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 закомментирован, все работает нормально. Жидкость течет так, как должна. Но когда я пытаюсь использовать мой графический процессор, приложение останавливается при первом вызове fetchResult () (метод simulate () никогда не завершает свою работу). У меня нет журнала ошибок, он просто зависает. Это происходит независимо от того, является ли он DEBUG или RELEASE, и является ли он 32 или 64 билдом.
У меня GeForce 560Ti. Я использую Physx SDK 3.3.0. Я ссылаюсь (например, на сборку отладки win64) против:
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 ().
Я понятия не имею, где искать ошибки. Все выглядит хорошо. Буду благодарен за любую помощь!
Я знаю, что это старая тема, но у меня возникла та же проблема, когда я перешел с 3.2.5 на 3.3.0.
Я нашел решение. Проблема в том, что вы дважды инициализируете расширения. Ты используешь PxCreateBasePhysics
создать свой объект SDK, который выполняет дополнительную работу в фоновом режиме. А именно это вызывает PxInitExtensions
если я не ошибаюсь.
Исправление состоит в том, чтобы просто изменить PxCreateBasePhysics
функция к стандарту PxCreatePhysics
звоните с точно такими же аргументами. Этот не делает никаких дополнительных настроек за сценой. Просто опуская InitExtensions
Call может работать, но я попробовал только первую идею.
Странно, что это приводит к зависанию только в том случае, если используется графический процессор, может быть, nVidia должна посмотреть на это.
Других решений пока нет …