Increased encapsulation of AABBs and added TranslatedAABB
- Interface of AABB (getOrigin(), getSize() and getWall(int)) now extracted into AABBoid interface - Same with Walls - Collection<Wall> getWalls() replaced with Wall getWall(int) - Added TranslatedAABB extends AABBoid - CollisionClock replaced with direct reference to WorldData - Reorganized tmp code in LayerWorld, so as to decrease cRiNgE_ levels
This commit is contained in:
parent
88d5170fe5
commit
0dd5e6d3da
@ -36,16 +36,12 @@ import ru.windcorp.progressia.client.graphics.input.CursorMoveEvent;
|
|||||||
import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
||||||
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
||||||
import ru.windcorp.progressia.client.graphics.input.bus.Input;
|
import ru.windcorp.progressia.client.graphics.input.bus.Input;
|
||||||
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.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;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
import ru.windcorp.progressia.test.AABBRenderer;
|
import ru.windcorp.progressia.test.CollisionModelRenderer;
|
||||||
|
|
||||||
public class LayerWorld extends Layer {
|
public class LayerWorld extends Layer {
|
||||||
|
|
||||||
@ -128,52 +124,46 @@ 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 = true;
|
private static final boolean RENDER_COLLISION_MODELS = true;
|
||||||
|
|
||||||
private void tmp_doEveryFrame() {
|
private void tmp_doEveryFrame() {
|
||||||
try {
|
try {
|
||||||
if (RENDER_AABBS) {
|
tmp_performCollisions();
|
||||||
for (EntityData data : this.client.getWorld().getData().getEntities()) {
|
|
||||||
CollisionModel model = data.getCollisionModel();
|
|
||||||
if (model instanceof AABB) {
|
|
||||||
AABBRenderer.renderAABB((AABB) model, helper);
|
|
||||||
} else if (model instanceof CompoundCollisionModel) {
|
|
||||||
AABBRenderer.renderAABBsInCompound((CompoundCollisionModel) model, helper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_collideableList.clear();
|
|
||||||
tmp_collideableList.addAll(this.client.getWorld().getData().getEntities());
|
|
||||||
|
|
||||||
Collider.performCollisions(
|
|
||||||
tmp_collideableList,
|
|
||||||
new CollisionClock() {
|
|
||||||
private float t = 0;
|
|
||||||
@Override
|
|
||||||
public float getTime() {
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void advanceTime(float change) {
|
|
||||||
t += change;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(float) GraphicsInterface.getFrameLength(),
|
|
||||||
tmp_colliderWorkspace
|
|
||||||
);
|
|
||||||
|
|
||||||
final float frictionCoeff = 1 - 1e-2f;
|
|
||||||
|
|
||||||
for (EntityData data : this.client.getWorld().getData().getEntities()) {
|
for (EntityData data : this.client.getWorld().getData().getEntities()) {
|
||||||
data.getVelocity().mul(frictionCoeff);
|
tmp_applyFriction(data);
|
||||||
|
tmp_renderCollisionModel(data);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.println("OLEGSHA is to blame. Tell him he vry stupiDD!!");
|
||||||
System.exit(31337);
|
System.exit(31337);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tmp_renderCollisionModel(EntityData entity) {
|
||||||
|
if (RENDER_COLLISION_MODELS) {
|
||||||
|
CollisionModelRenderer.renderCollisionModel(entity.getCollisionModel(), helper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tmp_performCollisions() {
|
||||||
|
tmp_collideableList.clear();
|
||||||
|
tmp_collideableList.addAll(this.client.getWorld().getData().getEntities());
|
||||||
|
|
||||||
|
Collider.performCollisions(
|
||||||
|
tmp_collideableList,
|
||||||
|
this.client.getWorld().getData(),
|
||||||
|
(float) GraphicsInterface.getFrameLength(),
|
||||||
|
tmp_colliderWorkspace
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tmp_applyFriction(EntityData entity) {
|
||||||
|
final float frictionCoeff = 1 - 1e-2f;
|
||||||
|
entity.getVelocity().mul(frictionCoeff);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleInput(Input input) {
|
protected void handleInput(Input input) {
|
||||||
if (input.isConsumed()) return;
|
if (input.isConsumed()) return;
|
||||||
|
@ -1,93 +1,111 @@
|
|||||||
package ru.windcorp.progressia.common.collision;
|
package ru.windcorp.progressia.common.collision;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import ru.windcorp.progressia.common.world.block.BlockFace;
|
|
||||||
|
|
||||||
public class AABB implements CollisionModel {
|
/**
|
||||||
|
* An implementation of an
|
||||||
|
* <a href="https://en.wikipedia.org/wiki/Minimum_bounding_box#Axis-aligned_minimum_bounding_box">Axis-Aligned Bounding Box</a>.
|
||||||
|
* @author javapony
|
||||||
|
*/
|
||||||
|
public class AABB implements AABBoid {
|
||||||
|
|
||||||
|
private class AABBWallImpl implements Wall {
|
||||||
|
|
||||||
|
private final Vec3 originOffset = new Vec3();
|
||||||
|
private final Vec3 widthSelector = new Vec3();
|
||||||
|
private final Vec3 heightSelector = new Vec3();
|
||||||
|
|
||||||
private final Map<BlockFace, CollisionWall> faces = BlockFace.mapToFaces(
|
public AABBWallImpl(
|
||||||
new CollisionWall(-0.5f, -0.5f, -0.5f, +1, 0, 0, 0, 0, +1),
|
float ox, float oy, float oz,
|
||||||
new CollisionWall(+0.5f, -0.5f, -0.5f, 0, +1, 0, 0, 0, +1),
|
float wx, float wy, float wz,
|
||||||
new CollisionWall(+0.5f, +0.5f, -0.5f, -1, 0, 0, 0, 0, +1),
|
float hx, float hy, float hz
|
||||||
new CollisionWall(-0.5f, +0.5f, -0.5f, 0, -1, 0, 0, 0, +1),
|
) {
|
||||||
|
this.originOffset.set(ox, oy, oz);
|
||||||
new CollisionWall(-0.5f, -0.5f, +0.5f, +1, 0, 0, 0, +1, 0),
|
this.widthSelector.set(wx, wy, wz);
|
||||||
new CollisionWall(-0.5f, -0.5f, -0.5f, 0, +1, 0, +1, 0, 0)
|
this.heightSelector.set(hx, hy, hz);
|
||||||
);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getOrigin(Vec3 output) {
|
||||||
|
output.set(originOffset).mul(AABB.this.getSize()).add(AABB.this.getOrigin());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getWidth(Vec3 output) {
|
||||||
|
output.set(AABB.this.getSize()).mul(widthSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getHeight(Vec3 output) {
|
||||||
|
output.set(AABB.this.getSize()).mul(heightSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Wall[] walls = new Wall[] {
|
||||||
|
new AABBWallImpl(-0.5f, -0.5f, +0.5f, +1, 0, 0, 0, +1, 0), // Top
|
||||||
|
new AABBWallImpl(-0.5f, -0.5f, -0.5f, 0, +1, 0, +1, 0, 0), // Bottom
|
||||||
|
new AABBWallImpl(+0.5f, -0.5f, -0.5f, 0, +1, 0, 0, 0, +1), // North
|
||||||
|
new AABBWallImpl(-0.5f, +0.5f, -0.5f, 0, -1, 0, 0, 0, +1), // South
|
||||||
|
new AABBWallImpl(+0.5f, +0.5f, -0.5f, -1, 0, 0, 0, 0, +1), // West
|
||||||
|
new AABBWallImpl(-0.5f, -0.5f, -0.5f, +1, 0, 0, 0, 0, +1) // East
|
||||||
|
};
|
||||||
|
|
||||||
private final Vec3 origin = new Vec3();
|
private final Vec3 origin = new Vec3();
|
||||||
private final Vec3 size = new Vec3();
|
private final Vec3 size = new Vec3();
|
||||||
|
|
||||||
public AABB(Vec3 origin, Vec3 size) {
|
public AABB(Vec3 origin, Vec3 size) {
|
||||||
this.origin.set(origin);
|
this(origin.x, origin.y, origin.z, size.x, size.y, size.z);
|
||||||
this.size.set(size);
|
|
||||||
|
|
||||||
for (CollisionWall wall : getFaces()) {
|
|
||||||
wall.moveOrigin(origin);
|
|
||||||
wall.getWidth().mul(size);
|
|
||||||
wall.getHeight().mul(size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AABB(
|
public AABB(
|
||||||
float ox, float oy, float oz,
|
float ox, float oy, float oz,
|
||||||
float xSize, float ySize, float zSize
|
float xSize, float ySize, float zSize
|
||||||
) {
|
) {
|
||||||
this.origin.set(ox, oy, oz);
|
this.origin.set(ox, oy, oz);
|
||||||
this.size.set(xSize, ySize, zSize);
|
this.size.set(xSize, ySize, zSize);
|
||||||
|
|
||||||
for (CollisionWall wall : getFaces()) {
|
|
||||||
wall.moveOrigin(ox, oy, oz);
|
|
||||||
wall.getWidth().mul(xSize, ySize, zSize);
|
|
||||||
wall.getHeight().mul(xSize, ySize, zSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<CollisionWall> getFaces() {
|
|
||||||
return faces.values();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3 getOrigin() {
|
public Vec3 getOrigin() {
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getOrigin(Vec3 output) {
|
||||||
|
output.set(origin);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOrigin(Vec3 origin) {
|
public void setOrigin(Vec3 origin) {
|
||||||
for (CollisionWall wall : getFaces()) {
|
|
||||||
wall.getOrigin().sub(this.origin).add(origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.origin.set(origin);
|
this.origin.set(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveOrigin(Vec3 displacement) {
|
public void moveOrigin(Vec3 displacement) {
|
||||||
for (CollisionWall wall : getFaces()) {
|
|
||||||
wall.getOrigin().add(displacement);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.origin.add(displacement);
|
this.origin.add(displacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3 getSize() {
|
public Vec3 getSize() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getSize(Vec3 output) {
|
||||||
|
output.set(size);
|
||||||
|
}
|
||||||
|
|
||||||
public void setSize(Vec3 size) {
|
public void setSize(Vec3 size) {
|
||||||
setSize(size.x, size.y, size.z);
|
setSize(size.x, size.y, size.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSize(float xSize, float ySize, float zSize) {
|
public void setSize(float xSize, float ySize, float zSize) {
|
||||||
for (CollisionWall wall : getFaces()) {
|
|
||||||
wall.getWidth().div(this.size).mul(xSize, ySize, zSize);
|
|
||||||
wall.getHeight().div(this.size).mul(xSize, ySize, zSize);
|
|
||||||
wall.getOrigin().sub(getOrigin()).div(this.size).mul(xSize, ySize, zSize).add(getOrigin());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.size.set(xSize, ySize, zSize);
|
this.size.set(xSize, ySize, zSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Wall getWall(int faceId) {
|
||||||
|
// No, we don't support Apple.
|
||||||
|
return walls[faceId];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package ru.windcorp.progressia.common.collision;
|
||||||
|
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||||
|
|
||||||
|
public interface AABBoid extends CollisionModel {
|
||||||
|
|
||||||
|
void getOrigin(Vec3 output);
|
||||||
|
void getSize(Vec3 output);
|
||||||
|
|
||||||
|
default Wall getWall(BlockFace face) {
|
||||||
|
return getWall(face.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
Wall getWall(int faceId);
|
||||||
|
|
||||||
|
}
|
@ -1,8 +0,0 @@
|
|||||||
package ru.windcorp.progressia.common.collision;
|
|
||||||
|
|
||||||
public interface CollisionClock {
|
|
||||||
|
|
||||||
float getTime();
|
|
||||||
void advanceTime(float change);
|
|
||||||
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package ru.windcorp.progressia.common.collision;
|
|
||||||
|
|
||||||
import glm.vec._3.Vec3;
|
|
||||||
|
|
||||||
public class CollisionWall {
|
|
||||||
|
|
||||||
private final Vec3 origin = new Vec3();
|
|
||||||
private final Vec3 width = new Vec3();
|
|
||||||
private final Vec3 height = new Vec3();
|
|
||||||
|
|
||||||
public CollisionWall(Vec3 origin, Vec3 width, Vec3 height) {
|
|
||||||
this.origin.set(origin);
|
|
||||||
this.width.set(width);
|
|
||||||
this.height.set(height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollisionWall(
|
|
||||||
float ox, float oy, float oz,
|
|
||||||
float wx, float wy, float wz,
|
|
||||||
float hx, float hy, float hz
|
|
||||||
) {
|
|
||||||
this.origin.set(ox, oy, oz);
|
|
||||||
this.width.set(wx, wy, wz);
|
|
||||||
this.height.set(hx, hy, hz);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3 getOrigin() {
|
|
||||||
return origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3 getWidth() {
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3 getHeight() {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrigin(Vec3 origin) {
|
|
||||||
setOrigin(origin.x, origin.y, origin.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrigin(float x, float y, float z) {
|
|
||||||
this.origin.set(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void moveOrigin(Vec3 displacement) {
|
|
||||||
moveOrigin(displacement.x, displacement.y, displacement.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void moveOrigin(float dx, float dy, float dz) {
|
|
||||||
this.origin.add(dx, dy, dz);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,105 @@
|
|||||||
|
package ru.windcorp.progressia.common.collision;
|
||||||
|
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
|
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||||
|
|
||||||
|
public class TranslatedAABB implements AABBoid {
|
||||||
|
|
||||||
|
private class TranslatedAABBWall implements Wall {
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
public TranslatedAABBWall(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getOrigin(Vec3 output) {
|
||||||
|
parent.getWall(id).getOrigin(output);
|
||||||
|
output.add(translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getWidth(Vec3 output) {
|
||||||
|
parent.getWall(id).getWidth(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getHeight(Vec3 output) {
|
||||||
|
parent.getWall(id).getHeight(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AABBoid parent;
|
||||||
|
private final Vec3 translation = new Vec3();
|
||||||
|
|
||||||
|
private final TranslatedAABBWall[] walls = new TranslatedAABBWall[BlockFace.BLOCK_FACE_COUNT];
|
||||||
|
|
||||||
|
{
|
||||||
|
for (int id = 0; id < walls.length; ++id) {
|
||||||
|
walls[id] = new TranslatedAABBWall(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranslatedAABB(AABBoid parent, float tx, float ty, float tz) {
|
||||||
|
setParent(parent);
|
||||||
|
setTranslation(tx, ty, tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranslatedAABB(AABBoid parent, Vec3 translation) {
|
||||||
|
this(parent, translation.x, translation.y, translation.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TranslatedAABB() {
|
||||||
|
this(null, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOrigin(Vec3 origin) {
|
||||||
|
Vec3 v = Vectors.grab3().set(origin).sub(translation);
|
||||||
|
parent.setOrigin(v);
|
||||||
|
Vectors.release(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveOrigin(Vec3 displacement) {
|
||||||
|
parent.moveOrigin(displacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getOrigin(Vec3 output) {
|
||||||
|
parent.getOrigin(output);
|
||||||
|
output.add(translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getSize(Vec3 output) {
|
||||||
|
parent.getSize(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Wall getWall(int faceId) {
|
||||||
|
return walls[faceId];
|
||||||
|
}
|
||||||
|
|
||||||
|
public AABBoid getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParent(AABBoid parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 getTranslation() {
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTranslation(Vec3 translation) {
|
||||||
|
setTranslation(translation.x, translation.y, translation.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTranslation(float tx, float ty, float tz) {
|
||||||
|
this.translation.set(tx, ty, tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package ru.windcorp.progressia.common.collision;
|
||||||
|
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
|
||||||
|
public interface Wall {
|
||||||
|
|
||||||
|
void getOrigin(Vec3 output);
|
||||||
|
|
||||||
|
void getWidth(Vec3 output);
|
||||||
|
void getHeight(Vec3 output);
|
||||||
|
|
||||||
|
}
|
@ -2,26 +2,25 @@ package ru.windcorp.progressia.common.collision.colliders;
|
|||||||
|
|
||||||
import glm.mat._3.Mat3;
|
import glm.mat._3.Mat3;
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import ru.windcorp.progressia.common.collision.AABB;
|
import ru.windcorp.progressia.common.collision.*;
|
||||||
import ru.windcorp.progressia.common.collision.Collideable;
|
|
||||||
import ru.windcorp.progressia.common.collision.CollisionWall;
|
|
||||||
import ru.windcorp.progressia.common.collision.colliders.Collider.ColliderWorkspace;
|
import ru.windcorp.progressia.common.collision.colliders.Collider.ColliderWorkspace;
|
||||||
import ru.windcorp.progressia.common.collision.colliders.Collider.Collision;
|
import ru.windcorp.progressia.common.collision.colliders.Collider.Collision;
|
||||||
import ru.windcorp.progressia.common.util.Matrices;
|
import ru.windcorp.progressia.common.util.Matrices;
|
||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
|
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||||
|
|
||||||
class AABBWithAABBCollider {
|
class AABBoidCollider {
|
||||||
|
|
||||||
static Collider.Collision computeModelCollision(
|
static Collider.Collision computeModelCollision(
|
||||||
Collideable aBody, Collideable bBody,
|
Collideable aBody, Collideable bBody,
|
||||||
AABB aModel, AABB bModel,
|
AABBoid aModel, AABBoid bModel,
|
||||||
float tickLength,
|
float tickLength,
|
||||||
ColliderWorkspace workspace
|
ColliderWorkspace workspace
|
||||||
) {
|
) {
|
||||||
Collideable obstacleBody = bBody;
|
Collideable obstacleBody = bBody;
|
||||||
Collideable colliderBody = aBody;
|
Collideable colliderBody = aBody;
|
||||||
AABB obstacleModel = bModel;
|
AABBoid obstacleModel = bModel;
|
||||||
AABB colliderModel = aModel;
|
AABBoid colliderModel = aModel;
|
||||||
|
|
||||||
Collision result = null;
|
Collision result = null;
|
||||||
|
|
||||||
@ -32,7 +31,8 @@ class AABBWithAABBCollider {
|
|||||||
computeCollisionVelocity(collisionVelocity, obstacleBody, colliderBody);
|
computeCollisionVelocity(collisionVelocity, obstacleBody, colliderBody);
|
||||||
|
|
||||||
// For every wall of collision space
|
// For every wall of collision space
|
||||||
for (CollisionWall wall : originCollisionSpace.getFaces()) {
|
for (int i = 0; i < BlockFace.BLOCK_FACE_COUNT; ++i) {
|
||||||
|
Wall wall = originCollisionSpace.getWall(i);
|
||||||
|
|
||||||
Collision collision = computeWallCollision(
|
Collision collision = computeWallCollision(
|
||||||
wall, colliderModel,
|
wall, colliderModel,
|
||||||
@ -80,12 +80,21 @@ class AABBWithAABBCollider {
|
|||||||
Vectors.release(colliderVelocity);
|
Vectors.release(colliderVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AABB createOriginCollisionSpace(AABB obstacle, AABB collider, AABB output) {
|
private static AABB createOriginCollisionSpace(AABBoid obstacle, AABBoid collider, AABB output) {
|
||||||
output.setOrigin(obstacle.getOrigin());
|
Vec3 obstacleOrigin = Vectors.grab3();
|
||||||
|
Vec3 obstacleSize = Vectors.grab3();
|
||||||
|
Vec3 colliderSize = Vectors.grab3();
|
||||||
|
|
||||||
Vec3 size = Vectors.grab3().set(obstacle.getSize()).add(collider.getSize());
|
obstacle.getOrigin(obstacleOrigin);
|
||||||
output.setSize(size);
|
output.setOrigin(obstacleOrigin);
|
||||||
Vectors.release(size);
|
|
||||||
|
obstacle.getSize(obstacleSize);
|
||||||
|
collider.getSize(colliderSize);
|
||||||
|
output.setSize(obstacleSize.add(colliderSize));
|
||||||
|
|
||||||
|
Vectors.release(obstacleOrigin);
|
||||||
|
Vectors.release(obstacleSize);
|
||||||
|
Vectors.release(colliderSize);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@ -134,27 +143,34 @@ class AABBWithAABBCollider {
|
|||||||
* If all conditions are satisfied, then the moment of impact is t0 + t.
|
* If all conditions are satisfied, then the moment of impact is t0 + t.
|
||||||
*/
|
*/
|
||||||
private static Collision computeWallCollision(
|
private static Collision computeWallCollision(
|
||||||
CollisionWall obstacleWall,
|
Wall obstacleWall,
|
||||||
AABB colliderModel,
|
AABBoid colliderModel,
|
||||||
Vec3 collisionVelocity,
|
Vec3 collisionVelocity,
|
||||||
float tickLength, ColliderWorkspace workspace,
|
float tickLength, ColliderWorkspace workspace,
|
||||||
Collideable aBody, Collideable bBody
|
Collideable aBody, Collideable bBody
|
||||||
) {
|
) {
|
||||||
Vec3 w = obstacleWall.getWidth();
|
Vec3 w = Vectors.grab3();
|
||||||
Vec3 h = obstacleWall.getHeight();
|
Vec3 h = Vectors.grab3();
|
||||||
Vec3 v = Vectors.grab3();
|
Vec3 v = Vectors.grab3();
|
||||||
Mat3 m = Matrices.grab3(); // The matrix [w h -v]
|
Mat3 m = Matrices.grab3(); // The matrix [w h -v]
|
||||||
Vec3 r = Vectors.grab3();
|
Vec3 r = Vectors.grab3();
|
||||||
|
Vec3 r_line = Vectors.grab3();
|
||||||
|
Vec3 r_wall = Vectors.grab3();
|
||||||
Vec3 xyt = Vectors.grab3();
|
Vec3 xyt = Vectors.grab3();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
obstacleWall.getWidth(w);
|
||||||
|
obstacleWall.getHeight(h);
|
||||||
|
|
||||||
v.set(collisionVelocity);
|
v.set(collisionVelocity);
|
||||||
|
|
||||||
if (isExiting(v, w, h)) {
|
if (isExiting(v, w, h)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
r.set(colliderModel.getOrigin()).sub(obstacleWall.getOrigin());
|
obstacleWall.getOrigin(r_wall);
|
||||||
|
colliderModel.getOrigin(r_line);
|
||||||
|
r.set(r_line).sub(r_wall);
|
||||||
m.c0(w).c1(h).c2(v.negate());
|
m.c0(w).c1(h).c2(v.negate());
|
||||||
|
|
||||||
if (Math.abs(m.det()) < 1e-6) {
|
if (Math.abs(m.det()) < 1e-6) {
|
||||||
@ -179,9 +195,13 @@ class AABBWithAABBCollider {
|
|||||||
|
|
||||||
return workspace.grab().set(aBody, bBody, obstacleWall, t);
|
return workspace.grab().set(aBody, bBody, obstacleWall, t);
|
||||||
} finally {
|
} finally {
|
||||||
|
Vectors.release(w);
|
||||||
|
Vectors.release(h);
|
||||||
Vectors.release(v);
|
Vectors.release(v);
|
||||||
Vectors.release(r);
|
|
||||||
Matrices.release(m);
|
Matrices.release(m);
|
||||||
|
Vectors.release(r);
|
||||||
|
Vectors.release(r_line);
|
||||||
|
Vectors.release(r_wall);
|
||||||
Vectors.release(xyt);
|
Vectors.release(xyt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,6 +213,6 @@ class AABBWithAABBCollider {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AABBWithAABBCollider() {}
|
private AABBoidCollider() {}
|
||||||
|
|
||||||
}
|
}
|
@ -6,14 +6,10 @@ import java.util.List;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import ru.windcorp.progressia.common.collision.AABB;
|
import ru.windcorp.progressia.common.collision.*;
|
||||||
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.LowOverheadCache;
|
||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
|
import ru.windcorp.progressia.common.world.WorldData;
|
||||||
|
|
||||||
public class Collider {
|
public class Collider {
|
||||||
|
|
||||||
@ -21,7 +17,7 @@ public class Collider {
|
|||||||
|
|
||||||
public static void performCollisions(
|
public static void performCollisions(
|
||||||
List<? extends Collideable> colls,
|
List<? extends Collideable> colls,
|
||||||
CollisionClock clock,
|
WorldData world,
|
||||||
float tickLength,
|
float tickLength,
|
||||||
ColliderWorkspace workspace
|
ColliderWorkspace workspace
|
||||||
) {
|
) {
|
||||||
@ -42,7 +38,7 @@ public class Collider {
|
|||||||
if (firstCollision == null) {
|
if (firstCollision == null) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
collide(firstCollision, colls, clock, tickLength, workspace);
|
collide(firstCollision, colls, world, tickLength, workspace);
|
||||||
workspace.release(firstCollision);
|
workspace.release(firstCollision);
|
||||||
collisionCount++;
|
collisionCount++;
|
||||||
|
|
||||||
@ -50,7 +46,7 @@ public class Collider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
advanceTime(colls, clock, tickLength);
|
advanceTime(colls, world, tickLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Collision getFirstCollision(
|
private static Collision getFirstCollision(
|
||||||
@ -108,10 +104,10 @@ public class Collider {
|
|||||||
float tickLength,
|
float tickLength,
|
||||||
ColliderWorkspace workspace
|
ColliderWorkspace workspace
|
||||||
) {
|
) {
|
||||||
if (aModel instanceof AABB && bModel instanceof AABB) {
|
if (aModel instanceof AABBoid && bModel instanceof AABBoid) { /*replace AABB with AABBoid where makes sense, also add TranslatedAABB support in TestAABBRenderer*/
|
||||||
return AABBWithAABBCollider.computeModelCollision(
|
return AABBoidCollider.computeModelCollision(
|
||||||
aBody, bBody,
|
aBody, bBody,
|
||||||
(AABB) aModel, (AABB) bModel,
|
(AABBoid) aModel, (AABBoid) bModel,
|
||||||
tickLength,
|
tickLength,
|
||||||
workspace
|
workspace
|
||||||
);
|
);
|
||||||
@ -144,11 +140,11 @@ public class Collider {
|
|||||||
Collision collision,
|
Collision collision,
|
||||||
|
|
||||||
Collection<? extends Collideable> colls,
|
Collection<? extends Collideable> colls,
|
||||||
CollisionClock clock,
|
WorldData world,
|
||||||
float tickLength,
|
float tickLength,
|
||||||
ColliderWorkspace workspace
|
ColliderWorkspace workspace
|
||||||
) {
|
) {
|
||||||
advanceTime(colls, clock, collision.time);
|
advanceTime(colls, world, collision.time);
|
||||||
|
|
||||||
boolean doNotHandle = false;
|
boolean doNotHandle = false;
|
||||||
|
|
||||||
@ -237,7 +233,7 @@ public class Collider {
|
|||||||
Vec3 du_a = Vectors.grab3();
|
Vec3 du_a = Vectors.grab3();
|
||||||
Vec3 du_b = Vectors.grab3();
|
Vec3 du_b = Vectors.grab3();
|
||||||
|
|
||||||
n.set(collision.wall.getWidth()).cross(collision.wall.getHeight()).normalize();
|
n.set(collision.wallWidth).cross(collision.wallHeight).normalize();
|
||||||
collision.a.getCollideableVelocity(v_a);
|
collision.a.getCollideableVelocity(v_a);
|
||||||
collision.b.getCollideableVelocity(v_b);
|
collision.b.getCollideableVelocity(v_b);
|
||||||
|
|
||||||
@ -306,10 +302,10 @@ public class Collider {
|
|||||||
|
|
||||||
private static void advanceTime(
|
private static void advanceTime(
|
||||||
Collection<? extends Collideable> colls,
|
Collection<? extends Collideable> colls,
|
||||||
CollisionClock clock,
|
WorldData world,
|
||||||
float step
|
float step
|
||||||
) {
|
) {
|
||||||
clock.advanceTime(step);
|
world.advanceTime(step);
|
||||||
|
|
||||||
Vec3 tmp = Vectors.grab3();
|
Vec3 tmp = Vectors.grab3();
|
||||||
|
|
||||||
@ -342,7 +338,9 @@ public class Collider {
|
|||||||
static class Collision {
|
static class Collision {
|
||||||
public Collideable a;
|
public Collideable a;
|
||||||
public Collideable b;
|
public Collideable b;
|
||||||
public final CollisionWall wall = new CollisionWall(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
||||||
|
public final Vec3 wallWidth = new Vec3();
|
||||||
|
public final Vec3 wallHeight = new Vec3();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time offset from the start of the tick.
|
* Time offset from the start of the tick.
|
||||||
@ -350,12 +348,15 @@ public class Collider {
|
|||||||
*/
|
*/
|
||||||
public float time;
|
public float time;
|
||||||
|
|
||||||
public Collision set(Collideable a, Collideable b, CollisionWall wall, float time) {
|
public Collision set(
|
||||||
|
Collideable a, Collideable b,
|
||||||
|
Wall wall,
|
||||||
|
float time
|
||||||
|
) {
|
||||||
this.a = a;
|
this.a = a;
|
||||||
this.b = b;
|
this.b = b;
|
||||||
this.wall.getOrigin().set(wall.getOrigin());
|
wall.getWidth(wallWidth);
|
||||||
this.wall.getWidth().set(wall.getWidth());
|
wall.getHeight(wallHeight);
|
||||||
this.wall.getHeight().set(wall.getHeight());
|
|
||||||
this.time = time;
|
this.time = time;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -30,6 +30,19 @@ import glm.vec._4.i.Vec4i;
|
|||||||
*/
|
*/
|
||||||
public class Vectors {
|
public class Vectors {
|
||||||
|
|
||||||
|
public static final Vec2 ZERO_2 = new Vec2 (0, 0);
|
||||||
|
public static final Vec2i ZERO_2i = new Vec2i(0, 0);
|
||||||
|
public static final Vec3 ZERO_3 = new Vec3 (0, 0, 0);
|
||||||
|
public static final Vec3i ZERO_3i = new Vec3i(0, 0, 0);
|
||||||
|
public static final Vec4 ZERO_4 = new Vec4 (0, 0, 0, 0);
|
||||||
|
public static final Vec4i ZERO_4i = new Vec4i(0, 0, 0, 0);
|
||||||
|
public static final Vec2 UNIT_2 = new Vec2 (1, 1);
|
||||||
|
public static final Vec2i UNIT_2i = new Vec2i(1, 1);
|
||||||
|
public static final Vec3 UNIT_3 = new Vec3 (1, 1, 1);
|
||||||
|
public static final Vec3i UNIT_3i = new Vec3i(1, 1, 1);
|
||||||
|
public static final Vec4 UNIT_4 = new Vec4 (1, 1, 1, 1);
|
||||||
|
public static final Vec4i UNIT_4i = new Vec4i(1, 1, 1, 1);
|
||||||
|
|
||||||
private static final LowOverheadCache<Vec3i> VEC3IS =
|
private static final LowOverheadCache<Vec3i> VEC3IS =
|
||||||
new LowOverheadCache<>(Vec3i::new);
|
new LowOverheadCache<>(Vec3i::new);
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ public class WorldData {
|
|||||||
private final Collection<EntityData> entities =
|
private final Collection<EntityData> entities =
|
||||||
Collections.unmodifiableCollection(entitiesById.valueCollection());
|
Collections.unmodifiableCollection(entitiesById.valueCollection());
|
||||||
|
|
||||||
|
private float time = 0;
|
||||||
|
|
||||||
public WorldData() {
|
public WorldData() {
|
||||||
final int size = 1;
|
final int size = 1;
|
||||||
|
|
||||||
@ -96,4 +98,16 @@ public class WorldData {
|
|||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void advanceTime(float change) {
|
||||||
|
this.time += change;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public CollisionModel getCollisionModelOfBlock(Vec3i blockInWorld) {
|
||||||
|
// Vec3i
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
package ru.windcorp.progressia.test;
|
|
||||||
|
|
||||||
import ru.windcorp.progressia.client.graphics.model.Shape;
|
|
||||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
|
||||||
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 {
|
|
||||||
|
|
||||||
private static final Shape CUBE = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), (Texture) null).setColorMultiplier(1.0f, 0.7f, 0.2f).create();
|
|
||||||
|
|
||||||
public static void renderAABB(AABB aabb, ShapeRenderHelper helper) {
|
|
||||||
helper.pushTransform().translate(aabb.getOrigin()).scale(aabb.getSize());
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,61 @@
|
|||||||
|
package ru.windcorp.progressia.test;
|
||||||
|
|
||||||
|
import glm.mat._4.Mat4;
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import glm.vec._3.i.Vec3i;
|
||||||
|
import ru.windcorp.progressia.client.graphics.model.Shape;
|
||||||
|
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
||||||
|
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.AABBoid;
|
||||||
|
import ru.windcorp.progressia.common.collision.CollisionModel;
|
||||||
|
import ru.windcorp.progressia.common.collision.CompoundCollisionModel;
|
||||||
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
|
|
||||||
|
public class CollisionModelRenderer {
|
||||||
|
|
||||||
|
private static final Shape CUBE = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), (Texture) null).setColorMultiplier(1.0f, 0.7f, 0.2f).create();
|
||||||
|
private static final Shape CUBE_GRAY = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), (Texture) null).setColorMultiplier(0.5f, 0.5f, 0.5f).create();
|
||||||
|
|
||||||
|
public static void renderCollisionModel(CollisionModel model, ShapeRenderHelper helper) {
|
||||||
|
if (model instanceof AABBoid) {
|
||||||
|
renderAABBoid((AABBoid) model, helper);
|
||||||
|
} else if (model instanceof CompoundCollisionModel) {
|
||||||
|
renderCompound((CompoundCollisionModel) model, helper);
|
||||||
|
} else {
|
||||||
|
// Ignore silently
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void renderAABBoid(AABBoid aabb, ShapeRenderHelper helper) {
|
||||||
|
Mat4 mat = helper.pushTransform();
|
||||||
|
Vec3 tmp = Vectors.grab3();
|
||||||
|
|
||||||
|
aabb.getOrigin(tmp);
|
||||||
|
mat.translate(tmp);
|
||||||
|
aabb.getSize(tmp);
|
||||||
|
mat.scale(tmp);
|
||||||
|
|
||||||
|
Vectors.release(tmp);
|
||||||
|
|
||||||
|
CUBE.render(helper);
|
||||||
|
helper.popTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void renderCompound(
|
||||||
|
CompoundCollisionModel model,
|
||||||
|
ShapeRenderHelper helper
|
||||||
|
) {
|
||||||
|
for (CollisionModel part : model.getModels()) {
|
||||||
|
renderCollisionModel(part, helper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderBlock(Vec3i coords, ShapeRenderHelper helper) {
|
||||||
|
helper.pushTransform().translate(coords.x, coords.y, coords.z);
|
||||||
|
CUBE_GRAY.render(helper);
|
||||||
|
helper.popTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@ 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.collision.CompoundCollisionModel;
|
||||||
|
import ru.windcorp.progressia.common.collision.TranslatedAABB;
|
||||||
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;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ public class TestEntityDataStatie extends EntityData {
|
|||||||
super("Test", "Statie");
|
super("Test", "Statie");
|
||||||
setCollisionModel(new CompoundCollisionModel(
|
setCollisionModel(new CompoundCollisionModel(
|
||||||
new AABB(0, 0, 0, 1, 1, 1 ),
|
new AABB(0, 0, 0, 1, 1, 1 ),
|
||||||
new AABB(0, 0, 0.7f, 0.6f, 0.6f, 0.6f)
|
new TranslatedAABB(new AABB(0, 0, 0.7f, 0.6f, 0.6f, 0.6f), 0, 0, 1)
|
||||||
));
|
));
|
||||||
setSizeNow(16);
|
setSizeNow(16);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user