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.KeyEvent;
|
||||
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.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;
|
||||
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 {
|
||||
|
||||
@ -128,52 +124,46 @@ public class LayerWorld extends Layer {
|
||||
private final Collider.ColliderWorkspace tmp_colliderWorkspace = new Collider.ColliderWorkspace();
|
||||
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() {
|
||||
try {
|
||||
if (RENDER_AABBS) {
|
||||
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;
|
||||
tmp_performCollisions();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
protected void handleInput(Input input) {
|
||||
if (input.isConsumed()) return;
|
||||
|
@ -1,53 +1,69 @@
|
||||
package ru.windcorp.progressia.common.collision;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
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 final Map<BlockFace, CollisionWall> faces = BlockFace.mapToFaces(
|
||||
new CollisionWall(-0.5f, -0.5f, -0.5f, +1, 0, 0, 0, 0, +1),
|
||||
new CollisionWall(+0.5f, -0.5f, -0.5f, 0, +1, 0, 0, 0, +1),
|
||||
new CollisionWall(+0.5f, +0.5f, -0.5f, -1, 0, 0, 0, 0, +1),
|
||||
new CollisionWall(-0.5f, +0.5f, -0.5f, 0, -1, 0, 0, 0, +1),
|
||||
private class AABBWallImpl implements Wall {
|
||||
|
||||
new CollisionWall(-0.5f, -0.5f, +0.5f, +1, 0, 0, 0, +1, 0),
|
||||
new CollisionWall(-0.5f, -0.5f, -0.5f, 0, +1, 0, +1, 0, 0)
|
||||
);
|
||||
private final Vec3 originOffset = new Vec3();
|
||||
private final Vec3 widthSelector = new Vec3();
|
||||
private final Vec3 heightSelector = new Vec3();
|
||||
|
||||
public AABBWallImpl(
|
||||
float ox, float oy, float oz,
|
||||
float wx, float wy, float wz,
|
||||
float hx, float hy, float hz
|
||||
) {
|
||||
this.originOffset.set(ox, oy, oz);
|
||||
this.widthSelector.set(wx, wy, wz);
|
||||
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 size = new Vec3();
|
||||
|
||||
public AABB(Vec3 origin, Vec3 size) {
|
||||
this.origin.set(origin);
|
||||
this.size.set(size);
|
||||
|
||||
for (CollisionWall wall : getFaces()) {
|
||||
wall.moveOrigin(origin);
|
||||
wall.getWidth().mul(size);
|
||||
wall.getHeight().mul(size);
|
||||
}
|
||||
this(origin.x, origin.y, origin.z, size.x, size.y, size.z);
|
||||
}
|
||||
|
||||
public AABB(
|
||||
float ox, float oy, float oz,
|
||||
float ox, float oy, float oz,
|
||||
float xSize, float ySize, float zSize
|
||||
) {
|
||||
this.origin.set(ox, oy, oz);
|
||||
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() {
|
||||
@ -55,20 +71,17 @@ public class AABB implements CollisionModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrigin(Vec3 origin) {
|
||||
for (CollisionWall wall : getFaces()) {
|
||||
wall.getOrigin().sub(this.origin).add(origin);
|
||||
}
|
||||
public void getOrigin(Vec3 output) {
|
||||
output.set(origin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrigin(Vec3 origin) {
|
||||
this.origin.set(origin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveOrigin(Vec3 displacement) {
|
||||
for (CollisionWall wall : getFaces()) {
|
||||
wall.getOrigin().add(displacement);
|
||||
}
|
||||
|
||||
this.origin.add(displacement);
|
||||
}
|
||||
|
||||
@ -76,18 +89,23 @@ public class AABB implements CollisionModel {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSize(Vec3 output) {
|
||||
output.set(size);
|
||||
}
|
||||
|
||||
public void setSize(Vec3 size) {
|
||||
setSize(size.x, size.y, size.z);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@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.vec._3.Vec3;
|
||||
import ru.windcorp.progressia.common.collision.AABB;
|
||||
import ru.windcorp.progressia.common.collision.Collideable;
|
||||
import ru.windcorp.progressia.common.collision.CollisionWall;
|
||||
import ru.windcorp.progressia.common.collision.*;
|
||||
import ru.windcorp.progressia.common.collision.colliders.Collider.ColliderWorkspace;
|
||||
import ru.windcorp.progressia.common.collision.colliders.Collider.Collision;
|
||||
import ru.windcorp.progressia.common.util.Matrices;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||
|
||||
class AABBWithAABBCollider {
|
||||
class AABBoidCollider {
|
||||
|
||||
static Collider.Collision computeModelCollision(
|
||||
Collideable aBody, Collideable bBody,
|
||||
AABB aModel, AABB bModel,
|
||||
AABBoid aModel, AABBoid bModel,
|
||||
float tickLength,
|
||||
ColliderWorkspace workspace
|
||||
) {
|
||||
Collideable obstacleBody = bBody;
|
||||
Collideable colliderBody = aBody;
|
||||
AABB obstacleModel = bModel;
|
||||
AABB colliderModel = aModel;
|
||||
AABBoid obstacleModel = bModel;
|
||||
AABBoid colliderModel = aModel;
|
||||
|
||||
Collision result = null;
|
||||
|
||||
@ -32,7 +31,8 @@ class AABBWithAABBCollider {
|
||||
computeCollisionVelocity(collisionVelocity, obstacleBody, colliderBody);
|
||||
|
||||
// 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(
|
||||
wall, colliderModel,
|
||||
@ -80,12 +80,21 @@ class AABBWithAABBCollider {
|
||||
Vectors.release(colliderVelocity);
|
||||
}
|
||||
|
||||
private static AABB createOriginCollisionSpace(AABB obstacle, AABB collider, AABB output) {
|
||||
output.setOrigin(obstacle.getOrigin());
|
||||
private static AABB createOriginCollisionSpace(AABBoid obstacle, AABBoid collider, AABB output) {
|
||||
Vec3 obstacleOrigin = Vectors.grab3();
|
||||
Vec3 obstacleSize = Vectors.grab3();
|
||||
Vec3 colliderSize = Vectors.grab3();
|
||||
|
||||
Vec3 size = Vectors.grab3().set(obstacle.getSize()).add(collider.getSize());
|
||||
output.setSize(size);
|
||||
Vectors.release(size);
|
||||
obstacle.getOrigin(obstacleOrigin);
|
||||
output.setOrigin(obstacleOrigin);
|
||||
|
||||
obstacle.getSize(obstacleSize);
|
||||
collider.getSize(colliderSize);
|
||||
output.setSize(obstacleSize.add(colliderSize));
|
||||
|
||||
Vectors.release(obstacleOrigin);
|
||||
Vectors.release(obstacleSize);
|
||||
Vectors.release(colliderSize);
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -134,27 +143,34 @@ class AABBWithAABBCollider {
|
||||
* If all conditions are satisfied, then the moment of impact is t0 + t.
|
||||
*/
|
||||
private static Collision computeWallCollision(
|
||||
CollisionWall obstacleWall,
|
||||
AABB colliderModel,
|
||||
Wall obstacleWall,
|
||||
AABBoid colliderModel,
|
||||
Vec3 collisionVelocity,
|
||||
float tickLength, ColliderWorkspace workspace,
|
||||
Collideable aBody, Collideable bBody
|
||||
) {
|
||||
Vec3 w = obstacleWall.getWidth();
|
||||
Vec3 h = obstacleWall.getHeight();
|
||||
Vec3 w = Vectors.grab3();
|
||||
Vec3 h = Vectors.grab3();
|
||||
Vec3 v = Vectors.grab3();
|
||||
Mat3 m = Matrices.grab3(); // The matrix [w h -v]
|
||||
Vec3 r = Vectors.grab3();
|
||||
Vec3 r_line = Vectors.grab3();
|
||||
Vec3 r_wall = Vectors.grab3();
|
||||
Vec3 xyt = Vectors.grab3();
|
||||
|
||||
try {
|
||||
obstacleWall.getWidth(w);
|
||||
obstacleWall.getHeight(h);
|
||||
|
||||
v.set(collisionVelocity);
|
||||
|
||||
if (isExiting(v, w, h)) {
|
||||
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());
|
||||
|
||||
if (Math.abs(m.det()) < 1e-6) {
|
||||
@ -179,9 +195,13 @@ class AABBWithAABBCollider {
|
||||
|
||||
return workspace.grab().set(aBody, bBody, obstacleWall, t);
|
||||
} finally {
|
||||
Vectors.release(w);
|
||||
Vectors.release(h);
|
||||
Vectors.release(v);
|
||||
Vectors.release(r);
|
||||
Matrices.release(m);
|
||||
Vectors.release(r);
|
||||
Vectors.release(r_line);
|
||||
Vectors.release(r_wall);
|
||||
Vectors.release(xyt);
|
||||
}
|
||||
}
|
||||
@ -193,6 +213,6 @@ class AABBWithAABBCollider {
|
||||
return result;
|
||||
}
|
||||
|
||||
private AABBWithAABBCollider() {}
|
||||
private AABBoidCollider() {}
|
||||
|
||||
}
|
@ -6,14 +6,10 @@ import java.util.List;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import glm.vec._3.Vec3;
|
||||
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.CollisionWall;
|
||||
import ru.windcorp.progressia.common.collision.CompoundCollisionModel;
|
||||
import ru.windcorp.progressia.common.collision.*;
|
||||
import ru.windcorp.progressia.common.util.LowOverheadCache;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
|
||||
public class Collider {
|
||||
|
||||
@ -21,7 +17,7 @@ public class Collider {
|
||||
|
||||
public static void performCollisions(
|
||||
List<? extends Collideable> colls,
|
||||
CollisionClock clock,
|
||||
WorldData world,
|
||||
float tickLength,
|
||||
ColliderWorkspace workspace
|
||||
) {
|
||||
@ -42,7 +38,7 @@ public class Collider {
|
||||
if (firstCollision == null) {
|
||||
break;
|
||||
} else {
|
||||
collide(firstCollision, colls, clock, tickLength, workspace);
|
||||
collide(firstCollision, colls, world, tickLength, workspace);
|
||||
workspace.release(firstCollision);
|
||||
collisionCount++;
|
||||
|
||||
@ -50,7 +46,7 @@ public class Collider {
|
||||
}
|
||||
}
|
||||
|
||||
advanceTime(colls, clock, tickLength);
|
||||
advanceTime(colls, world, tickLength);
|
||||
}
|
||||
|
||||
private static Collision getFirstCollision(
|
||||
@ -108,10 +104,10 @@ public class Collider {
|
||||
float tickLength,
|
||||
ColliderWorkspace workspace
|
||||
) {
|
||||
if (aModel instanceof AABB && bModel instanceof AABB) {
|
||||
return AABBWithAABBCollider.computeModelCollision(
|
||||
if (aModel instanceof AABBoid && bModel instanceof AABBoid) { /*replace AABB with AABBoid where makes sense, also add TranslatedAABB support in TestAABBRenderer*/
|
||||
return AABBoidCollider.computeModelCollision(
|
||||
aBody, bBody,
|
||||
(AABB) aModel, (AABB) bModel,
|
||||
(AABBoid) aModel, (AABBoid) bModel,
|
||||
tickLength,
|
||||
workspace
|
||||
);
|
||||
@ -144,11 +140,11 @@ public class Collider {
|
||||
Collision collision,
|
||||
|
||||
Collection<? extends Collideable> colls,
|
||||
CollisionClock clock,
|
||||
WorldData world,
|
||||
float tickLength,
|
||||
ColliderWorkspace workspace
|
||||
) {
|
||||
advanceTime(colls, clock, collision.time);
|
||||
advanceTime(colls, world, collision.time);
|
||||
|
||||
boolean doNotHandle = false;
|
||||
|
||||
@ -237,7 +233,7 @@ public class Collider {
|
||||
Vec3 du_a = 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.b.getCollideableVelocity(v_b);
|
||||
|
||||
@ -306,10 +302,10 @@ public class Collider {
|
||||
|
||||
private static void advanceTime(
|
||||
Collection<? extends Collideable> colls,
|
||||
CollisionClock clock,
|
||||
WorldData world,
|
||||
float step
|
||||
) {
|
||||
clock.advanceTime(step);
|
||||
world.advanceTime(step);
|
||||
|
||||
Vec3 tmp = Vectors.grab3();
|
||||
|
||||
@ -342,7 +338,9 @@ public class Collider {
|
||||
static class Collision {
|
||||
public Collideable a;
|
||||
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.
|
||||
@ -350,12 +348,15 @@ public class Collider {
|
||||
*/
|
||||
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.b = b;
|
||||
this.wall.getOrigin().set(wall.getOrigin());
|
||||
this.wall.getWidth().set(wall.getWidth());
|
||||
this.wall.getHeight().set(wall.getHeight());
|
||||
wall.getWidth(wallWidth);
|
||||
wall.getHeight(wallHeight);
|
||||
this.time = time;
|
||||
|
||||
return this;
|
||||
|
@ -30,6 +30,19 @@ import glm.vec._4.i.Vec4i;
|
||||
*/
|
||||
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 =
|
||||
new LowOverheadCache<>(Vec3i::new);
|
||||
|
||||
|
@ -42,6 +42,8 @@ public class WorldData {
|
||||
private final Collection<EntityData> entities =
|
||||
Collections.unmodifiableCollection(entitiesById.valueCollection());
|
||||
|
||||
private float time = 0;
|
||||
|
||||
public WorldData() {
|
||||
final int size = 1;
|
||||
|
||||
@ -96,4 +98,16 @@ public class WorldData {
|
||||
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.CompoundCollisionModel;
|
||||
import ru.windcorp.progressia.common.collision.TranslatedAABB;
|
||||
import ru.windcorp.progressia.common.state.IntStateField;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||
|
||||
@ -14,7 +15,7 @@ public class TestEntityDataStatie extends EntityData {
|
||||
super("Test", "Statie");
|
||||
setCollisionModel(new CompoundCollisionModel(
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user