From 3e403681a3517557819a14fc052c8f1374affa54 Mon Sep 17 00:00:00 2001
From: "Grayson Riffe (Laptop)" <graysonriffe@yahoo.com>
Date: Tue, 2 Nov 2021 01:41:42 -0500
Subject: [PATCH] Added physics-related functions to Entity and mouse clicks vs
 holds

---
 Game/src/MainState.cpp                  | 31 ++++++++++--
 Game/src/include/MainState.h            |  3 ++
 NothinFancy/src/Application.cpp         | 52 +++++++++++++++++---
 NothinFancy/src/Gamestate.cpp           | 18 +++++--
 NothinFancy/src/NFObject/Button.cpp     |  2 +-
 NothinFancy/src/NFObject/Entity.cpp     | 12 +++++
 NothinFancy/src/PhysicsEngine.cpp       | 64 ++++++++++++++++++-------
 NothinFancy/src/Renderer/Renderer.cpp   |  2 +-
 NothinFancy/src/include/Application.h   |  5 +-
 NothinFancy/src/include/Entity.h        | 13 +++--
 NothinFancy/src/include/Gamestate.h     | 13 +++--
 NothinFancy/src/include/PhysicsEngine.h |  5 ++
 12 files changed, 174 insertions(+), 46 deletions(-)

diff --git a/Game/src/MainState.cpp b/Game/src/MainState.cpp
index ba64f2a..8c318d3 100644
--- a/Game/src/MainState.cpp
+++ b/Game/src/MainState.cpp
@@ -9,8 +9,9 @@ void MainState::onEnter() {
 	test.setPosition(nf::Vec3(0.0, 1.5, -5.0));
 	plane.create(nf::BaseAssets::plane);
 	plane.setScale(20.0);
-	text.create("This is a test text.", nf::Vec2(0.1, 0.025), nf::Vec3(0.8));
+	text.create("", nf::Vec2(0.1, 0.025), nf::Vec3(0.8));
 	text.centered(true);
+	gravText.create("", nf::Vec2(0.025, 0.2), nf::Vec3(0.8), 1.0f, 0.5f);
 	uiTex.create(nf::BaseAssets::logo, nf::Vec2(0.025, 0.025), 0.5);
 	button.create(nf::Vec2(0.8, 0.025), "Reset");
 	button2.create(nf::Vec2(0.6, 0.025), "Play Sound");
@@ -29,12 +30,15 @@ void MainState::onEnter() {
 		for (int y = 0; y < 5; y++) {
 			for (int z = 0; z < 5; z++) {
 				entities.push_back(new nf::Entity);
-				entities.back()->create(nf::BaseAssets::sphere, nf::Entity::Type::DYNAMIC);
+				entities.back()->create(ap["2mats.obj"], nf::Entity::Type::DYNAMIC);
 				entities.back()->setPosition(nf::Vec3(5.0 + x * 2.05, 1.0 + y * 2.05, -5.0 + z * 2.05));
 			}
 		}
 	}
 
+	grav = 2.0f;
+	setGravity(grav);
+
 	camera->setPosition(-20.0, 5.0, 0.0);
 	camera->setRotation(85.0, 0.0);
 }
@@ -76,12 +80,28 @@ void MainState::update(float deltaTime) {
 		sound2.stop();
 	}
 
-	if (app->isKeyPressed(NFI_K)) {
+	if (app->isMouseClicked(NFI_LEFTMOUSE) || app->isMouseHeld(NFI_RIGHTMOUSE)) {
 		entities.push_back(new nf::Entity);
-		entities.back()->create(ap["2mats.obj"], nf::Entity::Type::DYNAMIC);
-		entities.back()->setPosition(camera->getPosition());
+		entities.back()->create(nf::BaseAssets::sphere, nf::Entity::Type::DYNAMIC);
+		entities.back()->setPosition(camera->getPosition() + camera->getRotation() * 5.0);
+		entities.back()->setVelocity(camera->getRotation() * 100.0f);
+		entities.back()->setMass(1000.0f);
 	}
 
+	if (app->isKeyHeld(NFI_UP)) {
+		grav += 0.05f;
+		setGravity(grav);
+	}
+	if (app->isKeyHeld(NFI_DOWN)) {
+		grav -= 0.05f;
+		setGravity(grav);
+	}
+	if (app->isKeyPressed(NFI_T)) {
+		grav = 1.0f;
+		setGravity(1.0f);
+	}
+	gravText.setText("Gravity Scale: " + std::to_string(grav));
+
 	if (app->isKeyPressed(NFI_ESCAPE))
 		app->quit();
 }
