From b628370115dbf754e2b397001573e8501d749c39 Mon Sep 17 00:00:00 2001 From: adQuid <28126232+adQuid@users.noreply.github.com> Date: Thu, 5 Jan 2023 17:35:41 -0500 Subject: [PATCH 1/3] allow concave membranes --- src/microbe_stage/Membrane.cs | 46 +++++++++++++++++++++------- src/microbe_stage/Microbe.Contact.cs | 4 ++- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/microbe_stage/Membrane.cs b/src/microbe_stage/Membrane.cs index f3a012f922c..8dc9283cb73 100644 --- a/src/microbe_stage/Membrane.cs +++ b/src/microbe_stage/Membrane.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Godot; using Array = Godot.Collections.Array; +using System.Linq; /// /// Membrane for microbes @@ -284,17 +285,16 @@ public Vector3 GetVectorTowardsNearestPointOfMembrane(float x, float y) /// /// Return the position of the closest organelle to the target point if it is less then a certain threshold away. /// - public Vector2 FindClosestOrganelles(Vector2 target) + public Vector2 FindClosestOrganelleInRange(Vector2 origin, float range) { - // The distance we want the membrane to be from the organelles squared. - float closestSoFar = 4; + float closestSoFar = range; Vector2 closest = new Vector2(INVALID_FOUND_ORGANELLE, INVALID_FOUND_ORGANELLE); foreach (var pos in OrganellePositions) { - float lenToObject = (target - pos).LengthSquared(); + float lenToObject = (origin - pos).LengthSquared(); - if (lenToObject < 4 && lenToObject < closestSoFar) + if (lenToObject < closestSoFar) { closestSoFar = lenToObject; closest = pos; @@ -304,6 +304,15 @@ public Vector2 FindClosestOrganelles(Vector2 target) return closest; } + public Vector2 FindCenterOfOrganellesInRange(Vector2 origin, float range) + { + List points = new List() { origin }; + + points.AddRange(OrganellePositions.Where(x => (origin - x).LengthSquared() < range)); + + return new Vector2(points.Sum(x => x.x) / points.Count(), points.Sum(x => x.y) / points.Count()); + } + public bool MatchesCacheParameters(ICacheableData cacheData) { if (cacheData is IComputedMembraneData data) @@ -322,14 +331,14 @@ public long ComputeCacheHash() /// private static Vector2 GetMovement(Vector2 target, Vector2 closestOrganelle) { - float power = Mathf.Pow(2.7f, -(target - closestOrganelle).Length() / 10) / 50; + float power = Mathf.Pow(2.7f, -(target - closestOrganelle).Length() / 10) / 250; return (closestOrganelle - target) * power; } private static Vector2 GetMovementForCellWall(Vector2 target, Vector2 closestOrganelle) { - float power = Mathf.Pow(10.0f, -(target - closestOrganelle).Length()) / 50; + float power = Mathf.Pow(3.1f, -(target - closestOrganelle).Length() / 10) / 250; return (closestOrganelle - target) * power; } @@ -503,7 +512,7 @@ private void InitializeMesh() // This needs to actually run a bunch of times as the points moving towards the organelles is iterative. // We use rotating work buffers to save time on skipping useless copies - for (int i = 0; i < 40 * cellDimensions; i++) + for (int i = 0; i < 60 * cellDimensions; i++) { DrawCorrectMembrane(cellDimensions, previousWorkBuffer, nextWorkBuffer); @@ -658,13 +667,28 @@ private void DrawCorrectMembrane(float cellDimensions, List sourceBuffe targetBuffer.RemoveAt(targetBuffer.Count - 1); // Loops through all the points in the membrane and relocates them as necessary. - for (int i = 0, end = sourceBuffer.Count; i < end; ++i) + // Iterate from the center of the array for avoid asymetry + for (int i = sourceBuffer.Count / 2 + 1, end = sourceBuffer.Count; i != end / 2; i = (i + 1) % end) { - var closestOrganelle = FindClosestOrganelles(sourceBuffer[i]); + var closestOrganelle = FindClosestOrganelleInRange(sourceBuffer[i], 4f); if (closestOrganelle == new Vector2(INVALID_FOUND_ORGANELLE, INVALID_FOUND_ORGANELLE)) { - targetBuffer[i] = (sourceBuffer[(end + i - 1) % end] + sourceBuffer[(i + 1) % end]) / 2; + var distantOrganelle = FindCenterOfOrganellesInRange(sourceBuffer[i], 8f); + + var midpoint = (sourceBuffer[(end + i - 1) % end] + sourceBuffer[(i + 1) % end]) / 2; + + if (distantOrganelle == sourceBuffer[i]) + { + targetBuffer[i] = midpoint; + } + else + { + var movementDirection = movementFunc(sourceBuffer[i], distantOrganelle + midpoint + midpoint / 3); + + targetBuffer[i] = new Vector2(sourceBuffer[i].x - movementDirection.x, + sourceBuffer[i].y - movementDirection.y); + } } else { diff --git a/src/microbe_stage/Microbe.Contact.cs b/src/microbe_stage/Microbe.Contact.cs index 6fa986afcb9..1f51165360b 100644 --- a/src/microbe_stage/Microbe.Contact.cs +++ b/src/microbe_stage/Microbe.Contact.cs @@ -419,7 +419,9 @@ public void SendOrganellePositionsToMembrane() foreach (var entry in organelles.Organelles) { var cartesian = Hex.AxialToCartesian(entry.Position); - organellePositions.Add(new Vector2(cartesian.x, cartesian.z)); + organellePositions + .AddRange(entry.Definition.Hexes + .Select(x => new Vector2(Hex.AxialToCartesian(x).x, Hex.AxialToCartesian(x).z) + new Vector2(cartesian.x, cartesian.z))); } Membrane.OrganellePositions = organellePositions; From cb5467961b04644c19f1ab2973d082c7d0967b83 Mon Sep 17 00:00:00 2001 From: adQuid <28126232+adQuid@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:40:38 -0500 Subject: [PATCH 2/3] more tweaks --- src/microbe_stage/Membrane.cs | 41 +++++++++++++++-------------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/microbe_stage/Membrane.cs b/src/microbe_stage/Membrane.cs index 8dc9283cb73..f79c121962d 100644 --- a/src/microbe_stage/Membrane.cs +++ b/src/microbe_stage/Membrane.cs @@ -329,14 +329,14 @@ public long ComputeCacheHash() /// /// Decides where the point needs to move based on the position of the closest organelle. /// - private static Vector2 GetMovement(Vector2 target, Vector2 closestOrganelle) + private Vector2 GetMovement(Vector2 target, Vector2 closestOrganelle) { float power = Mathf.Pow(2.7f, -(target - closestOrganelle).Length() / 10) / 250; return (closestOrganelle - target) * power; } - private static Vector2 GetMovementForCellWall(Vector2 target, Vector2 closestOrganelle) + private Vector2 GetMovementForCellWall(Vector2 target, Vector2 closestOrganelle) { float power = Mathf.Pow(3.1f, -(target - closestOrganelle).Length() / 10) / 250; @@ -468,6 +468,8 @@ private void InitializeMesh() // Half the side length of the original square that is compressed to make the membrane. int cellDimensions = 10; + var nodeLength = cellDimensions / membraneResolution; + foreach (var pos in OrganellePositions) { if (Mathf.Abs(pos.x) + 1 > cellDimensions) @@ -484,29 +486,33 @@ private void InitializeMesh() previousWorkBuffer.Capacity = vertices2D.Capacity; nextWorkBuffer.Capacity = previousWorkBuffer.Capacity; + // left wall of square for (int i = membraneResolution; i > 0; i--) { previousWorkBuffer.Add(new Vector2(-cellDimensions, - cellDimensions - 2 * cellDimensions / membraneResolution * i)); + cellDimensions - 2 * nodeLength * i)); } + // bottom wall of square for (int i = membraneResolution; i > 0; i--) { previousWorkBuffer.Add(new Vector2( - cellDimensions - 2 * cellDimensions / membraneResolution * i, + cellDimensions - 2 * nodeLength * i, cellDimensions)); } + // right wall of square for (int i = membraneResolution; i > 0; i--) { previousWorkBuffer.Add(new Vector2(cellDimensions, - -cellDimensions + 2 * cellDimensions / membraneResolution * i)); + -cellDimensions + 2 * nodeLength * i)); } + // bottom wall of square for (int i = membraneResolution; i > 0; i--) { previousWorkBuffer.Add(new Vector2( - -cellDimensions + 2 * cellDimensions / membraneResolution * i, + -cellDimensions + 2 * nodeLength * i, -cellDimensions)); } @@ -514,7 +520,7 @@ private void InitializeMesh() // We use rotating work buffers to save time on skipping useless copies for (int i = 0; i < 60 * cellDimensions; i++) { - DrawCorrectMembrane(cellDimensions, previousWorkBuffer, nextWorkBuffer); + DrawMembrane(cellDimensions, previousWorkBuffer, nextWorkBuffer, Type.CellWall ? GetMovementForCellWall : GetMovement); (previousWorkBuffer, nextWorkBuffer) = (nextWorkBuffer, previousWorkBuffer); } @@ -644,18 +650,6 @@ private void BuildMesh() return writeIndex; } - private void DrawCorrectMembrane(float cellDimensions, List sourceBuffer, List targetBuffer) - { - if (Type.CellWall) - { - DrawMembrane(cellDimensions, sourceBuffer, targetBuffer, GetMovementForCellWall); - } - else - { - DrawMembrane(cellDimensions, sourceBuffer, targetBuffer, GetMovement); - } - } - private void DrawMembrane(float cellDimensions, List sourceBuffer, List targetBuffer, Func movementFunc) { @@ -667,14 +661,13 @@ private void DrawCorrectMembrane(float cellDimensions, List sourceBuffe targetBuffer.RemoveAt(targetBuffer.Count - 1); // Loops through all the points in the membrane and relocates them as necessary. - // Iterate from the center of the array for avoid asymetry - for (int i = sourceBuffer.Count / 2 + 1, end = sourceBuffer.Count; i != end / 2; i = (i + 1) % end) + for (int i = 0, end = sourceBuffer.Count; i < end; i++) { - var closestOrganelle = FindClosestOrganelleInRange(sourceBuffer[i], 4f); + var closestOrganelle = FindClosestOrganelleInRange(sourceBuffer[i], 3f); if (closestOrganelle == new Vector2(INVALID_FOUND_ORGANELLE, INVALID_FOUND_ORGANELLE)) { - var distantOrganelle = FindCenterOfOrganellesInRange(sourceBuffer[i], 8f); + var distantOrganelle = FindCenterOfOrganellesInRange(sourceBuffer[i], 5f); var midpoint = (sourceBuffer[(end + i - 1) % end] + sourceBuffer[(i + 1) % end]) / 2; @@ -684,7 +677,7 @@ private void DrawCorrectMembrane(float cellDimensions, List sourceBuffe } else { - var movementDirection = movementFunc(sourceBuffer[i], distantOrganelle + midpoint + midpoint / 3); + var movementDirection = movementFunc(sourceBuffer[i], distantOrganelle + distantOrganelle + midpoint / 3); targetBuffer[i] = new Vector2(sourceBuffer[i].x - movementDirection.x, sourceBuffer[i].y - movementDirection.y); From bda0bfa90987287dbfbaf211913929299b696ce8 Mon Sep 17 00:00:00 2001 From: adQuid <28126232+adQuid@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:45:26 -0500 Subject: [PATCH 3/3] one more cell wall tweek --- src/microbe_stage/Membrane.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/microbe_stage/Membrane.cs b/src/microbe_stage/Membrane.cs index f79c121962d..27cd6c7c2a1 100644 --- a/src/microbe_stage/Membrane.cs +++ b/src/microbe_stage/Membrane.cs @@ -338,7 +338,7 @@ private Vector2 GetMovement(Vector2 target, Vector2 closestOrganelle) private Vector2 GetMovementForCellWall(Vector2 target, Vector2 closestOrganelle) { - float power = Mathf.Pow(3.1f, -(target - closestOrganelle).Length() / 10) / 250; + float power = Mathf.Pow(3.1f, -(target - closestOrganelle).Length() / 3) / 250; return (closestOrganelle - target) * power; }