/** * Perform any cleanup of physics engine resources. * This is deferred because when closing down the game, you want to make sure you are not destroying a mesh after the physics SDK has been shut down. */ void DeferredPhysResourceCleanup() { #if WITH_PHYSX // Release all tri meshes and reset array for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillTriMesh.Num(); MeshIdx++) { PxTriangleMesh* PTriMesh = GPhysXPendingKillTriMesh[MeshIdx]; check(PTriMesh); PTriMesh->release(); GPhysXPendingKillTriMesh[MeshIdx] = NULL; } GPhysXPendingKillTriMesh.Reset(); // Release all convex meshes and reset array for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillConvex.Num(); MeshIdx++) { PxConvexMesh* PConvexMesh = GPhysXPendingKillConvex[MeshIdx]; check(PConvexMesh); PConvexMesh->release(); GPhysXPendingKillConvex[MeshIdx] = NULL; } GPhysXPendingKillConvex.Reset(); // Release all heightfields and reset array for(int32 HfIdx=0; HfIdx<GPhysXPendingKillHeightfield.Num(); HfIdx++) { PxHeightField* PHeightfield = GPhysXPendingKillHeightfield[HfIdx]; check(PHeightfield); PHeightfield->release(); GPhysXPendingKillHeightfield[HfIdx] = NULL; } GPhysXPendingKillHeightfield.Reset(); // Release all materials and reset array for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillMaterial.Num(); MeshIdx++) { PxMaterial* PMaterial = GPhysXPendingKillMaterial[MeshIdx]; check(PMaterial); PMaterial->release(); GPhysXPendingKillMaterial[MeshIdx] = NULL; } GPhysXPendingKillMaterial.Reset(); #endif }
// Creates an physics entity from an entity info structure and a starting transform void PhysicsEngine::createEntity(PhysicsEntity* entity, PhysicsEntityInfo* info, PxTransform transform) { transform.p.y += info->yPosOffset; // Set static/dynamic info for actor depending on its type PxRigidActor* actor; if (info->type == PhysicsType::DYNAMIC) { DynamicInfo* dInfo = info->dynamicInfo; PxRigidDynamic* dynamicActor = physics->createRigidDynamic(transform); dynamicActor->setLinearDamping(dInfo->linearDamping); dynamicActor->setAngularDamping(dInfo->angularDamping); dynamicActor->setMaxAngularVelocity(dInfo->maxAngularVelocity); actor = dynamicActor; } else if (info->type == PhysicsType::STATIC) { PxRigidStatic* staticActor = physics->createRigidStatic(transform); actor = staticActor; } // All shapes in actor for (auto sInfo : info->shapeInfo) { // Create material and geometry for shape and add it to actor PxGeometry* geometry; PxMaterial* material; if (sInfo->geometry == Geometry::SPHERE) { SphereInfo* sphInfo = (SphereInfo*)sInfo; geometry = new PxSphereGeometry(sphInfo->radius); } else if (sInfo->geometry == Geometry::BOX) { BoxInfo* boxInfo = (BoxInfo*)sInfo; geometry = new PxBoxGeometry(boxInfo->halfX, boxInfo->halfY, boxInfo->halfZ); } else if (sInfo->geometry == Geometry::CAPSULE) { CapsuleInfo* capInfo = (CapsuleInfo*)sInfo; geometry = new PxCapsuleGeometry(capInfo->radius, capInfo->halfHeight); } else if (sInfo->geometry == Geometry::CONVEX_MESH) { ConvexMeshInfo* cmInfo = (ConvexMeshInfo*)sInfo; PxConvexMesh* mesh = helper->createConvexMesh(cmInfo->verts.data(), cmInfo->verts.size()); geometry = new PxConvexMeshGeometry(mesh); } // Not working until index drawing is set up else if (sInfo->geometry == Geometry::TRIANGLE_MESH) { TriangleMeshInfo* tmInfo = (TriangleMeshInfo*)sInfo; PxTriangleMesh* mesh = helper->createTriangleMesh(tmInfo->verts.data(), tmInfo->verts.size(), tmInfo->faces.data(), tmInfo->faces.size()/3); geometry = new PxTriangleMeshGeometry(mesh); } material = (sInfo->isDrivable) ? drivingSurfaces[0] : physics->createMaterial(sInfo->dynamicFriction, sInfo->staticFriction, sInfo->restitution); PxShape* shape = actor->createShape(*geometry, *material); // TODO support shape flags shape->setLocalPose(sInfo->transform); material->release(); delete geometry; // Set up querry filter data for shape PxFilterData qryFilterData; qryFilterData.word3 = (sInfo->isDrivable) ? (PxU32)Surface::DRIVABLE : (PxU32)Surface::UNDRIVABLE; shape->setQueryFilterData(qryFilterData); // Set up simulation filter data for shape PxFilterData simFilterData; simFilterData.word0 = (PxU32)sInfo->filterFlag0; simFilterData.word1 = (PxU32)sInfo->filterFlag1; simFilterData.word2 = (PxU32)sInfo->filterFlag2; simFilterData.word3 = (PxU32)sInfo->filterFlag3; shape->setSimulationFilterData(simFilterData); if (info->type == PhysicsType::DYNAMIC) { DynamicInfo* dInfo = info->dynamicInfo; PxRigidBodyExt::updateMassAndInertia(*(PxRigidBody*)actor, dInfo->density, &dInfo->cmOffset); PxRigidBody* body = (PxRigidBody*)actor; } } // Add actor to scene, set actor for entity, and set user data for actor. Creates one to one between entities and phyX scene->addActor(*actor); entity->setActor(actor); actor->userData = entity; }
/** * Perform any cleanup of physics engine resources. * This is deferred because when closing down the game, you want to make sure you are not destroying a mesh after the physics SDK has been shut down. */ void DeferredPhysResourceCleanup() { #if WITH_PHYSX // Release all tri meshes and reset array for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillTriMesh.Num(); MeshIdx++) { PxTriangleMesh* PTriMesh = GPhysXPendingKillTriMesh[MeshIdx]; // Check this as it shouldn't be null, but then gate on it so we can // avoid a crash if we end up in this state in shipping check(PTriMesh); if(PTriMesh) { PTriMesh->release(); if(GPhysXPendingKillTriMesh.IsValidIndex(MeshIdx)) { GPhysXPendingKillTriMesh[MeshIdx] = NULL; } else { UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found invalid index into GPhysXPendingKillTriMesh, another thread may have modified the array."), MeshIdx); } } else { UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found null PxTriangleMesh in pending kill array, another thread may have modified the array."), MeshIdx); } } GPhysXPendingKillTriMesh.Reset(); // Release all convex meshes and reset array for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillConvex.Num(); MeshIdx++) { PxConvexMesh* PConvexMesh = GPhysXPendingKillConvex[MeshIdx]; // Check this as it shouldn't be null, but then gate on it so we can // avoid a crash if we end up in this state in shipping check(PConvexMesh); if(PConvexMesh) { PConvexMesh->release(); if(GPhysXPendingKillConvex.IsValidIndex(MeshIdx)) { GPhysXPendingKillConvex[MeshIdx] = NULL; } else { UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found invalid index into GPhysXPendingKillConvex (%d), another thread may have modified the array."), MeshIdx); } } else { UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found null PxConvexMesh in pending kill array (at %d), another thread may have modified the array."), MeshIdx); } } GPhysXPendingKillConvex.Reset(); // Release all heightfields and reset array for(int32 HfIdx=0; HfIdx<GPhysXPendingKillHeightfield.Num(); HfIdx++) { PxHeightField* PHeightfield = GPhysXPendingKillHeightfield[HfIdx]; // Check this as it shouldn't be null, but then gate on it so we can // avoid a crash if we end up in this state in shipping check(PHeightfield); if(PHeightfield) { PHeightfield->release(); if(GPhysXPendingKillHeightfield.IsValidIndex(HfIdx)) { GPhysXPendingKillHeightfield[HfIdx] = NULL; } else { UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found invalid index into GPhysXPendingKillHeightfield (%d), another thread may have modified the array."), HfIdx); } } else { UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found null PxHeightField in pending kill array (at %d), another thread may have modified the array."), HfIdx); } } GPhysXPendingKillHeightfield.Reset(); // Release all materials and reset array for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillMaterial.Num(); MeshIdx++) { PxMaterial* PMaterial = GPhysXPendingKillMaterial[MeshIdx]; // Check this as it shouldn't be null, but then gate on it so we can // avoid a crash if we end up in this state in shipping check(PMaterial); if(PMaterial) { PMaterial->release(); if(GPhysXPendingKillMaterial.IsValidIndex(MeshIdx)) { GPhysXPendingKillMaterial[MeshIdx] = NULL; } else { UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found invalid index into GPhysXPendingKillMaterial(%d), another thread may have modified the array."), MeshIdx); } } else { UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found null PxMaterial in pending kill array (at %d), another thread may have modified the array."), MeshIdx); } } GPhysXPendingKillMaterial.Reset(); #endif }