Im having a small issue here, so basically if I add particles to my particle system, then later on (almost instantly) a worker thread crashes, inside APEX_Particles86.dll (More or less the name), if I do not add these particles then no crash occurs.
How I add particles:
// Buffers
PxU32* pIndex = new PxU32[nParticles];
PxVec3* pPosition = new PxVec3[nParticles];
PxVec3* pVelocity = new PxVec3[nParticles];
UNTIL(nParticles)
{
// Index
pIndex[i] = i;
// Copy Data
pPosition[i] = PxVec3(pParticles[i].vPosition.x, pParticles[i].vPosition.y, pParticles[i].vPosition.z);
pVelocity[i] = PxVec3(pParticles[i].vVelocity.x, pParticles[i].vVelocity.y, pParticles[i].vVelocity.z);
// Push Particle
pSystem->pParticles.push_back(&pParticles[i]);
}
// Desc
PxParticleCreationData particleCreationData;
particleCreationData.numParticles = nParticles;
particleCreationData.indexBuffer = PxStrideIterator<const PxU32>(pIndex);
particleCreationData.positionBuffer = PxStrideIterator<const PxVec3>(pPosition);
particleCreationData.velocityBuffer = PxStrideIterator<const PxVec3>(pVelocity);
// Create Particles
if (!((PxParticleSystem*)pSystem->ppNative)->createParticles(particleCreationData))
{
MessageBoxA(NULL, "PhysX Particle insertion failed, this behavior is not intended", "PhysX Error", 0);
}
If youre interested, here’s how I set up the apex/physx system, as the crash did NOT occur before adding APEX support:
// Create Foundation
m_pFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback);
// Check
if (!m_pFoundation) return false;
// Create Profiling Zone Manager
//m_pProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(m_pFoundation);
// Check
//if (!m_pProfileZoneManager) return false;
// Create SDK System
m_pPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *m_pFoundation, PxTolerancesScale());
// Check
if (!m_pPhysicsSDK) return false;
// Create Default Material
m_pMaterialDefault = MaterialCreate(0.5f, 0.5f, 0.6f);
// Check
if (!m_pMaterialDefault) return false;
// Load extensions
PxInitExtensions(*m_pPhysicsSDK);
// Cooking
{
// Create Cooking
PxCookingParams PCookingParams = PxCookingParams(PxTolerancesScale());
PCookingParams.meshWeldTolerance = 0.1f; // Weld to 1mm precision
PCookingParams.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eWELD_VERTICES | PxMeshPreprocessingFlag::eREMOVE_UNREFERENCED_VERTICES | PxMeshPreprocessingFlag::eREMOVE_DUPLICATED_TRIANGLES);
PCookingParams.targetPlatform = PxPlatform::ePC;
// Create Cooking
m_pCooking = PxCreateCooking(PX_PHYSICS_VERSION, *m_pFoundation, PCookingParams);
}
// Create CPU Dispatcher
m_pDispatcher = PxDefaultCpuDispatcherCreate(2);
// Check
if (!m_pDispatcher) return false;
// Scene...
{
// Create Scene Description
PxSceneDesc sceneDesc(m_pPhysicsSDK->getTolerancesScale());
// Set Gravity
sceneDesc.gravity = PxVec3(0.0f, 0.0f, 0.0f);
// Dispatcher
sceneDesc.cpuDispatcher = m_pDispatcher;
// Set Filter
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
sceneDesc.flags |= PxSceneFlag::eENABLE_CCD; // Prevent tunneling
// Create the actual scene
m_pScene = m_pPhysicsSDK->createScene(sceneDesc);
// Check
if (!m_pScene) return false;
}
// APEX SDK
{
using namespace physx::apex;
// Desc
NxApexSDKDesc apexDesc;
apexDesc.physXSDK = m_pPhysicsSDK;
apexDesc.cooking = m_pCooking;
apexDesc.physXSDKVersion = NX_PHYSICS_SDK_VERSION;
apexDesc.resourceCallback = new CEApexResourceCallback(NULL);
apexDesc.renderResourceManager = new FApexNullRenderResourceManager();
// Error Code
apex::NxApexCreateError errorCode;
// Load Apex
m_pApexSDK = NxCreateApexSDK(apexDesc, &errorCode, NX_APEX_SDK_VERSION);
// Set Resource Manager SDK
((CEApexResourceCallback*)apexDesc.resourceCallback)->pSDK = m_pApexSDK;
// Scene
{
NxApexSceneDesc apexSceneDesc;
// Set Reference
apexSceneDesc.scene = m_pScene;
// Create the APEX scene...
m_pApexScene = m_pApexSDK->createScene(apexSceneDesc);
}
// Modules
{
m_pApexParticles = static_cast<NxModuleParticles*>(m_pApexSDK->createModule("Particles"));
PX_ASSERT(m_pApexParticles);
m_pApexParticleBasicIOS = static_cast<NxModuleBasicIos*>(m_pApexParticles->getModule("BasicIOS"));
PX_ASSERT(m_pApexParticleBasicIOS);
if (m_pApexParticleBasicIOS)
{
NxParameterized::Interface* params = m_pApexParticleBasicIOS->getDefaultModuleDesc();
m_pApexParticleBasicIOS->init(*params);
m_pApexParticleBasicIOS->setLODBenefitValue(10000.0f);
}
m_pApexParticleIOS = static_cast<NxModuleParticleIos*>(m_pApexParticles->getModule("ParticleIOS"));
PX_ASSERT(m_pApexParticleIOS);
if (m_pApexParticleIOS)
{
NxParameterized::Interface* params = m_pApexParticleIOS->getDefaultModuleDesc();
m_pApexParticleIOS->init(*params);
}
m_pApexEmitter = static_cast<NxModuleEmitter*>(m_pApexParticles->getModule("Emitter"));
PX_ASSERT(m_pApexEmitter);
if (m_pApexEmitter)
{
NxParameterized::Interface* params = m_pApexEmitter->getDefaultModuleDesc();
m_pApexEmitter->init(*params);
int mNbEmitterModuleScalables = m_pApexEmitter->getNbParameters();
NxApexParameter **mEmitterModuleScalables = m_pApexEmitter->getParameters();
for (physx::PxU32 i = 0; i < mNbEmitterModuleScalables; i++)
{
NxApexParameter& p = *mEmitterModuleScalables[i];
m_pApexEmitter->setIntValue(i, p.range.maximum);
}
//updateScalableAndLodInfo();
}
m_pApexIOFX = static_cast<NxModuleIofx*>(m_pApexParticles->getModule("IOFX"));
PX_ASSERT(m_pApexIOFX);
if (m_pApexIOFX)
{
NxParameterized::Interface* params = m_pApexIOFX->getDefaultModuleDesc();
m_pApexIOFX->init(*params);
//mApexIofxModule->disableCudaInterop();
//mApexIofxModule->disableCudaModifiers();
}
NxModuleFieldSampler* fsModule = static_cast<NxModuleFieldSampler*>(m_pApexParticles->getModule("FieldSampler"));
physx::apex::NxModule* Legacy = m_pApexSDK->createModule("Legacy");
PX_ASSERT(Legacy);
if (Legacy)
{
Legacy->init(*Legacy->getDefaultModuleDesc());
}
}
}
m_pScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, false);
m_pScene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1.0f);
// If there, try to connect to the PVD
{
// Check if PhysX Visual Debuger is running and listening
if (!m_pPhysicsSDK->getPvdConnectionManager())
{
return true;
}
const char* pvdHostIP = "127.0.0.1";
int port = 5425;
unsigned int timeout = 100;
physx::PxVisualDebuggerConnectionFlags flags =
physx::PxVisualDebuggerConnectionFlag::eDEBUG
| physx::PxVisualDebuggerConnectionFlag::ePROFILE
| physx::PxVisualDebuggerConnectionFlag::eMEMORY;
m_pPhysicsSDK->getVisualDebugger()->setVisualizeConstraints(true);
m_pPhysicsSDK->getVisualDebugger()->setVisualDebuggerFlag(physx::PxVisualDebuggerFlag::eTRANSMIT_SCENEQUERIES, true);
// Create connection with PhysX Visual Debugger
physx::debugger::comm::PvdConnection* conn = physx::PxVisualDebuggerExt::createConnection(
m_pPhysicsSDK->getPvdConnectionManager(),
pvdHostIP,
port,
timeout,
flags);
if (conn)
{
m_pPhysicsSDK->getVisualDebugger()->setVisualizeConstraints(true);
m_pPhysicsSDK->getVisualDebugger()->setVisualDebuggerFlag(physx::PxVisualDebuggerFlag::eTRANSMIT_CONTACTS, true);
}
}
Any help would be great.
If you need any other information please inform me and I’ll add it as soon as possible.
Thank you.