mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
2D Polygon Collider
This commit is contained in:
@@ -505,6 +505,34 @@ namespace GlitchyEngine.World
|
||||
internal ref b2Vec2 b2Offset mut => ref *(Box2D.b2Vec2*)(void*)&Offset;
|
||||
}
|
||||
|
||||
// Todo: This component is rather large (> 1 Cache line)
|
||||
struct PolygonCollider2DComponent
|
||||
{
|
||||
public float2 Offset = .(0.0f, 0.0f);
|
||||
|
||||
// TODO: move into 2D physics material
|
||||
public float Density = 1.0f;
|
||||
public float Friction = 0.5f;
|
||||
public float Restitution = 0.0f;
|
||||
public float RestitutionThreshold = 0.5f;
|
||||
|
||||
public float2[8] Vertices = .();
|
||||
public int8 VertexCount = 3;
|
||||
|
||||
private int _runtimeFixture = 0;
|
||||
|
||||
internal b2Fixture* RuntimeFixture
|
||||
{
|
||||
[Inline]
|
||||
get => (b2Fixture*)(void*)_runtimeFixture;
|
||||
[Inline]
|
||||
set mut => _runtimeFixture = (int)(void*)value;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
internal ref b2Vec2 b2Offset mut => ref *(Box2D.b2Vec2*)(void*)&Offset;
|
||||
}
|
||||
|
||||
struct ScriptComponent : IDisposableComponent
|
||||
{
|
||||
private String _scriptClassName = null;
|
||||
|
||||
@@ -88,6 +88,7 @@ namespace GlitchyEngine.World
|
||||
CopyComponents<Rigidbody2DComponent>(this, target);
|
||||
CopyComponents<BoxCollider2DComponent>(this, target);
|
||||
CopyComponents<CircleCollider2DComponent>(this, target);
|
||||
CopyComponents<PolygonCollider2DComponent>(this, target);
|
||||
|
||||
// Copy ScriptComponents... needs extra handling for the script instances
|
||||
for (let (sourceHandle, sourceComponent) in _ecsWorld.Enumerate<ScriptComponent>())
|
||||
@@ -365,6 +366,13 @@ namespace GlitchyEngine.World
|
||||
|
||||
InitCircleCollider2D(entity, circleCollider);
|
||||
}
|
||||
|
||||
for (let (ecsHandle, polygonCollider) in _ecsWorld.Enumerate<PolygonCollider2DComponent>())
|
||||
{
|
||||
Entity entity = .(ecsHandle, this);
|
||||
|
||||
InitPolygonCollider2D(entity, polygonCollider);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeRigidbody2D(Entity entity, Rigidbody2DComponent* rigidBody)
|
||||
@@ -426,8 +434,6 @@ namespace GlitchyEngine.World
|
||||
let localToWorld = entity.Transform.WorldTransform;
|
||||
let worldToRigidbody = entityWithRigidbody.Transform.WorldTransform.Invert();
|
||||
|
||||
let boxShape = Box2D.Shape.CreatePolygon();
|
||||
|
||||
Box2D.b2Vec2[4] points = .(
|
||||
.(-1, -1),
|
||||
.( 1, -1),
|
||||
@@ -444,6 +450,7 @@ namespace GlitchyEngine.World
|
||||
points[i] = (worldToRigidbody * localToWorld * float4(points[i], 0, 1)).XY;
|
||||
}
|
||||
|
||||
let boxShape = Box2D.Shape.CreatePolygon();
|
||||
Shape.PolygonSet(boxShape, &points, 4);
|
||||
|
||||
b2FixtureDef fixtureDef = .();
|
||||
@@ -486,6 +493,42 @@ namespace GlitchyEngine.World
|
||||
circleCollider.RuntimeFixture = fixture;
|
||||
}
|
||||
|
||||
private void InitPolygonCollider2D(Entity entity, PolygonCollider2DComponent* polygonCollider)
|
||||
{
|
||||
if (FindParentWithRigidbody(entity, let entityWithRigidbody, let rigidbody, let parentToRigidbody) case .Err)
|
||||
return;
|
||||
|
||||
let localToWorld = entity.Transform.WorldTransform;
|
||||
let worldToRigidbody = entityWithRigidbody.Transform.WorldTransform.Invert();
|
||||
|
||||
Box2D.b2Vec2[8] points = .();
|
||||
|
||||
for (int i < polygonCollider.VertexCount)
|
||||
{
|
||||
points[i] = ((float2)polygonCollider.Vertices[i] + polygonCollider.Offset);
|
||||
|
||||
if (entity == entityWithRigidbody)
|
||||
points[i] = entity.Transform.Scale.XY * (float2)points[i];
|
||||
|
||||
points[i] = (worldToRigidbody * localToWorld * float4(points[i], 0, 1)).XY;
|
||||
}
|
||||
|
||||
let polygonShape = Box2D.Shape.CreatePolygon();
|
||||
Shape.PolygonSet(polygonShape, &points, polygonCollider.VertexCount);
|
||||
|
||||
b2FixtureDef fixtureDef = .();
|
||||
fixtureDef.shape = polygonShape;
|
||||
fixtureDef.density = polygonCollider.Density;
|
||||
fixtureDef.friction = polygonCollider.Friction;
|
||||
fixtureDef.restitution = polygonCollider.Restitution;
|
||||
fixtureDef.restitutionThreshold = polygonCollider.RestitutionThreshold;
|
||||
fixtureDef.userData = (void*)(uint)entity.Handle;
|
||||
|
||||
Log.EngineLogger.AssertDebug(rigidbody.RuntimeBody != null);
|
||||
b2Fixture* fixture = Box2D.Body.CreateFixture(rigidbody.RuntimeBody, &fixtureDef);
|
||||
polygonCollider.RuntimeFixture = fixture;
|
||||
}
|
||||
|
||||
public void OnSimulationStop()
|
||||
{
|
||||
Box2D.World.Delete(_physicsWorld2D);
|
||||
|
||||
@@ -177,6 +177,19 @@ class SceneSerializer
|
||||
Serialize.Value(writer, "RestitutionThreshold", component.RestitutionThreshold);
|
||||
});
|
||||
|
||||
SerializeComponent<PolygonCollider2DComponent>(writer, entity, "PolygonCollider2D", scope (component) =>
|
||||
{
|
||||
Serialize.Value(writer, "Offset", component.Offset);
|
||||
|
||||
Serialize.Value(writer, "Vertices", component.Vertices);
|
||||
Serialize.Value(writer, "VertexCount", component.VertexCount);
|
||||
|
||||
Serialize.Value(writer, "Density", component.Density);
|
||||
Serialize.Value(writer, "Friction", component.Friction);
|
||||
Serialize.Value(writer, "Restitution", component.Restitution);
|
||||
Serialize.Value(writer, "RestitutionThreshold", component.RestitutionThreshold);
|
||||
});
|
||||
|
||||
SerializeComponent<MeshComponent>(writer, entity, "MeshComponent", scope (component) =>
|
||||
{
|
||||
Serialize.Value(writer, "Mesh", component.Mesh);
|
||||
@@ -526,6 +539,28 @@ class SceneSerializer
|
||||
Deserialize.Value(reader, "Radius", out component.Radius);
|
||||
reader.EntryEnd();
|
||||
|
||||
Deserialize.Value(reader, "Density", out component.Density);
|
||||
reader.EntryEnd();
|
||||
Deserialize.Value(reader, "Friction", out component.Friction);
|
||||
reader.EntryEnd();
|
||||
Deserialize.Value(reader, "Restitution", out component.Restitution);
|
||||
reader.EntryEnd();
|
||||
Deserialize.Value(reader, "RestitutionThreshold", out component.RestitutionThreshold);
|
||||
|
||||
return .Ok;
|
||||
}));
|
||||
case "PolygonCollider2D":
|
||||
Try!(DeserializeComponent<PolygonCollider2DComponent>(reader, entity, scope (component) =>
|
||||
{
|
||||
Deserialize.Value(reader, "Offset", out component.Offset);
|
||||
reader.EntryEnd();
|
||||
|
||||
Deserialize.Value(reader, "Vertices", out component.Vertices);
|
||||
reader.EntryEnd();
|
||||
Deserialize.Value(reader, "VertexCount", out component.VertexCount);
|
||||
reader.EntryEnd();
|
||||
|
||||
|
||||
Deserialize.Value(reader, "Density", out component.Density);
|
||||
reader.EntryEnd();
|
||||
Deserialize.Value(reader, "Friction", out component.Friction);
|
||||
|
||||
Reference in New Issue
Block a user