Beispiel #1
0
namespace EnginePhysics
{
	#pragma region Enums
		
		typedef enum
		{
			ZERO,			//No Gravity or other forces are applied, objects retain momentum
			NORMAL,			//Standard gravity such that all objects are pulled down
			PULL_SINGLE,	//Pulls from a single point
			PULL_DOUBLE,	//Pulls from two points
			PULL_TRIPLE,	//Pulls from three points
			PULL_PUSH,  	//Pulls from left, pushes from right
			PUSH_PULL,		//Pushes from left, pulls from right
			PLANET_GRAVITY,	//Uses planets as gravity, gravity adheres to inverse squared law, scales with distance
			ORBITS			//Applys an force tangential to the center point
		} GravityState;

	#pragma endregion

	#pragma region Defines

		#define PLANET_HEIGHT 100
		#define PLANET_NUM 1
		#define PLANE_NUM 6
		#define BLOCK_NUM 100
		#define STRONG_UNIVERSAL_GRAVITATIONAL_FORCE 200.0f
		#define WEAK_UNIVERSAL_GRAVITATIONAL_FORCE 100.0f
		#define INVERSE_SQUARE_GRAVITATIONAL_FORCE 200.0f

	#pragma endregion

	#pragma region Variables

		static PxPhysics* gPhysicsSDK = NULL;
		static PxDefaultErrorCallback gDefaultErrorCallback;
		static PxDefaultAllocator gDefaultAllocatorCallback;
		static PxSimulationFilterShader gDefaultFilterShader = PxDefaultSimulationFilterShader;

		PxScene* gScene = NULL;
		PxReal myTimestep = 1.0f/60.0f;

		vector<PhysXObject*> *allActors;
		vector<PhysXObject*> boxes;
		vector<PhysXObject*> planets;
		//vector<PxRigidActor*> planetJointHandles;
		vector<PhysXObject*> planes;

