Browse Source

some basic elastic constrains

vlod 1 year ago
parent
commit
f43553288e

+ 18 - 2
Pika/gameplay/containers/physicsTest/physicsTest.h

@@ -72,7 +72,24 @@ struct PhysicsTest: public Container
 		};
 		for (int i = 0; i < 5; i++) { shape[i] *= 2; }
 
-		physicsEngine.addBody({500, 200}, ph2d::createConvexPolygonCollider(shape, 5));
+
+		auto bodyA = physicsEngine.addBody({500, 200}, ph2d::createCircleCollider({20}));
+		physicsEngine.bodies[bodyA].flags.setKinematic(true);
+
+		for (int i = 0; i < 10; i++)
+		{
+			auto bodyB = physicsEngine.addBody({500, 220 + i * 20}, ph2d::createCircleCollider({20}));
+			physicsEngine.addConstrain({bodyA, bodyB, 40});
+			bodyA = bodyB;
+			
+
+		}
+
+	
+
+		//physicsEngine.addBody({500, 200}, ph2d::createConvexPolygonCollider(shape, 5));
+		//auto body = physicsEngine.addBody({500, 200}, ph2d::createBoxCollider({300, 300}));
+
 
 		//physicsEngine.addBody({500, 1100}, 
 		//	ph2d::createBoxCollider({1100, 10}));
@@ -92,7 +109,6 @@ struct PhysicsTest: public Container
 		//physicsEngine.addBody({600, 600}, ph2d::createBoxCollider({350, 350}));
 		//physicsEngine.bodies[1].motionState.rotation = glm::radians(30.f);
 
-		physicsEngine.addBody({500, 500}, ph2d::createCircleCollider({75}));
 		//physicsEngine.addBody({800, 100}, ph2d::createCircleCollider({25}));
 		//physicsEngine.addBody({900, 500}, ph2d::createCircleCollider({40}));
 		//physicsEngine.addBody({550, 700}, ph2d::createCircleCollider({25}));

+ 2 - 37
Pika/resources/logs.txt

@@ -1,37 +1,2 @@
-#2024-11-28 15:01:42: Created container: PhysicsTest
-#2024-11-28 15:05:50: Reloaded dll
-#2024-11-28 15:06:06: Reloaded dll
-#2024-11-28 15:09:43: Reloaded dll
-#2024-11-28 15:12:49: Reloaded dll
-#2024-11-28 15:13:46: Reloaded dll
-#2024-11-28 15:17:39: Reloaded dll
-#2024-11-28 15:26:56: Reloaded dll
-#2024-11-28 15:27:31: Reloaded dll
-#2024-11-28 15:28:55: Reloaded dll
-#2024-11-28 15:29:54: Reloaded dll
-#2024-11-28 15:30:09: Reloaded dll
-#2024-11-28 15:32:52: Reloaded dll
-#2024-11-28 15:33:16: Reloaded dll
-#2024-11-28 15:36:51: Reloaded dll
-#2024-11-28 15:37:35: Reloaded dll
-#2024-11-28 15:38:05: Reloaded dll
-#2024-11-28 15:38:29: Reloaded dll
-#2024-11-28 15:38:49: Reloaded dll
-#2024-11-28 15:39:28: Reloaded dll
-#2024-11-28 15:42:39: Reloaded dll
-#2024-11-28 15:43:19: Reloaded dll
-#2024-11-28 15:52:27: Reloaded dll
-#2024-11-28 15:53:37: Reloaded dll
-#2024-11-28 15:54:16: Reloaded dll
-#2024-11-28 15:54:34: Reloaded dll
-#2024-11-28 15:55:35: Reloaded dll
-#2024-11-28 15:56:00: Reloaded dll
-#2024-11-28 15:56:46: Reloaded dll
-#2024-11-28 15:57:27: Reloaded dll
-#2024-11-28 15:58:17: Reloaded dll
-#2024-11-28 16:01:08: Reloaded dll
-#2024-11-28 16:02:22: Reloaded dll
-#2024-11-28 16:03:03: Reloaded dll
-#2024-11-28 16:04:42: Reloaded dll
-#2024-11-28 16:04:49: Reloaded dll
-#2024-11-28 16:06:51: Destroyed continer: PhysicsTest #1
+#2024-11-28 17:31:23: Created container: PhysicsTest
+#2024-11-28 17:31:50: Destroyed continer: PhysicsTest #1

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

