Cherry-picked de2136c (level physicsbody optimization)

This commit is contained in:
Joonas Rikkonen
2018-07-20 12:23:07 +03:00
parent e7e7d32123
commit bcd9fd7e5f
3 changed files with 25 additions and 41 deletions
@@ -323,18 +323,9 @@ namespace Barotrauma
//choose random edge (ignoring ones where the adjacent cell is outside limits) //choose random edge (ignoring ones where the adjacent cell is outside limits)
else else
{ {
//if (allowedEdges.Count==0)
//{
// edgeIndex = Rand.Int(currentCell.edges.Count, false);
//}
//else
//{
edgeIndex = Rand.Int(allowedEdges.Count, Rand.RandSync.Server); edgeIndex = Rand.Int(allowedEdges.Count, Rand.RandSync.Server);
if (mirror && edgeIndex > 0) edgeIndex = allowedEdges.Count - edgeIndex; if (mirror && edgeIndex > 0) edgeIndex = allowedEdges.Count - edgeIndex;
edgeIndex = currentCell.edges.IndexOf(allowedEdges[edgeIndex]); edgeIndex = currentCell.edges.IndexOf(allowedEdges[edgeIndex]);
//}
} }
currentCell = currentCell.edges[edgeIndex].AdjacentCell(currentCell); currentCell = currentCell.edges[edgeIndex].AdjacentCell(currentCell);
@@ -357,8 +348,8 @@ namespace Barotrauma
return pathCells; return pathCells;
} }
public static List<Body> GeneratePolygons(List<VoronoiCell> cells, out List<Vector2[]> renderTriangles, bool setSolid=true) public static List<Body> GeneratePolygons(List<VoronoiCell> cells, out List<Vector2[]> renderTriangles, bool setSolid = true)
{ {
renderTriangles = new List<Vector2[]>(); renderTriangles = new List<Vector2[]>();
var bodies = new List<Body>(); var bodies = new List<Body>();
@@ -366,6 +357,14 @@ namespace Barotrauma
List<Vector2> tempVertices = new List<Vector2>(); List<Vector2> tempVertices = new List<Vector2>();
List<Vector2> bodyPoints = new List<Vector2>(); List<Vector2> bodyPoints = new List<Vector2>();
Body cellBody = new Body(GameMain.World)
{
SleepingAllowed = false,
BodyType = BodyType.Static,
CollisionCategories = Physics.CollisionLevel
};
bodies.Add(cellBody);
for (int n = cells.Count - 1; n >= 0; n-- ) for (int n = cells.Count - 1; n >= 0; n-- )
{ {
VoronoiCell cell = cells[n]; VoronoiCell cell = cells[n];
@@ -412,14 +411,12 @@ namespace Barotrauma
cell.bodyVertices.Add(bodyPoints[i]); cell.bodyVertices.Add(bodyPoints[i]);
bodyPoints[i] = ConvertUnits.ToSimUnits(bodyPoints[i]); bodyPoints[i] = ConvertUnits.ToSimUnits(bodyPoints[i]);
} }
if (cell.CellType == CellType.Empty) continue; if (cell.CellType == CellType.Empty) continue;
cellBody.UserData = cell;
var triangles = MathUtils.TriangulateConvexHull(bodyPoints, ConvertUnits.ToSimUnits(cell.Center)); var triangles = MathUtils.TriangulateConvexHull(bodyPoints, ConvertUnits.ToSimUnits(cell.Center));
Body cellBody = new Body(GameMain.World);
for (int i = 0; i < triangles.Count; i++) for (int i = 0; i < triangles.Count; i++)
{ {
//don't create a triangle if any of the vertices are too close to each other //don't create a triangle if any of the vertices are too close to each other
@@ -429,16 +426,11 @@ namespace Barotrauma
Vector2.Distance(triangles[i][1], triangles[i][2]) < 0.05f) continue; Vector2.Distance(triangles[i][1], triangles[i][2]) < 0.05f) continue;
Vertices bodyVertices = new Vertices(triangles[i]); Vertices bodyVertices = new Vertices(triangles[i]);
FixtureFactory.AttachPolygon(bodyVertices, 5.0f, cellBody); var newFixture = FixtureFactory.AttachPolygon(bodyVertices, 5.0f, cellBody);
newFixture.UserData = cell;
} }
cellBody.UserData = cell;
cellBody.SleepingAllowed = false;
cellBody.BodyType = BodyType.Kinematic;
cellBody.CollisionCategories = Physics.CollisionLevel;
cell.body = cellBody; cell.body = cellBody;
bodies.Add(cellBody);
} }
return bodies; return bodies;
@@ -21,7 +21,6 @@ namespace Barotrauma
public LevelWall(List<Vector2> edgePositions, Vector2 extendAmount, Color color) public LevelWall(List<Vector2> edgePositions, Vector2 extendAmount, Color color)
{ {
cells = new List<VoronoiCell>(); cells = new List<VoronoiCell>();
for (int i = 0; i < edgePositions.Count - 1; i++) for (int i = 0; i < edgePositions.Count - 1; i++)
{ {
Vector2[] vertices = new Vector2[4]; Vector2[] vertices = new Vector2[4];
@@ -47,8 +46,7 @@ namespace Barotrauma
cells.Add(wallCell); cells.Add(wallCell);
} }
List<Vector2[]> triangles; bodies = CaveGenerator.GeneratePolygons(cells, out List<Vector2[]> triangles, false);
bodies = CaveGenerator.GeneratePolygons(cells, out triangles, false);
#if CLIENT #if CLIENT
List<VertexPositionTexture> bodyVertices = CaveGenerator.GenerateRenderVerticeList(triangles); List<VertexPositionTexture> bodyVertices = CaveGenerator.GenerateRenderVerticeList(triangles);
@@ -370,27 +370,22 @@ namespace Barotrauma
public bool OnCollision(Fixture f1, Fixture f2, Contact contact) public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
{ {
Limb limb = f2.Body.UserData as Limb; if (f2.Body.UserData is Limb limb)
if (limb != null)
{ {
bool collision = CheckLimbCollision(contact, limb); bool collision = CheckLimbCollision(contact, limb);
if (collision) HandleLimbCollision(contact, limb); if (collision) HandleLimbCollision(contact, limb);
return collision; return collision;
} }
VoronoiCell cell = f2.Body.UserData as VoronoiCell; if (f2.UserData is VoronoiCell cell)
if (cell != null)
{ {
HandleLevelCollision(contact, Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center)); HandleLevelCollision(contact, Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center));
return true; return true;
} }
Structure structure = f2.Body.UserData as Structure; if (f2.Body.UserData is Structure structure)
if (structure != null)
{ {
Vector2 normal; contact.GetWorldManifold(out Vector2 normal, out FixedArray2<Vector2> points);
FixedArray2<Vector2> points;
contact.GetWorldManifold(out normal, out points);
if (contact.FixtureA.Body == f1.Body) if (contact.FixtureA.Body == f1.Body)
{ {
normal = -normal; normal = -normal;
@@ -400,8 +395,7 @@ namespace Barotrauma
return true; return true;
} }
Submarine otherSub = f2.Body.UserData as Submarine; if (f2.Body.UserData is Submarine otherSub)
if (otherSub != null)
{ {
HandleSubCollision(contact, otherSub); HandleSubCollision(contact, otherSub);
return true; return true;
@@ -486,8 +480,8 @@ namespace Barotrauma
levelContact.GetWorldManifold(out contactNormal, out temp); levelContact.GetWorldManifold(out contactNormal, out temp);
//if the contact normal is pointing from the limb towards the level cell it's touching, flip the normal //if the contact normal is pointing from the limb towards the level cell it's touching, flip the normal
VoronoiCell cell = levelContact.FixtureB.Body.UserData is VoronoiCell ? VoronoiCell cell = levelContact.FixtureB.UserData is VoronoiCell ?
((VoronoiCell)levelContact.FixtureB.Body.UserData) : ((VoronoiCell)levelContact.FixtureA.Body.UserData); ((VoronoiCell)levelContact.FixtureB.UserData) : ((VoronoiCell)levelContact.FixtureA.UserData);
var cellDiff = ConvertUnits.ToDisplayUnits(limb.body.SimPosition) - cell.Center; var cellDiff = ConvertUnits.ToDisplayUnits(limb.body.SimPosition) - cell.Center;
if (Vector2.Dot(contactNormal, cellDiff) < 0) if (Vector2.Dot(contactNormal, cellDiff) < 0)
@@ -603,8 +597,8 @@ namespace Barotrauma
levelContact.GetWorldManifold(out contactNormal, out temp); levelContact.GetWorldManifold(out contactNormal, out temp);
//if the contact normal is pointing from the sub towards the level cell we collided with, flip the normal //if the contact normal is pointing from the sub towards the level cell we collided with, flip the normal
VoronoiCell cell = levelContact.FixtureB.Body.UserData is VoronoiCell ? VoronoiCell cell = levelContact.FixtureB.UserData is VoronoiCell ?
((VoronoiCell)levelContact.FixtureB.Body.UserData) : ((VoronoiCell)levelContact.FixtureA.Body.UserData); ((VoronoiCell)levelContact.FixtureB.UserData) : ((VoronoiCell)levelContact.FixtureA.UserData);
var cellDiff = ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center; var cellDiff = ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center;
if (Vector2.Dot(contactNormal, cellDiff) < 0) if (Vector2.Dot(contactNormal, cellDiff) < 0)