/** * 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; }
//------------------------------------------------------------------------------ void PlayScene::create() { World& world = getSceneManager().getWorld(); // Camera Transform* transCamera = DG_NEW(Transform, world.getLinearArena()); transCamera->position = vmVector3(0.0f, 3.4f, 0.0f); Camera* camera = DG_NEW(Camera, world.getLinearArena()); camera->fov = 0.9f; world.getEntity(0).addComponent(transCamera); world.getEntity(0).addComponent(camera); // Light Transform* transLight = DG_NEW(Transform, world.getLinearArena()); transLight->position = vmVector3(0, 10, 0); Light* light = DG_NEW(Light, world.getLinearArena())(0); light->lightType = LT_DIRECTIONAL; light->direction = vmVector3(0.0f, 0.9f, 1.0f); //Material matCube; //matCube.ambient = vmVector4(0.7f, 0.7f, 0.7f, 1.f); //matCube.diffuse = vmVector4(0.7f, 0.7f, 0.7f, 1.f); //matCube.textureFiles.push_back("tiles.png"); //Mesh* meshCube = DG_NEW(Mesh, world.getLinearArena()); //meshCube->file = "../media/cube.x"; //meshCube->materials.push_back(matCube); world.getEntity(1).addComponent(transLight); world.getEntity(1).addComponent(light); //world.getEntity(1).addComponent(meshCube); // Set active camera and light world.getSystemManager().getSystem<MeshSystem>()->setCamera(camera); world.getSystemManager().getSystem<MeshSystem>()->setLight(light); // Sky Transform* transSky = DG_NEW(Transform, world.getLinearArena()); transSky->position = vmVector3(0, 0, 0); Material matSky; matSky.textureFiles.push_back("NoiseVolume.dds"); Mesh* meshSky = DG_NEW(Mesh, world.getLinearArena()); meshSky->file = "../media/sphere_inverted.x"; meshSky->effectFile = "../media/sky.cg"; meshSky->materials.push_back(matSky); world.getEntity(2).addComponent(transSky); world.getEntity(2).addComponent(meshSky); // Terrain Transform* transTerrain = DG_NEW(Transform, world.getLinearArena()); transTerrain->position = vmVector3(0, 0, 0); Material matTerrain; matTerrain.ambient = vmVector4(0.2f, 0.2f, 0.2f, 1.f); matTerrain.diffuse = vmVector4(0.7f, 0.7f, 0.7f, 1.f); matTerrain.textureFiles.push_back("grass.jpg"); Mesh* meshTerrain = DG_NEW(Mesh, world.getLinearArena()); meshTerrain->file = "../media/TerrainTextured.x"; meshTerrain->effectFile = "../media/terrain.cg"; meshTerrain->materials.push_back(matTerrain); world.getEntity(3).addComponent(transTerrain); world.getEntity(3).addComponent(meshTerrain); // Water Transform* transWater = DG_NEW(Transform, world.getLinearArena()); transWater->position = vmVector3(0, -2, 0); transWater->scale = vmVector3(130, 1, 130); Material matWater; matWater.ambient = vmVector4(0.0f, 0.5459f, 0.8496f, 1.f); matWater.diffuse = vmVector4(0.0f, 0.5459f, 0.8496f, 0.5f); Mesh* meshWater = DG_NEW(Mesh, world.getLinearArena()); meshWater->file = "../media/quad.x"; meshWater->effectFile = "../media/water.cg"; meshWater->materials.push_back(matWater); world.getEntity(4).addComponent(transWater); world.getEntity(4).addComponent(meshWater); // Copter Transform* transCopter = DG_NEW(Transform, world.getLinearArena()); transCopter->position = vmVector3(0, 0, 0); Material matCopter; Material matCopter2; matCopter2.ambient = vmVector4(0.2f, 0.2f, 0.2f, 1.f); matCopter2.diffuse = vmVector4(0.7f, 0.7f, 0.7f, 1.f); matCopter2.textureFiles.push_back("copter_diffuse.png"); matCopter2.textureFiles.push_back("copter_normal.png"); //matCopter2.textureFiles.push_back("tiles.png"); //matCopter2.textureFiles.push_back("tiles_normal.png"); Mesh* meshCopter = DG_NEW(Mesh, world.getLinearArena()); meshCopter->file = "../media/copter.x"; meshCopter->effectFile = "../media/copter.cg"; meshCopter->materials.push_back(matCopter); meshCopter->materials.push_back(matCopter2); world.getEntity(5).addComponent(transCopter); world.getEntity(5).addComponent(meshCopter); // Initialise all systems world.getSystemManager().initialiseAll(); // Test physics PxMaterial* material = &mPhysXWorld.getDefaultMaterial(); material->setRestitution(0.5f); material->setStaticFriction(1.0f); material->setDynamicFriction(1.0f); //mActor = mPhysXWorld.getScene("Main")->createRigidDynamic( //physx::PxConvexMeshGeometry(PhysXCooker::createPxConvexMesh(*mPhysXWorld.getPxPhysics(), *mPhysXWorld.getCookingInterface(), //world.getSystemManager().getSystem<MeshSystem>()->getVertices(world.getEntity(3)))), 20.0f, *material); /*mActor = mPhysXWorld.getScene("Main")->createRigidDynamic( PhysXGeometry::boxGeometry(world.getEntity(2), *world.getSystemManager().getSystem<MeshSystem>()), 10.0f, *material); mPhysXWorld.getScene("Main")->createRenderedActorBinding(mActor, DG_NEW(PhysXEntityRenderable, world.getLinearArena())(&world.getEntity(2))); mActor.setGlobalPosition(vmVector3(0.0f, 20.0, 0.0f));*/ //PhysXActor<PxRigidDynamic> actor1 = mPhysXWorld.getScene("Main")->createRigidDynamic( //physx::PxConvexMeshGeometry(PhysXCooker::createPxConvexMesh(*mPhysXWorld.getPxPhysics(), *mPhysXWorld.getCookingInterface(), //world.getSystemManager().getSystem<MeshSystem>()->getVertices(world.getEntity(4)))), 20.0f, *material); mActor = mPhysXWorld.getScene("Main")->createRigidDynamic( PhysXGeometry::boxGeometry(world.getEntity(5), *world.getSystemManager().getSystem<MeshSystem>()), 1.f, *material); mPhysXWorld.getScene("Main")->createRenderedActorBinding(mActor, DG_NEW(PhysXEntityRenderable, world.getLinearArena())(&world.getEntity(5))); mActor.setGlobalPosition(vmVector3(-3.0f, 0.0f, 0.0f)); mActor.getPxActor()->setLinearDamping(0.8f); mActor.getPxActor()->setAngularDamping(1.0f); PhysXActor<PxRigidStatic> actor2 = mPhysXWorld.getScene("Main")->createRigidStatic( physx::PxTriangleMeshGeometry(PhysXCooker::createPxTriangleMesh(*mPhysXWorld.getPxPhysics(), *mPhysXWorld.getCookingInterface(), world.getSystemManager().getSystem<MeshSystem>()->getIndices(world.getEntity(3)), world.getSystemManager().getSystem<MeshSystem>()->getVertices(world.getEntity(3)))), *material); mInput.subscribeKeyboard(*this); mInput.subscribeMouse(*this); }
/** * 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 }