@@ -364,12 +364,25 @@ namespace ph2d
 		float restingAngularVelocity = glm::radians(0.01);
 	};
 
+	struct Constrain
+	{
+		ph2dBodyId A;
+		ph2dBodyId B;
+
+		float restingDistance = 0;
+		float elasticForce = 50000;
+
+	};
+
 	struct PhysicsEngine
 	{
 		ph2dBodyId idCounter = 0;
 
 		std::unordered_map<ph2dBodyId, Body> bodies;
 
+		std::unordered_map<ph2dBodyId, Constrain> constrains;
+
+
 		//for internal use for now
 		std::vector<ManifoldIntersection> intersections;
 
@@ -388,6 +401,8 @@ namespace ph2d
 
 		ph2dBodyId addBody(glm::vec2 centerPos, Collider collider);
 
+		ph2dBodyId addConstrain(Constrain c);
+
 		ph2dBodyId addHalfSpaceStaticObject(glm::vec2 position, glm::vec2 normal);
 	};
 

+ 45 - 2
Pika/thirdparty/ph2d/src/ph2d.cpp

@@ -1121,8 +1121,12 @@ namespace ph2d
 	}
 
 	bool BodyvsBody(Body &A, Body &B, float &penetration,
-		glm::vec2 &normal, glm::vec2 &contactPoint, glm::vec2 &tangentA, glm::vec2 &tangentB, bool *reverseOrder)
+		glm::vec2 &normal, glm::vec2 &contactPoint, glm::vec2 &tangentA, 
+		glm::vec2 &tangentB, bool *reverseOrder)
 	{
+
+		//todo reverseOrder for all
+
 		tangentA = {};
 		tangentB = {};
 		if (reverseOrder) { *reverseOrder = false; }
@@ -1273,6 +1277,11 @@ namespace ph2d
 			&& B.collider.type == ph2d::ColliderConvexPolygon
 			)
 			{
+				if (reverseOrder)
+				{
+					*reverseOrder = true;
+				}
+
 				return CirclevsConvexPolygon(A.getAABB(), B.collider.collider.convexPolygon,
 					B.motionState.pos, B.motionState.rotation, penetration, normal, contactPoint);
 			}
@@ -1280,6 +1289,7 @@ namespace ph2d
 			&& B.collider.type == ph2d::ColliderCircle
 			)
 			{
+
 				bool rez = CirclevsConvexPolygon(B.getAABB(), A.collider.collider.convexPolygon,
 					A.motionState.pos, A.motionState.rotation, penetration, normal, contactPoint);
 				normal = -normal;
@@ -1877,7 +1887,6 @@ void ph2d::PhysicsEngine::runSimulation(float deltaTime)
 
 		}
 
-
 		for (int _ = 0; _ < collisionChecksCount; _++)
 		{
 			intersections.clear();
@@ -1980,7 +1989,35 @@ void ph2d::PhysicsEngine::runSimulation(float deltaTime)
 			}
 
 		}
+	
+
+		for (auto &c : constrains)
+		{
+
+			auto ait = bodies.find(c.second.A);
+			auto bit = bodies.find(c.second.B);
+
+			if (ait == bodies.end() || bit == bodies.end()) { continue; }
+
+			float distance = glm::distance(ait->second.motionState.pos, bit->second.motionState.pos);
+
+			float deformation = c.second.restingDistance - distance;
+
+			if (deformation == 0) { continue; }
+
+			float elasticForce = deformation * c.second.elasticForce;
 		
+			glm::vec2 dir = bit->second.motionState.pos - ait->second.motionState.pos;
+			normalizeSafe(dir);
+
+			dir *= elasticForce;
+
+			ait->second.applyImpulseObjectPosition(-dir, {});
+			bit->second.applyImpulseObjectPosition( dir, {});
+
+		}
+
+
 		for (auto &it : bodies)
 		{
 			auto &b = it.second;
@@ -2008,6 +2045,12 @@ ph2d::ph2dBodyId ph2d::PhysicsEngine::addBody(glm::vec2 centerPos, Collider coll
 	return idCounter;
 }
 
+ph2d::ph2dBodyId ph2d::PhysicsEngine::addConstrain(ph2d::Constrain c)
+{
+	constrains.emplace(++idCounter, c);
+	return idCounter;
+}
+
 
 float ph2d::vectorToRotation(const glm::vec2 &vector)
 {