Beispiel #1
0
/** 
*	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;
}
Beispiel #3
0
//------------------------------------------------------------------------------
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
}