From 88d5170fe50d64247a5acc300a443b053eb1f4b7 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 8 Nov 2020 20:22:32 +0300 Subject: [PATCH] Added CompoundColliderModel --- .../client/graphics/world/LayerWorld.java | 5 +- .../collision/CompoundCollisionModel.java | 39 +++++++++++++++ .../AnythingWithCompoundCollider.java | 47 +++++++++++++++++++ .../common/collision/colliders/Collider.java | 35 ++++++++++++-- .../progressia/test/AABBRenderer.java | 15 ++++++ .../progressia/test/TestEntityDataStatie.java | 6 ++- 6 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/collision/CompoundCollisionModel.java create mode 100644 src/main/java/ru/windcorp/progressia/common/collision/colliders/AnythingWithCompoundCollider.java diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java index 09d6db4..114e1ed 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java @@ -40,6 +40,7 @@ import ru.windcorp.progressia.common.collision.AABB; import ru.windcorp.progressia.common.collision.Collideable; import ru.windcorp.progressia.common.collision.CollisionClock; import ru.windcorp.progressia.common.collision.CollisionModel; +import ru.windcorp.progressia.common.collision.CompoundCollisionModel; import ru.windcorp.progressia.common.collision.colliders.Collider; import ru.windcorp.progressia.common.util.FloatMathUtils; import ru.windcorp.progressia.common.util.Vectors; @@ -127,7 +128,7 @@ public class LayerWorld extends Layer { private final Collider.ColliderWorkspace tmp_colliderWorkspace = new Collider.ColliderWorkspace(); private final List tmp_collideableList = new ArrayList<>(); - private static final boolean RENDER_AABBS = false; + private static final boolean RENDER_AABBS = true; private void tmp_doEveryFrame() { try { @@ -136,6 +137,8 @@ public class LayerWorld extends Layer { CollisionModel model = data.getCollisionModel(); if (model instanceof AABB) { AABBRenderer.renderAABB((AABB) model, helper); + } else if (model instanceof CompoundCollisionModel) { + AABBRenderer.renderAABBsInCompound((CompoundCollisionModel) model, helper); } } } diff --git a/src/main/java/ru/windcorp/progressia/common/collision/CompoundCollisionModel.java b/src/main/java/ru/windcorp/progressia/common/collision/CompoundCollisionModel.java new file mode 100644 index 0000000..2cf4572 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/collision/CompoundCollisionModel.java @@ -0,0 +1,39 @@ +package ru.windcorp.progressia.common.collision; + +import java.util.Collection; + +import com.google.common.collect.ImmutableList; + +import glm.vec._3.Vec3; + +public class CompoundCollisionModel implements CollisionModel { + + private final Collection models; + + public CompoundCollisionModel(Collection models) { + this.models = models; + } + + public CompoundCollisionModel(CollisionModel... models) { + this(ImmutableList.copyOf(models)); + } + + public Collection getModels() { + return models; + } + + @Override + public void setOrigin(Vec3 origin) { + for (CollisionModel model : getModels()) { + model.setOrigin(origin); + } + } + + @Override + public void moveOrigin(Vec3 displacement) { + for (CollisionModel model : getModels()) { + model.moveOrigin(displacement); + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AnythingWithCompoundCollider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AnythingWithCompoundCollider.java new file mode 100644 index 0000000..5efcb00 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AnythingWithCompoundCollider.java @@ -0,0 +1,47 @@ +package ru.windcorp.progressia.common.collision.colliders; + +import ru.windcorp.progressia.common.collision.Collideable; +import ru.windcorp.progressia.common.collision.CollisionModel; +import ru.windcorp.progressia.common.collision.CompoundCollisionModel; +import ru.windcorp.progressia.common.collision.colliders.Collider.ColliderWorkspace; +import ru.windcorp.progressia.common.collision.colliders.Collider.Collision; + +class AnythingWithCompoundCollider { + + static Collider.Collision computeModelCollision( + Collideable aBody, Collideable bBody, + CompoundCollisionModel aModel, CollisionModel bModel, + float tickLength, + ColliderWorkspace workspace + ) { + Collision result = null; + + for (CollisionModel aModelPart : aModel.getModels()) { + + Collision collision = Collider.getCollision( + aBody, bBody, + aModelPart, bModel, + tickLength, workspace + ); + + // Update result + if (collision != null) { + Collision second; + + if (result == null || collision.time < result.time) { + second = result; + result = collision; + } else { + second = collision; + } + + // Release Collision that is no longer used + if (second != null) workspace.release(second); + } + + } + + return result; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java index 4c040ba..74bcc2c 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java @@ -11,6 +11,7 @@ import ru.windcorp.progressia.common.collision.Collideable; import ru.windcorp.progressia.common.collision.CollisionClock; import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.collision.CollisionWall; +import ru.windcorp.progressia.common.collision.CompoundCollisionModel; import ru.windcorp.progressia.common.util.LowOverheadCache; import ru.windcorp.progressia.common.util.Vectors; @@ -88,7 +89,7 @@ public class Collider { return result; } - private static Collision getCollision( + static Collision getCollision( Collideable a, Collideable b, float tickLength, @@ -96,16 +97,44 @@ public class Collider { ) { CollisionModel aModel = a.getCollisionModel(); CollisionModel bModel = b.getCollisionModel(); - + return getCollision(a, b, aModel, bModel, tickLength, workspace); + } + + static Collision getCollision( + Collideable aBody, + Collideable bBody, + CollisionModel aModel, + CollisionModel bModel, + float tickLength, + ColliderWorkspace workspace + ) { if (aModel instanceof AABB && bModel instanceof AABB) { return AABBWithAABBCollider.computeModelCollision( - a, b, + aBody, bBody, (AABB) aModel, (AABB) bModel, tickLength, workspace ); } + if (aModel instanceof CompoundCollisionModel) { + return AnythingWithCompoundCollider.computeModelCollision( + aBody, bBody, + (CompoundCollisionModel) aModel, bModel, + tickLength, + workspace + ); + } + + if (bModel instanceof CompoundCollisionModel) { + return AnythingWithCompoundCollider.computeModelCollision( + bBody, aBody, + (CompoundCollisionModel) bModel, aModel, + tickLength, + workspace + ); + } + throw new UnsupportedOperationException( "Collisions between " + aModel + " and " + bModel + " are not yet implemented" ); diff --git a/src/main/java/ru/windcorp/progressia/test/AABBRenderer.java b/src/main/java/ru/windcorp/progressia/test/AABBRenderer.java index 0afbb09..e9a6b7b 100644 --- a/src/main/java/ru/windcorp/progressia/test/AABBRenderer.java +++ b/src/main/java/ru/windcorp/progressia/test/AABBRenderer.java @@ -6,6 +6,8 @@ import ru.windcorp.progressia.client.graphics.model.Shapes; import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.common.collision.AABB; +import ru.windcorp.progressia.common.collision.CollisionModel; +import ru.windcorp.progressia.common.collision.CompoundCollisionModel; public class AABBRenderer { @@ -16,5 +18,18 @@ public class AABBRenderer { CUBE.render(helper); helper.popTransform(); } + + public static void renderAABBsInCompound( + CompoundCollisionModel model, + ShapeRenderHelper helper + ) { + for (CollisionModel part : model.getModels()) { + if (part instanceof CompoundCollisionModel) { + renderAABBsInCompound((CompoundCollisionModel) part, helper); + } else if (part instanceof AABB) { + renderAABB((AABB) part, helper); + } + } + } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityDataStatie.java b/src/main/java/ru/windcorp/progressia/test/TestEntityDataStatie.java index fb29df1..a58ed35 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityDataStatie.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityDataStatie.java @@ -1,6 +1,7 @@ package ru.windcorp.progressia.test; import ru.windcorp.progressia.common.collision.AABB; +import ru.windcorp.progressia.common.collision.CompoundCollisionModel; import ru.windcorp.progressia.common.state.IntStateField; import ru.windcorp.progressia.common.world.entity.EntityData; @@ -11,7 +12,10 @@ public class TestEntityDataStatie extends EntityData { public TestEntityDataStatie() { super("Test", "Statie"); - setCollisionModel(new AABB(0, 0, 0, 16f/24, 16f/24, 16f/24)); + setCollisionModel(new CompoundCollisionModel( + new AABB(0, 0, 0, 1, 1, 1 ), + new AABB(0, 0, 0.7f, 0.6f, 0.6f, 0.6f) + )); setSizeNow(16); }