		PxTransform planePoses[6] = {
			PxTransform(PxVec3(0.0f,-PLANET_HEIGHT,0.0f), PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f))),
			PxTransform(PxVec3(0.0f,PLANET_HEIGHT,0.0f), PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, -1.0f))),
			PxTransform(PxVec3(PLANET_HEIGHT,0.0f,0.0f), PxQuat(PxPi, PxVec3(0.0f, 0.0f, 1.0f))),
			PxTransform(PxVec3(-PLANET_HEIGHT,0.0f,0.0f), PxQuat(0, PxVec3(0.0f, 0.0f, 1.0f))),
			PxTransform(PxVec3(0.0f,0.0f,PLANET_HEIGHT), PxQuat(PxHalfPi, PxVec3(0.0f, 1.0f, 0.0f))),
			PxTransform(PxVec3(0.0f,0.0f,-PLANET_HEIGHT), PxQuat(PxHalfPi, PxVec3(0.0f, -1.0f, 0.0f)))
		};

		PxTransform planetTransforms[3] = {
			PxTransform(PxVec3(0, 0, 0), PxQuat::createIdentity()),
			PxTransform(PxVec3(20, 20,20), PxQuat::createIdentity()),
			PxTransform(PxVec3(-20, -20,-20),PxQuat::createIdentity())
		};

		time_t stepTimer = -1;

		GravityState currentGravState = GravityState::ZERO;

		bool isPaused = false;

	#pragma endregion

	#pragma region Prototypes

		void DisableGravity(PxRigidActor* actor);
		void EnableGravity(PxRigidActor* actor);
		void ApplyGravity(PxRigidActor* actor, PxVec3 source, PxReal power);
		void ApplyInverseSquareGravity(PxRigidActor* actor, PxVec3 source, PxReal power);
		void UpdatePhysXObject(PhysXObject* object);
		void ResetScene();

		void ApplyZeroGravity(PhysXObject* object);
		void ApplyNormalGravity(PhysXObject* object);
		void ApplyPlanetGravity(PhysXObject* object);
		void ApplyPullDouble(PhysXObject* object);
		void ApplyPullPush(PhysXObject* object);
		void ApplyPullSingle(PhysXObject* object);
		void ApplyPullTriple(PhysXObject* object);
		void ApplyPushPull(PhysXObject* object);
		void ApplyOrbitVelocity(PxRigidActor* box, float power);
		void SetVelocity(PxVec3 newVelocity, PhysXObject* object);
		void RandomVelocities(PhysXObject* object, int powerMax, int seedMultiplier = 1);
		PxVec3 RandomOrthogonalVector(PxVec3 normal);
		PxVec3 CreateRandomVector(int maxAxisValue, int seedMultiplier = 1);

	#pragma endregion
		
	#pragma region Public Methods

		void InitializePhysX(vector<PhysXObject*>* &cubeList)
		{
			allActors = new vector<PhysXObject*>;

			PxFoundation* foundation = PxCreateFoundation(PX_PHYSICS_VERSION, 
				gDefaultAllocatorCallback, gDefaultErrorCallback);
			gPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *foundation, PxTolerancesScale());

			if(gPhysicsSDK == NULL)
			{
				exit(1);
			}

			PxInitExtensions(*gPhysicsSDK);

			PxSceneDesc sceneDesc(gPhysicsSDK->getTolerancesScale());

			sceneDesc.gravity=PxVec3(0.0f, -9.8f, 0.0f);

			if(!sceneDesc.cpuDispatcher)
			{
				PxDefaultCpuDispatcher* mCpuDispatcher = PxDefaultCpuDispatcherCreate(3);

				sceneDesc.cpuDispatcher = mCpuDispatcher;
			}

			if(!sceneDesc.filterShader)
				sceneDesc.filterShader = gDefaultFilterShader;

			gScene = gPhysicsSDK->createScene(sceneDesc);

			gScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1.0);
			gScene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1.0f);


			//1) Create Planes
			PxMaterial* mMaterial = gPhysicsSDK->createMaterial(0.5, 0.5, 0.5);

			for(int i = 0; i < 1; i++)
			{
				PhysXObject* plane = new PhysXObject;
				plane->actor = gPhysicsSDK->createRigidStatic(planePoses[i]);

				PxShape* shape = plane->actor->createShape(PxPlaneGeometry(), *mMaterial);

				gScene->addActor(*(plane->actor));
				allActors->push_back(plane);
				planes.push_back(plane);
			}

			//2) Create Planets
			PxReal planetDensity = 1.0f;
			PxVec3 planetDimensions(2,2,2);
			PxBoxGeometry planetGeom(planetDimensions);
			PxTransform planetTransform;

			for(int i = 0; i < PLANET_NUM; i++)
			{
				planetTransform = planetTransforms[i];
				PhysXObject* planet = new PhysXObject;
				planet->actor = PxCreateStatic(*gPhysicsSDK, planetTransform, planetGeom, *mMaterial);

				EnableGravity(planet->actor);

				gScene->addActor(*(planet->actor));
				allActors->push_back(planet);
				planets.push_back(planet);

				//HACK: 
				/* Create the joint handlers for distance limiting
				/* We need to do this because a distance joint attached to an actor
				/* seems to void collisions between those two actors (i.e. "phases through")
				/* So we make another actor in the same position to hold the position
			
				PhysXObject* newHandle = new PhysXObject;
				newHandle->actor = PxCreateStatic(*gPhysicsSDK, tran, boxgeom, *mMaterial);

				gScene->addActor(*(newHandle->actor));
				planetJointHandles.push_back(newHandle);
				//We also don't need to worry about drawing the joints, for obvious reasons
				*/
			}

			//3) Create Cubes
			PxReal density = 1.0f;
			PxTransform transform(PxVec3(0.0f, 0.0f, 0.0f), PxQuat::createIdentity());
			PxVec3 dimensions(0.5, 0.5, 0.5);
			PxBoxGeometry geometry(dimensions);

			for(int i = 0; i < BLOCK_NUM; i++)
			{
				srand((time(NULL) * i) + time(NULL));

				transform.p = PxVec3((float)((rand() % (2 * PLANET_HEIGHT)) - PLANET_HEIGHT),
					(float)((rand() % (2 * PLANET_HEIGHT)) - PLANET_HEIGHT),
					(float)((rand() % (2 * PLANET_HEIGHT)) - PLANET_HEIGHT));

				PhysXObject* cube = new PhysXObject;

				cube->actor = PxCreateDynamic(*gPhysicsSDK, transform, geometry, *mMaterial, density);

				//Create Distance Joints between planets here
					//Not included for run time optimizations
				//End creating distance joints

				//Create D6 Joints between planets here
					//Not included for run time optimizations
				//End creating distance joints

				cube->actor->isRigidDynamic()->setAngularDamping(0.75);
				cube->actor->isRigidDynamic()->setLinearVelocity(PxVec3(0,0,0));

				gScene->addActor(*(cube->actor));
				allActors->push_back(cube);
				boxes.push_back(cube);
			}

			cubeList = allActors;
		}

		void StepPhysX()
		{
			if(!isPaused && gScene)
			{
				for(int i = 0; i < boxes.size(); i++)
				{
					switch(currentGravState)
					{
						case GravityState::ZERO:
							ApplyZeroGravity(boxes[i]);
							break;

						case GravityState::NORMAL:
							ApplyNormalGravity(boxes[i]);
							break;
				
						case GravityState::PLANET_GRAVITY:
							ApplyPlanetGravity(boxes[i]);
							break;

						case GravityState::PULL_DOUBLE:
							ApplyPullDouble(boxes[i]);
							break;

						case GravityState::PULL_PUSH:
							ApplyPullPush(boxes[i]);
							break;

						case GravityState::PULL_SINGLE:
							ApplyPullSingle(boxes[i]);
							break;

						case GravityState::PULL_TRIPLE:
							ApplyPullTriple(boxes[i]);
							break;

						case GravityState::PUSH_PULL:
							ApplyPushPull(boxes[i]);
							break;

						case GravityState::ORBITS:
							boxes[i]->actor->isRigidDynamic()->setLinearVelocity(PxVec3(0,0,0));
							ApplyOrbitVelocity(boxes[i]->actor, 40);
							break;
					}

					UpdatePhysXObject(boxes[i]);
				}

				gScene->simulate(myTimestep);

				while(!gScene->fetchResults())
				{
					//we can do some work here while the
					//frame is simulating, but I don't have anything
					//for the moment
				}
			}
		}

		void ShutdownPhysX()
		{
			if(allActors)
			{
				for(int i = 0; i < allActors->size(); i++)
				{
					gScene->removeActor(*(*allActors)[i]->actor);
					if((*allActors)[i]->actor){(*allActors)[i]->actor->release();}
					delete (*allActors)[i];
				}

				allActors->clear();
				allActors->shrink_to_fit();
			}
			if(gScene){gScene->release();gScene=NULL;}

			if(gPhysicsSDK){gPhysicsSDK->release();gPhysicsSDK=NULL;}
		}

		void ProcessKey(unsigned char key)
		{
			switch(key)
			{
				case '0':
					currentGravState = GravityState::ZERO;
					break;

				case '1':
					currentGravState = GravityState::NORMAL;
					break;
					
				case '2':
					currentGravState = GravityState::PLANET_GRAVITY;
					for(int i = 0; i < boxes.size(); i++)
					{
						PxVec3 dir = planets[0]->actor->getGlobalPose().p - boxes[i]->actor->getGlobalPose().p;

						ApplyOrbitVelocity(boxes[i]->actor, 100);
					}
					break;

				case '3':
					currentGravState = GravityState::PULL_SINGLE;
					break;

				case '4':
					currentGravState = GravityState::PULL_DOUBLE;
					break;

				case '5':
					currentGravState = GravityState::PULL_TRIPLE;
					break;

				case '6':
					currentGravState = GravityState::PULL_PUSH;
					break;

				case '7':
					currentGravState = GravityState::PUSH_PULL;
					break;

				case '8':
					currentGravState = GravityState::ORBITS;
					break;

				case 'p':
					isPaused = !isPaused;
					break;

				case 'r':
				case ' ':
					ResetScene();
					break;

				case '\n':
				case '\r':
					{
						for(int i = 0; i < boxes.size(); i++)
						{
							SetVelocity(PxVec3(0,0,0), boxes[i]);
						}
					}
					break;

				case 'v':
					{
						for(int i = 0; i < boxes.size(); i++)
						{
							RandomVelocities(boxes[i], 50, i);
						}
					}
					break;
			}
		}

	#pragma endregion

	#pragma region Private Methods
		
		void ApplyZeroGravity(PhysXObject* object)
		{
			DisableGravity(object->actor);
		}

		void ApplyNormalGravity(PhysXObject* object)
		{
			EnableGravity(object->actor);
		}

		void ApplyPlanetGravity(PhysXObject* object)
		{
			DisableGravity(object->actor);
			for(int j = 0; j < planets.size(); j++)
			{
				ApplyInverseSquareGravity(object->actor, planets[j]->actor->getGlobalPose().p, INVERSE_SQUARE_GRAVITATIONAL_FORCE);
			}
		}

		void ApplyPullDouble(PhysXObject* object)
		{
				DisableGravity(object->actor);

				ApplyGravity(object->actor, planetTransforms[1].p, STRONG_UNIVERSAL_GRAVITATIONAL_FORCE);
				ApplyGravity(object->actor, planetTransforms[2].p, STRONG_UNIVERSAL_GRAVITATIONAL_FORCE);
		}

		void ApplyPullPush(PhysXObject* object)
		{
				DisableGravity(object->actor);
			
				ApplyGravity(object->actor, planetTransforms[0].p, STRONG_UNIVERSAL_GRAVITATIONAL_FORCE);
				ApplyGravity(object->actor, planetTransforms[2].p, -WEAK_UNIVERSAL_GRAVITATIONAL_FORCE);
		}

		void ApplyPullSingle(PhysXObject* object)
		{
				DisableGravity(object->actor);
			
				ApplyGravity(object->actor, planetTransforms[0].p, STRONG_UNIVERSAL_GRAVITATIONAL_FORCE);
		}

		void ApplyPullTriple(PhysXObject* object)
		{
				DisableGravity(object->actor);
			
				ApplyGravity(object->actor, planetTransforms[0].p, STRONG_UNIVERSAL_GRAVITATIONAL_FORCE);
				ApplyGravity(object->actor, planetTransforms[2].p, STRONG_UNIVERSAL_GRAVITATIONAL_FORCE);
				ApplyGravity(object->actor, planetTransforms[1].p, STRONG_UNIVERSAL_GRAVITATIONAL_FORCE);
		}

		void ApplyPushPull(PhysXObject* object)
		{
				DisableGravity(object->actor);
			
				ApplyGravity(object->actor, planetTransforms[0].p, -WEAK_UNIVERSAL_GRAVITATIONAL_FORCE);
				ApplyGravity(object->actor, planetTransforms[2].p, STRONG_UNIVERSAL_GRAVITATIONAL_FORCE);
		}
	
		void ApplyOrbitVelocity(PxRigidActor* box, float power)
		{
			for(int i = 0; i < planets.size(); i++)
			{
				PxVec3 dir = planets[i]->actor->getGlobalPose().p - box->getGlobalPose().p;

				dir.normalize();

				PxVec3 velocity = RandomOrthogonalVector(dir) * power;

				box->isRigidDynamic()->addForce(velocity,PxForceMode::eACCELERATION);
			}
		}

	#pragma endregion

	#pragma region Helper Methods

		void SetVelocity(PxVec3 newVelocity, PhysXObject* object)
		{
			object->actor->isRigidDynamic()->setLinearVelocity(newVelocity);
		}

		void DisableGravity(PxRigidActor* actor)
		{
			actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);
		}

		void EnableGravity(PxRigidActor* actor)
		{
			actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
		}

		void ApplyGravity(PxRigidActor* actor, PxVec3 source, PxReal power)
		{
			PxVec3 dir, norm, force;
		
			//Disables the scene gravity so we can apply our own
			DisableGravity(actor);

			dir = source - actor->getGlobalPose().p;

			norm = dir.getNormalized();

			force = (norm * power);

			actor->isRigidBody()->addForce(force, PxForceMode::eACCELERATION);
		}

		void ApplyInverseSquareGravity(PxRigidActor* actor, PxVec3 source, PxReal power)
		{
			PxVec3 dir;
			PxReal distSquared;
			PxVec3 norm;
			PxVec3 force;
			int objectNum = boxes.size();

			for(int i = 0; i < objectNum; i++)
			{
				//Disables the scene gravity so we can apply our own
				DisableGravity(boxes[i]->actor);

				dir = source - boxes[i]->actor->getGlobalPose().p;

				distSquared = dir.magnitudeSquared();
				distSquared = (distSquared < 10) ? 10000 : distSquared;

				norm = dir.getNormalized();
				force = (norm * power) / distSquared;

				boxes[i]->actor->isRigidBody()->addForce(force, PxForceMode::eACCELERATION);
			}
		}

		void UpdatePhysXObject(PhysXObject* object)
		{
			PxVec3 pos = object->actor->getGlobalPose().p;

			object->x = pos.x;
			object->y = pos.y;
			object->z = pos.z;
		}

		void ResetScene()
		{
			PxVec3 resetPosition;
			for(int i = 0; i < boxes.size(); i++)
			{
				srand((time(NULL) * i) + time(NULL));

				resetPosition = PxVec3((float)((rand() % (2 * PLANET_HEIGHT)) - PLANET_HEIGHT),
					(float)((rand() % (2 * PLANET_HEIGHT)) - PLANET_HEIGHT),
					(float)((rand() % (2 * PLANET_HEIGHT)) - PLANET_HEIGHT));

				boxes[i]->actor->isRigidDynamic()->setLinearVelocity(PxVec3(0,0,0));
				boxes[i]->actor->setGlobalPose(PxTransform(resetPosition, PxQuat::createIdentity()));
			}
		}

		void RandomVelocities(PhysXObject* object, int powerMax, int seedMultiplier)
		{
			PxVec3 dir = CreateRandomVector(powerMax, seedMultiplier);
		
			srand((time(NULL) * seedMultiplier) + time(NULL));

			int power = rand() % powerMax;

			dir.normalize();

			SetVelocity(dir * power, object);
		}

		PxVec3 RandomOrthogonalVector(PxVec3 normal)
		{
			PxVec3 random = CreateRandomVector(10);

			return random - (normal * random.dot(normal));
		}

		PxVec3 CreateRandomVector(int maxAxisValue, int seedMultiplier)
		{
			srand((time(NULL) * seedMultiplier) + time(NULL));

			return PxVec3((rand() % (2*maxAxisValue)) - maxAxisValue,
				(rand() % (2*maxAxisValue)) - maxAxisValue,
				(rand() % (2*maxAxisValue)) - maxAxisValue);
		}

	#pragma endregion

}
Beispiel #2
0
/** Convert glm::quat to Physx::PxQuat
 @param[in] quat The glm::quat
 @return Converted Physx::PxQuat */