@@ -93,6 +113,7 @@ void MainState::render(nf::Renderer& renderer) {
 	renderer.render(light2);
 	renderer.render(light3);
 	renderer.render(text);
+	renderer.render(gravText);
 	renderer.render(uiTex);
 	renderer.render(button);
 	renderer.render(button2);
diff --git a/Game/src/include/MainState.h b/Game/src/include/MainState.h
index f03adfd..b79fdcd 100644
--- a/Game/src/include/MainState.h
+++ b/Game/src/include/MainState.h
@@ -16,6 +16,7 @@ private:
 	nf::Entity test;
 	nf::Entity plane;
 	nf::Text text;
+	nf::Text gravText;
 	nf::UITexture uiTex;
 	nf::Button button;
 	nf::Button button2;
@@ -27,5 +28,7 @@ private:
 	nf::Sound sound;
 	nf::Sound sound2;
 
+	float grav;
+
 	std::vector<nf::Entity*> entities;
 };
\ No newline at end of file
diff --git a/NothinFancy/src/Application.cpp b/NothinFancy/src/Application.cpp
index 9cf67e7..81af94c 100644
--- a/NothinFancy/src/Application.cpp
+++ b/NothinFancy/src/Application.cpp
@@ -159,16 +159,24 @@ namespace nf {
 	}
 
 	bool Application::isKeyPressed(unsigned int code) {
-		if (code > 7 && code < 164) {
-			if (m_keysPressed[code]) {
-				m_keysPressed[code] = false;
+		if (code > 7 && code < 164)
+			if (m_inputPressed[code]) {
+				m_inputPressed[code] = false;
 				return true;
 			}
-		}
 		return false;
 	}
 
-	bool Application::isMouse(unsigned int code) {
+	bool Application::isMouseClicked(unsigned int code) {
+		if (code < 7)
+			if (m_inputPressed[code]) {
+				m_inputPressed[code] = false;
+				return true;
+			}
+		return false;
+	}
+
+	bool Application::isMouseHeld(unsigned int code) {
 		if (code < 7 && GetForegroundWindow() == m_window)
 			return GetKeyState(code) & 0x8000;
 		return false;
@@ -385,12 +393,42 @@ namespace nf {
 			}
 			case WM_KEYDOWN: {
 				if (wParam < 164 && !(lParam & (1 << 30)) && GetFocus() == hWnd)
-					app->m_keysPressed[wParam] = true;
+					app->m_inputPressed[wParam] = true;
 				return 0;
 			}
 			case WM_KEYUP: {
 				if (wParam < 164 && GetFocus() == hWnd)
-					app->m_keysPressed[wParam] = false;
+					app->m_inputPressed[wParam] = false;
+				return 0;
+			}
+			case WM_LBUTTONDOWN: {
+				if (GetFocus() == hWnd)
+					app->m_inputPressed[1] = true;
+				return 0;
+			}
+			case WM_LBUTTONUP: {
+				if (GetFocus() == hWnd)
+					app->m_inputPressed[1] = false;
+				return 0;
+			}
+			case WM_RBUTTONDOWN: {
+				if (GetFocus() == hWnd)
+					app->m_inputPressed[2] = true;
+				return 0;
+			}
+			case WM_RBUTTONUP: {
+				if (GetFocus() == hWnd)
+					app->m_inputPressed[2] = false;
+				return 0;
+			}
+			case WM_MBUTTONDOWN: {
+				if (GetFocus() == hWnd)
+					app->m_inputPressed[4] = true;
+				return 0;
+			}
+			case WM_MBUTTONUP: {
+				if (GetFocus() == hWnd)
+					app->m_inputPressed[4] = false;
 				return 0;
 			}
 			case WM_SETCURSOR: {
diff --git a/NothinFancy/src/Gamestate.cpp b/NothinFancy/src/Gamestate.cpp
index 118343a..91b2b27 100644
--- a/NothinFancy/src/Gamestate.cpp
+++ b/NothinFancy/src/Gamestate.cpp
@@ -30,10 +30,6 @@ namespace nf {
 		m_running = true;
 	}
 
-	void Gamestate::onEnter() {
-
-	}
-
 	bool Gamestate::isRunning() {
 		return m_running;
 	}
@@ -42,16 +38,28 @@ namespace nf {
 		return m_loading;
 	}
 
+	void Gamestate::onEnter() {
+
+	}
+
 	void Gamestate::update(float deltaTime) {
 
 	}
 
+	void Gamestate::render(Renderer& renderer) {
+
+	}
+
 	Camera* Gamestate::getCamera() {
 		return camera;
 	}
 
-	void Gamestate::render(Renderer& renderer) {
+	void Gamestate::setGravity(const Vec3& gravity) {
+		app->getPhysicsEngine()->setGravity(gravity * 9.81f);
+	}
 
+	void Gamestate::setGravity(float strength) {
+		app->getPhysicsEngine()->setGravity(Vec3(0.0f, -9.81f * strength, 0.0f));
 	}
 
 	void Gamestate::onExit() {
diff --git a/NothinFancy/src/NFObject/Button.cpp b/NothinFancy/src/NFObject/Button.cpp
index 7fe6c0e..e5ec3d3 100644
--- a/NothinFancy/src/NFObject/Button.cpp
+++ b/NothinFancy/src/NFObject/Button.cpp
@@ -84,7 +84,7 @@ namespace nf {
 		m_triggered = false;
 		if (mousePos.x >= posX && mousePos.x <= posX + width && mousePos.y <= windowHeight - posY && mousePos.y >= (windowHeight - posY) - height) {
 			m_currentTexture = m_hoverTexture;
-			if (app->isMouse(NFI_LEFTMOUSE))
+			if (app->isMouseHeld(NFI_LEFTMOUSE))
 				m_clicked = true;
 			else if (m_clicked) {
 				m_triggered = true;
diff --git a/NothinFancy/src/NFObject/Entity.cpp b/NothinFancy/src/NFObject/Entity.cpp
index a87f529..33d2a1a 100644
--- a/NothinFancy/src/NFObject/Entity.cpp
+++ b/NothinFancy/src/NFObject/Entity.cpp
@@ -102,6 +102,18 @@ namespace nf {
 		m_update = true;
 	}
 
+	void Entity::setVelocity(float x, float y, float z) {
+		setVelocity(Vec3(x, y, z));
+	}
+
+	void Entity::setVelocity(const Vec3& velocity) {
+		Application::getApp()->getPhysicsEngine()->setActorVelocity(this, velocity);
+	}
+
+	void Entity::setMass(float mass) {
+		Application::getApp()->getPhysicsEngine()->setActorMass(this, mass);
+	}
+
 	bool Entity::needsPhysicsUpdate() {
 		if (m_update) {
 			m_update = false;
diff --git a/NothinFancy/src/PhysicsEngine.cpp b/NothinFancy/src/PhysicsEngine.cpp
index 2739c28..e91667d 100644
--- a/NothinFancy/src/PhysicsEngine.cpp
+++ b/NothinFancy/src/PhysicsEngine.cpp
@@ -3,7 +3,6 @@
 #include "Application.h"
 #include "Entity.h"
 #include "Model.h"
-#include "Utility.h"
 
 //Remove this
 #include "Input.h"
@@ -79,6 +78,52 @@ namespace nf {
 		m_scene->addActor(*ground);
 	}
 
+	void PhysicsEngine::setGravity(const Vec3& grav) {
+		if (m_scene) {
+			m_scene->setGravity(PxVec3(grav.x, grav.y, grav.z));
+
+			unsigned int count = m_scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
+			PxActor** actors = new PxActor * [count];
+			m_scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC, actors, count);
+
+			for (unsigned int i = 0; i < count; i++) {
+				if (((PxRigidDynamic*)actors[i])->isSleeping())
+					((PxRigidDynamic*)actors[i])->wakeUp();
+			}
+			delete[] actors;
+		}
+	}
+
+	void PhysicsEngine::setActorVelocity(Entity* ent, const Vec3& vel) {
+		unsigned int count = m_scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
+		PxActor** actors = new PxActor * [count];
+		m_scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC, actors, count);
+
+		for (unsigned int i = 0; i < count; i++) {
+			Entity* curr = (Entity*)actors[i]->userData;
+			if (curr == ent) {
+				((PxRigidDynamic*)actors[i])->setLinearVelocity(PxVec3(vel.x, vel.y, vel.z), true);
+				break;
+			}
+		}
+		delete[] actors;
+	}
+
+	void PhysicsEngine::setActorMass(Entity* ent, float mass) {
+		unsigned int count = m_scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
+		PxActor** actors = new PxActor * [count];
+		m_scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC, actors, count);
+
+		for (unsigned int i = 0; i < count; i++) {
+			Entity* curr = (Entity*)actors[i]->userData;
+			if (curr == ent) {
+				((PxRigidDynamic*)actors[i])->setMass(mass);
+				break;
+			}
+		}
+		delete[] actors;
+	}
+
 	void PhysicsEngine::update(float dt) {
 		if (!m_scene || !m_scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC)) return;
 
@@ -86,21 +131,7 @@ namespace nf {
 		PxActor** actors = new PxActor*[count];
 		m_scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, actors, count);
 
-		if (m_app->isMouse(NFI_LEFTMOUSE)) {
-			Vec3 pos = m_app->getCurrentState()->getCamera()->getPosition();
-			PxVec3 camPos(pos.x, pos.y, pos.z);
-			PxQuat q(PxIdentity);
-			((PxRigidDynamic*)actors[1])->setGlobalPose(PxTransform(camPos, q));
-
-			Vec3 camDir = m_app->getCurrentState()->getCamera()->getRotation();
-			float speed = 100.0f;
-			PxRigidBodyExt::updateMassAndInertia(*(PxRigidDynamic*)actors[1], 1000.0);
-			((PxRigidDynamic*)actors[1])->setAngularVelocity(PxVec3(0.0));
-			((PxRigidDynamic*)actors[1])->setLinearVelocity(PxVec3(camDir.x * speed, camDir.y * speed, camDir.z * speed));
-		}
-
-		//TODO: CHANGE THIS 1 TO A 0!!!!
-
+		//Starting at 1 since 0 is the ground plane
 		for (unsigned int i = 1; i < count; i++) {
 			Entity* currEnt = (Entity*)actors[i]->userData;
 			if (!currEnt->needsPhysicsUpdate()) continue;
@@ -193,7 +224,6 @@ namespace nf {
 				else
 					it++;
 			}
-
 			m_scene->release();
 			m_scene = nullptr;
 		}
diff --git a/NothinFancy/src/Renderer/Renderer.cpp b/NothinFancy/src/Renderer/Renderer.cpp
index eaf4e77..d80acf6 100644
--- a/NothinFancy/src/Renderer/Renderer.cpp
+++ b/NothinFancy/src/Renderer/Renderer.cpp
@@ -157,7 +157,7 @@ namespace nf {
 		glBindFramebuffer(GL_FRAMEBUFFER, 0);
 		glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height);
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-		glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 10000.0f);
+		glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 1000.0f);
 		camera->bind(m_gBufferShader, m_lightingShader, m_cubemapShader);
 
 		//First, fill the gBuffer with entities
diff --git a/NothinFancy/src/include/Application.h b/NothinFancy/src/include/Application.h
index f4e6239..0800e90 100644
--- a/NothinFancy/src/include/Application.h
+++ b/NothinFancy/src/include/Application.h
@@ -40,7 +40,8 @@ namespace nf {
 		int getFPS() const;
 		bool isKeyHeld(unsigned int code);
 		bool isKeyPressed(unsigned int code);
-		bool isMouse(unsigned int code);
+		bool isMouseClicked(unsigned int code);
+		bool isMouseHeld(unsigned int code);
 		void trackMouse(bool track);
 		void getMouseDiff(int& x, int& y);
 		Vec2 getMousePos();
@@ -90,7 +91,7 @@ namespace nf {
 		bool m_stateChangeStarted;
 
 		//Array of booleans that represent keyboard and mouse input minus the scrollwheel
-		std::array<bool, 164> m_keysPressed;
+		std::array<bool, 164> m_inputPressed;
 		unsigned int m_mouseX, m_mouseY;
 		bool m_trackingMouse;
 		bool m_mouseTrackFirst;
diff --git a/NothinFancy/src/include/Entity.h b/NothinFancy/src/include/Entity.h
index 53f58b8..ad7adfd 100644
--- a/NothinFancy/src/include/Entity.h
+++ b/NothinFancy/src/include/Entity.h
@@ -27,19 +27,24 @@ namespace nf {
 
 		void setPosition(float x, float y, float z);
 		void setPosition(const Vec3& position);
-		void setPositionPhysics(const Vec3& position);
 		void setRotation(float x, float y, float z);
 		void setRotation(const Vec3& rotation);
-		void setRotationPhysics(const Vec4& rotation);
-		void setScale(float x);
 		void setScale(float x, float y, float z);
 		void setScale(const Vec3& scale);
+		void setScale(float x);
 
-		bool needsPhysicsUpdate();
+		void setVelocity(float x, float y, float z);
+		void setVelocity(const Vec3& velocity);
+
+		void setMass(float mass);
 
 		const Vec3& getPosition();
 		const Vec4& getRotation();
 		const Vec3& getScale();
+
+		void setPositionPhysics(const Vec3& position);
+		void setRotationPhysics(const Vec4& rotation);
+		bool needsPhysicsUpdate();
 		void render(Shader* shader, bool onlyDepth);
 		Model* getModel() const;
 #ifdef NFENGINE
diff --git a/NothinFancy/src/include/Gamestate.h b/NothinFancy/src/include/Gamestate.h
index 39864aa..5d90ee0 100644
--- a/NothinFancy/src/include/Gamestate.h
+++ b/NothinFancy/src/include/Gamestate.h
@@ -16,18 +16,23 @@ namespace nf {
 	class Gamestate {
 	public:
 		Gamestate();
-
+		//TODO: Add this to other objects
 		Gamestate(const Gamestate& other) = delete;
 
-		virtual void onEnter();
+		void run(Application* app, bool physics = true);
 		bool isRunning();
 		bool isLoading();
-		void run(Application* app, bool physics = true);
+
+		virtual void onEnter();
 
 		virtual void update(float deltaTime);
-		Camera* getCamera();
 		virtual void render(Renderer& renderer);
 
+		Camera* getCamera();
+		//In units of Earth gravity (9.81 m/s^2)
+		void setGravity(const Vec3& gravity);
+		void setGravity(float strength);
+
 		virtual void onExit();
 		void stop();
 
diff --git a/NothinFancy/src/include/PhysicsEngine.h b/NothinFancy/src/include/PhysicsEngine.h
index df23710..6670315 100644
--- a/NothinFancy/src/include/PhysicsEngine.h
+++ b/NothinFancy/src/include/PhysicsEngine.h
@@ -3,6 +3,8 @@
 #include <PxConfig.h>
 #include <PxPhysicsAPI.h>
 
+#include "Utility.h"
+
 using namespace physx;
 
 namespace nf {
@@ -15,6 +17,9 @@ namespace nf {
 		PhysicsEngine(Application* app);
 
 		void newScene();
+		void setGravity(const Vec3& grav);
+		void setActorVelocity(Entity* ent, const Vec3& vel);
+		void setActorMass(Entity* ent, float mass);
 		void update(float dt);
 		void addMesh(Model* model, std::vector<float>& vertices);
 		void addActor(Entity* entity);