Browse Source

stable push before angle correction

vlod 1 year ago
parent
commit
4b9ac54fde

+ 17 - 9
Pika/gameplay/containers/physicsTest/physicsTest.h

@@ -51,7 +51,7 @@ struct PhysicsTest: public Container
 				physicsEngine.bodies.back().motionState.rotation = ((rand() % 800) / 800.f) * 3.14159f;
 			}
 
-			for (int j = 0; j < 1; j++)
+			for (int j = 0; j < 2; j++)
 			{
 				float r = rand() % 35 + 10;
 
@@ -63,7 +63,7 @@ struct PhysicsTest: public Container
 		//physicsEngine.addBody({500, 1100}, 
 		//	ph2d::createBoxCollider({1100, 10}));
 
-		//physicsEngine.addBody({500, 500}, ph2d::createBoxCollider({300, 300}));
+		physicsEngine.addBody({500, 500}, ph2d::createBoxCollider({300, 100}));
 		//physicsEngine.addBody({700, 700}, ph2d::createBoxCollider({300, 300}));
 
 
@@ -72,7 +72,7 @@ struct PhysicsTest: public Container
 
 		//physicsEngine.addBody({500, 500}, ph2d::createCircleCollider({75}));
 		//physicsEngine.addBody({800, 100}, ph2d::createCircleCollider({55}));
-		physicsEngine.addBody({900, 500}, ph2d::createCircleCollider({40}));
+		//physicsEngine.addBody({900, 500}, ph2d::createCircleCollider({40}));
 		//physicsEngine.addBody({550, 700}, ph2d::createCircleCollider({25}));
 
 		//physicsEngine.addBody({600, 600}, ph2d::createBoxCollider({50, 50}));
@@ -91,7 +91,7 @@ struct PhysicsTest: public Container
 		//std::cout << ph2d::rotationToVector(ph2d::vectorToRotation({0,-1})).x << " " << ph2d::rotationToVector(ph2d::vectorToRotation({0,-1})).y << "\n";
 		//std::cout << ph2d::rotationToVector(ph2d::vectorToRotation({1,0}) ).x << " " << ph2d::rotationToVector(ph2d::vectorToRotation({1,0}) ).y  << "\n";
 
-		physicsEngine.addHalfSpaceStaticObject({0, floorPos}, {0.2, 1});
+		physicsEngine.addHalfSpaceStaticObject({0, floorPos}, {0.0, 1});
 		//physicsEngine.addBody({500, floorPos}, ph2d::createBoxCollider({900, 50}));
 		//physicsEngine.bodies.back().motionState.mass = 0;
 		//physicsEngine.bodies.back().motionState.momentOfInertia = 0;
@@ -154,6 +154,10 @@ struct PhysicsTest: public Container
 		ImGui::SliderAngle("angular velocity", &physicsEngine.bodies[0].motionState.angularVelocity);
 		//physicsEngine.bodies[0].motionState.angularVelocity = 1.5;
 
+		ImGui::Text("Mouse pos %d, %d", input.mouseX, input.mouseY);
+
+		ImGui::Text("Y min pos %f", physicsEngine.bodies[0].getAABB().min().y);
+
 		ImGui::Checkbox("Simulate", &simulate);
 
 		ImGui::End();
@@ -164,7 +168,7 @@ struct PhysicsTest: public Container
 		//mouse
 		if (!simulate)
 		{
-			physicsEngine.bodies[0].motionState.setPos({input.mouseX, input.mouseY});
+			//physicsEngine.bodies[0].motionState.setPos({input.mouseX, input.mouseY});
 		}
 
 		static glm::vec2 pressedPosition = {};
@@ -175,9 +179,7 @@ struct PhysicsTest: public Container
 
 			for (int i = 0; i < physicsEngine.bodies.size(); i++)
 			{
-				if (OBBvsPoint(physicsEngine.bodies[i].getAABB(),
-					physicsEngine.bodies[i].motionState.rotation,
-					{input.mouseX, input.mouseY}))
+				if (physicsEngine.bodies[i].intersectPoint({input.mouseX, input.mouseY}))
 				{
 					selected = i;
 					pressedPosition = {input.mouseX, input.mouseY};
@@ -336,7 +338,6 @@ struct PhysicsTest: public Container
 		ImGui::Text("Penetration: %f", p);
 		ImGui::End();
 
-
 		for (int i = 0; i < physicsEngine.bodies.size(); i++)
 		{
 			auto &b = physicsEngine.bodies[i];
@@ -358,6 +359,13 @@ struct PhysicsTest: public Container
 				color = Colors_Red;
 			}
 
+			//if (OBBvsPoint(physicsEngine.bodies[i].getAABB(),
+			//	physicsEngine.bodies[i].motionState.rotation,
+			//	{input.mouseX, input.mouseY}))
+			//{
+			//	color = Colors_Blue;
+			//}
+
 			if (b.collider.type == ph2d::ColliderCircle)
 			{
 				renderer.renderCircleOutline(b.motionState.pos,

+ 5 - 2
Pika/resources/logs.txt

@@ -1,2 +1,5 @@
-#2024-11-21 18:35:18: Created container: PhysicsTest
-#2024-11-21 18:35:27: Destroyed continer: PhysicsTest #1
+#2024-11-22 10:56:05: Created container: PhysicsTest
+#2024-11-22 11:02:20: Reloaded dll
+#2024-11-22 11:02:55: Reloaded dll
+#2024-11-22 11:08:07: Reloaded dll
+#2024-11-22 11:13:02: Destroyed continer: PhysicsTest #1

+ 6 - 0
Pika/thirdparty/ph2d/include/ph2d/ph2d.h

@@ -14,6 +14,8 @@
 // that means position x, position y; size x, size y.
 // you can easily convert from a vec4 to an aabb and back
 
+#pragma once
+
 #undef min
 #undef max
 
@@ -247,7 +249,11 @@ namespace ph2d
 
 		AABB getAABB();
 
+		bool isHalfPlane();
+
 		bool intersectPoint(glm::vec2 p, float delta = 0);
+
+		LineEquation getLineEquationForHalfPlaneColliders();
 	};
 
 	bool BodyvsBody(Body &A, Body &B, float &penetration,

+ 73 - 3
Pika/thirdparty/ph2d/src/ph2d.cpp

@@ -1,3 +1,4 @@
+#include "ph2d/ph2d.h"
 //////////////////////////////////////////////////
 //ph2d.h				0.0.1
 //Copyright(c) 2024 Luta Vlad - Low Level Game Dev
@@ -19,7 +20,10 @@
 #include <iostream>
 #include <algorithm>
 
+//todo per engine
 constexpr static float MAX_VELOCITY = 10'000;
+constexpr static float MIN_VELOCITY = 0.1;
+constexpr static float MIN_ANGULAR_VELOCITY = 0.01;
 constexpr static float MAX_ACCELERATION = 10'000;
 constexpr static float MAX_AIR_DRAG = 100;
 
@@ -40,6 +44,19 @@ void normalizeSafe(glm::vec2 &v)
 namespace ph2d
 {
 
+
+	LineEquation Body::getLineEquationForHalfPlaneColliders()
+	{
+		if (collider.type != ColliderHalfSpace) { return {}; }
+
+		LineEquation lineEquation;
+		lineEquation.createFromRotationAndPoint(motionState.rotation,
+			motionState.pos);
+
+		return lineEquation;
+	}
+
+
 	void AABB::rotateAroundCenter(float r)
 	{
 		glm::vec2 newCenter = ph2d::rotateAroundCenter(center(), r);
@@ -853,11 +870,15 @@ namespace ph2d
 
 	void applyAngularDrag(MotionState &motionState)
 	{
-		float dragForce = 0.1f * -motionState.angularVelocity;
+		float dragForce = 0.02f * -motionState.angularVelocity;
 		if (dragForce > MAX_AIR_DRAG)
 		{
 			dragForce = MAX_AIR_DRAG;
 		}
+		if (dragForce < -MAX_AIR_DRAG)
+		{
+			dragForce = -MAX_AIR_DRAG;
+		}
 		motionState.angularVelocity += dragForce;
 	}
 
@@ -871,6 +892,17 @@ namespace ph2d
 		}
 		else
 		{
+
+			//if (glm::length(motionState.velocity) < MIN_VELOCITY)
+			//{
+			//	motionState.velocity = glm::vec2(0.0f);
+			//}
+			//
+			//if (std::abs(motionState.angularVelocity) < MIN_ANGULAR_VELOCITY)
+			//{
+			//	motionState.angularVelocity = 0.0f;
+			//}
+
 			//linear motion
 			motionState.acceleration = glm::clamp(motionState.acceleration,
 				glm::vec2(-MAX_ACCELERATION), glm::vec2(MAX_ACCELERATION));
@@ -1015,7 +1047,7 @@ void ph2d::MotionState::applyImpulseObjectPosition(glm::vec2 impulse, glm::vec2
 
 	if (momentOfInertia != 0 && momentOfInertia != INFINITY)
 	{
-		angularVelocity -= (1.0f / momentOfInertia) * cross(contactVector, impulse) * 0.99f;
+		angularVelocity -= (1.0f / momentOfInertia) * cross(contactVector, impulse) * 0.95f;
 	}
 }
 
@@ -1073,6 +1105,27 @@ void ph2d::PhysicsEngine::runSimulation(float deltaTime)
 			B.motionState.pos += massInverseB * correction;
 		};
 
+		auto angularCorrection = [&](Body &A, Body &B, glm::vec2 n,
+			float penetrationDepth)
+		{
+
+			float intertiaInverseA = 1.f / A.motionState.momentOfInertia;
+			float intertiaInverseB = 1.f / B.motionState.momentOfInertia;
+
+			if (A.motionState.momentOfInertia == 0 || A.motionState.momentOfInertia == INFINITY) { intertiaInverseA = 0; }
+			if (B.motionState.momentOfInertia == 0 || B.motionState.momentOfInertia == INFINITY) { intertiaInverseB = 0; }
+
+			const float percent = 0.20; // usually 20% to 80%
+			const float slop = 0.01; // usually 0.01 to 0.1 
+
+			//float angularDeviationA = glm::dot(A.motionState.rotation, normal);
+			//float angularDeviationB = glm::dot(B.motionState.rotation, normal);
+
+			//glm::vec2 correction = (glm::max(penetrationDepth - slop, 0.0f) / (intertiaInverseA + intertiaInverseB)) * percent * n;
+			//A.motionState.pos -= massInverseA * correction;
+			//B.motionState.pos += massInverseB * correction;
+		};
+
 		auto applyFriction = [&](Body &A, Body &B, glm::vec2 tangent, glm::vec2 rv,
 			float aInverseMass, float bInverseMass, float j, glm::vec2 rContactA,
 			glm::vec2 rContactB, glm::vec2 contactPoint)
@@ -1189,7 +1242,7 @@ void ph2d::PhysicsEngine::runSimulation(float deltaTime)
 				// Re-calculate relative velocity after normal impulse
 				// is applied (impulse from first article, this code comes
 				// directly thereafter in the same resolve function)
-				// rv also holds the rotational velocity contribution
+				// rv also holds the rotationalrotational velocity contribution
 				glm::vec2 rv = (B.motionState.velocity + cross(-B.motionState.angularVelocity, rContactB)) -
 					(A.motionState.velocity + cross(-A.motionState.angularVelocity, rContactA));
 
@@ -1408,6 +1461,11 @@ ph2d::AABB ph2d::Body::getAABB()
 
 }
 
+bool ph2d::Body::isHalfPlane()
+{
+	return collider.type == ColliderHalfSpace;
+}
+
 bool ph2d::Body::intersectPoint(glm::vec2 p, float delta)
 {
 	switch (collider.type)
@@ -1425,6 +1483,18 @@ bool ph2d::Body::intersectPoint(glm::vec2 p, float delta)
 	}
 	break;
 
+	case ColliderHalfSpace:
+	{
+		LineEquation lineEquation;
+		lineEquation.createFromRotationAndPoint(motionState.rotation,
+			motionState.pos);
+
+		return (lineEquation.computeEquation(p) + delta) >= 0;
+	}
+	break;
+
+	//todo last cases
+
 	}
 
 	return {};