PxQuat glmQuatToPhysXQuat(const glm::quat& quat)
{
	return PxQuat(quat.x, quat.y, quat.z, quat.w);
}
	//
	// 创建物理场景
	//
	BOOL CSceneManager::CreatePhysicsScene(VOID)
	{
		for (EntityMap::const_iterator itEntity = m_meshs.begin(); itEntity != m_meshs.end(); ++itEntity) {
			const CEntityMesh *pEntityMesh = (const CEntityMesh *)itEntity->second;
			ASSERT(pEntityMesh);

			const CSubMesh *pPhysicsMesh = pEntityMesh->GetPhysicsSubMesh();
			if (pPhysicsMesh == NULL) continue;
			if (pEntityMesh->IsEnablePhysicsQuery() == FALSE && pEntityMesh->IsEnablePhysicsSimulation() == FALSE) continue;

			const VEC3 *position = pEntityMesh->GetSceneNode()->GetWorldPosition();
			const QUAT *orientation = pEntityMesh->GetSceneNode()->GetWorldOrientation();
			const PxTransform pxLocalPose(PxVec3(0.0f, 0.0f, 0.0f));
			const PxTransform pxGlobalPose(PxVec3((*position)[0], (*position)[1], (*position)[2]), PxQuat((*orientation)[0], (*orientation)[1], (*orientation)[2], (*orientation)[3]));

			const PxMaterial &pxMaterial = GetPhysicsStandardMaterial((MATERIAL_TYPE)pEntityMesh->GetPhysicsMaterial()->GetPhysics()->GetType());
			const PxFilterData pxQueryFilterData = PxFilterData(QUERY_FLAGS_SCENE_MESH, 0, 0, 0);
			const PxFilterData pxSimulationFilterData = PxFilterData(SIMULATION_FLAGS_WORD0[pEntityMesh->GetPhysicsSimulationTypeIndex()], SIMULATION_FLAGS_WORD1[pEntityMesh->GetPhysicsSimulationTypeIndex()], 0, 0);

			PxRigidActor *pPxRigidActor = (PxRigidActor *)m_physics.CreateRigidActor(pEntityMesh->GetSceneNode()->GetName(), pxGlobalPose, FALSE, TRUE, TRUE);
			PxShape *pPxShape = PxCreateShapeMesh(pPxRigidActor, pPhysicsMesh->GetVertexBuffer(), pPhysicsMesh->GetVertexCount(), pPhysicsMesh->GetFaceBuffer(), pPhysicsMesh->GetFaceCount(), pxMaterial, pxLocalPose, pEntityMesh->IsEnablePhysicsQuery(), pEntityMesh->IsEnablePhysicsSimulation(), pxQueryFilterData, pxSimulationFilterData);
			pPxShape->userData = pEntityMesh->userData;
		}

		return TRUE;
	}
