Added CompoundColliderModel

This commit is contained in:
OLEGSHA 2020-11-08 20:22:32 +03:00
parent 09af026137
commit 88d5170fe5
6 changed files with 142 additions and 5 deletions

View File

@ -40,6 +40,7 @@ import ru.windcorp.progressia.common.collision.AABB;
import ru.windcorp.progressia.common.collision.Collideable; import ru.windcorp.progressia.common.collision.Collideable;
import ru.windcorp.progressia.common.collision.CollisionClock; import ru.windcorp.progressia.common.collision.CollisionClock;
import ru.windcorp.progressia.common.collision.CollisionModel; 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.collision.colliders.Collider;
import ru.windcorp.progressia.common.util.FloatMathUtils; import ru.windcorp.progressia.common.util.FloatMathUtils;
import ru.windcorp.progressia.common.util.Vectors; 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 Collider.ColliderWorkspace tmp_colliderWorkspace = new Collider.ColliderWorkspace();
private final List<Collideable> tmp_collideableList = new ArrayList<>(); private final List<Collideable> tmp_collideableList = new ArrayList<>();
private static final boolean RENDER_AABBS = false; private static final boolean RENDER_AABBS = true;
private void tmp_doEveryFrame() { private void tmp_doEveryFrame() {
try { try {
@ -136,6 +137,8 @@ public class LayerWorld extends Layer {
CollisionModel model = data.getCollisionModel(); CollisionModel model = data.getCollisionModel();
if (model instanceof AABB) { if (model instanceof AABB) {
AABBRenderer.renderAABB((AABB) model, helper); AABBRenderer.renderAABB((AABB) model, helper);
} else if (model instanceof CompoundCollisionModel) {
AABBRenderer.renderAABBsInCompound((CompoundCollisionModel) model, helper);
} }
} }
} }

View File

@ -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<CollisionModel> models;
public CompoundCollisionModel(Collection<CollisionModel> models) {
this.models = models;
}
public CompoundCollisionModel(CollisionModel... models) {
this(ImmutableList.copyOf(models));
}
public Collection<CollisionModel> 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);
}
}
}

View File

@ -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;
}
}

View File

@ -11,6 +11,7 @@ import ru.windcorp.progressia.common.collision.Collideable;
import ru.windcorp.progressia.common.collision.CollisionClock; import ru.windcorp.progressia.common.collision.CollisionClock;
import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.collision.CollisionModel;
import ru.windcorp.progressia.common.collision.CollisionWall; 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.LowOverheadCache;
import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.Vectors;
@ -88,7 +89,7 @@ public class Collider {
return result; return result;
} }
private static Collision getCollision( static Collision getCollision(
Collideable a, Collideable a,
Collideable b, Collideable b,
float tickLength, float tickLength,
@ -96,16 +97,44 @@ public class Collider {
) { ) {
CollisionModel aModel = a.getCollisionModel(); CollisionModel aModel = a.getCollisionModel();
CollisionModel bModel = b.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) { if (aModel instanceof AABB && bModel instanceof AABB) {
return AABBWithAABBCollider.computeModelCollision( return AABBWithAABBCollider.computeModelCollision(
a, b, aBody, bBody,
(AABB) aModel, (AABB) bModel, (AABB) aModel, (AABB) bModel,
tickLength, tickLength,
workspace 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( throw new UnsupportedOperationException(
"Collisions between " + aModel + " and " + bModel + " are not yet implemented" "Collisions between " + aModel + " and " + bModel + " are not yet implemented"
); );

View File

@ -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.texture.Texture;
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
import ru.windcorp.progressia.common.collision.AABB; import ru.windcorp.progressia.common.collision.AABB;
import ru.windcorp.progressia.common.collision.CollisionModel;
import ru.windcorp.progressia.common.collision.CompoundCollisionModel;
public class AABBRenderer { public class AABBRenderer {
@ -16,5 +18,18 @@ public class AABBRenderer {
CUBE.render(helper); CUBE.render(helper);
helper.popTransform(); 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);
}
}
}
} }

View File

@ -1,6 +1,7 @@
package ru.windcorp.progressia.test; package ru.windcorp.progressia.test;
import ru.windcorp.progressia.common.collision.AABB; 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.state.IntStateField;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
@ -11,7 +12,10 @@ public class TestEntityDataStatie extends EntityData {
public TestEntityDataStatie() { public TestEntityDataStatie() {
super("Test", "Statie"); 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); setSizeNow(16);
} }