Beispiel #4
0
void CurrentApp::LoadContent()
{
	// setup gpass framebuffer
	m_gPassTarget = new RenderTarget();
	m_gPassTarget->SetSize(1280, 720);
	m_gPassTarget->Initialise();
	m_gPassTarget->AttachColourBuffer(0, GL_RGB8); //albedo
	m_gPassTarget->AttachColourBuffer(1, GL_RGB32F); //position
	m_gPassTarget->AttachColourBuffer(2, GL_RGB32F); //normal
	m_gPassTarget->AttachDepthBuffer();
	m_gPassTarget->SetDrawBuffers();

	// setup light framebuffer
	m_lightPassTarget = new RenderTarget();
	m_lightPassTarget->SetSize(1280, 720);
	m_lightPassTarget->Initialise();
	m_lightPassTarget->AttachColourBuffer(0, GL_RGB8);
	m_lightPassTarget->AttachDepthBuffer();
	m_lightPassTarget->SetDrawBuffers();

	CreateFullscreenQuad();

	//Setting up Physx
	m_gravity = -9.8f;
	SetupPhysx();
	SetupVisualDebugger();

	//Set up a Player
	g_ControllerManager = PxCreateControllerManager(*g_PhysicsScene);
	PxCapsuleControllerDesc desc;
	desc.contactOffset = 0.05f;
	desc.height = 3.0f;
	desc.material = g_PhysicsMaterial;
	desc.nonWalkableMode = PxControllerNonWalkableMode::ePREVENT_CLIMBING_AND_FORCE_SLIDING;
	desc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED;
	desc.position = PxExtendedVec3(100, 200, 150);
	desc.radius = 2.0f;
	desc.stepOffset = 0.1f;
	g_PlayerCollisions = new PlayerCollisions();
	desc.reportCallback = g_PlayerCollisions;
	g_PlayerController = g_ControllerManager->createController(desc);

	//Create a New Camera
	m_camera = new FlyCamera();
	m_camera->SetupProjection(glm::pi<float>() * 0.25f, 16 / 9.f, 0.1f, 10000.f);
	m_camera->LookAt(vec3(100, 10, 10), vec3(0), vec3(0, 1, 0));

	m_assetManager = new AssetManager();

	m_renderer = new Renderer(m_assetManager);

	//Terrain Shit here
	m_terrain = m_renderer->CreateTerrain();
	m_terrain->SetSize(30, 30);
	m_terrain->GenerateFromPerlin();

	m_nodeMap = new NodeMap();
	m_nodeMap->GenerateFromTerrain(m_terrain);

	////Snow Particle
	m_snowEmitter = m_renderer->CreateParticle();
	m_snowEmitter->ReadFile("./Content/Particles/Rain");
	//m_snowEmitter->UseTexture("./Content/Particles/ROBOTUNICORN.png");
	m_snowEmitter->SetPosition(glm::vec3(150, 400, 150));
	m_snowEmitter->initalise("");

	m_fairyEmitter = m_renderer->CreateParticle();
	m_fairyEmitter->ReadFile("./Content/Particles/fairy");
	m_fairyEmitter->SetPosition(glm::vec3(100, 130, 100));
	m_fairyEmitter->initalise("");

	//Load Renderables
	int cubeModel = m_assetManager->LoadModel("./Content/Renderables/cube.fbx");
	int sphereModel = m_assetManager->LoadModel("./Content/Renderables/cube.fbx");
	int bunnyModel = m_assetManager->LoadModel("./Content/Renderables/bunny.fbx");
	int treeModel = m_assetManager->LoadModel("./Content/Renderables/Tree/AlanTree.fbx");
	//m_assetManager->RecalculateNormals(treeModel);

	//LoadSkybox
	m_skybox = new Skybox(); 

	std::vector<std::string> faces;

	faces.push_back("./Content/Textures/skyRight.png");
	faces.push_back("./Content/Textures/skyLeft.png");
	faces.push_back("./Content/Textures/skyTop.png");
	faces.push_back("./Content/Textures/skyBottom.png");
	faces.push_back("./Content/Textures/skyFront.png");
	faces.push_back("./Content/Textures/skyBack.png");

	m_skybox->Initialize(faces);

	//Load AI
	m_world = new World(m_nodeMap);

	//Load Lights
	m_light = m_renderer->CreateLight();
	m_light->SetColour(glm::vec4(200, 255, 255, 1));
	m_light->SetFallOff(200000);
	m_light->SetPosition(glm::vec3(150, 30, 150));

	m_sunLight = m_renderer->CreateLight();
	m_sunLight->SetColour(glm::vec4(50, 50, 80, 1));
	m_sunLight->SetFallOff(1000000);
	m_sunLight->SetPosition(glm::vec3(0, 200, 0));

	//create our particle system
	PxParticleFluid* pf;
	// create particle system in PhysX SDK
	// set immutable properties.
	PxU32 maxParticles = 200;
	bool perParticleRestOffset = false;
	pf = g_Physics->createParticleFluid(maxParticles, perParticleRestOffset);
	pf->setRestParticleDistance(3.0f);
	pf->setDynamicFriction(0);
	pf->setStaticFriction(0);
	pf->setDamping(0);
	pf->setParticleMass(30);
	pf->setRestitution(0);
	//pf->setParticleReadDataFlag(PxParticleReadDataFlag::eDENSITY_BUFFER,
	// true);
	pf->setParticleBaseFlag(PxParticleBaseFlag::eCOLLISION_TWOWAY, true);
	pf->setStiffness(300);
	if (pf)
	{
		float multiplier = 10.0f;

		g_PhysicsScene->addActor(*pf);
		m_particleEmitter = new ParticleFluidEmitter(maxParticles, PxVec3(150, 120, 150), pf, .05f);
		m_particleEmitter->setStartVelocityRange(-0.001f, -6000.0f * multiplier, -0.001f, 0.001f, -6000.0f * multiplier, 0.001f);
	}

	for (int i = 0; i < 5; ++i)
	{
		m_AI[i] = new UtilityAI(m_assetManager, m_world, m_nodeMap);
		Renderable* renderBox = m_renderer->CreateRenderable();
		renderBox->SetModel(bunnyModel);
		renderBox->SetScale(glm::vec3(0.01f, 0.01f, 0.01f));
		renderBox->SetTexture(LoadTexture("./Content/Renderables/white.png"));
		m_AI[i]->SetRenderable(renderBox);
	}

	for (int i = 0; i < 50; ++i)
	{
		m_trees[i] = m_renderer->CreateRenderable();
		m_trees[i]->SetModel(treeModel);

		glm::vec3 position = m_nodeMap->GetClosestNode(glm::vec3(40 + rand() % 220, 40 + rand() % 220, 40 + rand() % 220))->GetPos();
		position.y -= 1;
		m_trees[i]->SetPosition(position);

		m_trees[i]->Rotate(glm::vec3(1, 0, 0), -(3.14159265f / 2.0f));
		m_trees[i]->Rotate(glm::vec3(0, 0, 1), rand() % 200 / 100.0f);

		float randVal = rand() % 120 / 120.f;
		m_trees[i]->SetScale(glm::vec3(0.2f + randVal, 0.2f + randVal, 0.2f + randVal));
	}
	
	//Define a Plane
	PxTransform pose = PxTransform(PxVec3(0.0f, 5, 0.0f), PxQuat(PxHalfPi*1.0f, PxVec3(0.0f, 0.0f, 1.0f)));
	PxRigidStatic* plane = PxCreateStatic(*g_Physics, pose, PxPlaneGeometry(), *g_PhysicsMaterial);

	//Add the plane to the Physx Scene
	g_PhysicsScene->addActor(*plane);
	m_terrain->AddPhysicsShape(g_PhysicsScene, g_Physics);

	//Disable the mouse
	SetCursorPos(0, 0);
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}