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:
OLEGSHA 2020-11-12 23:13:41 +03:00
parent 88d5170fe5
commit 0dd5e6d3da
14 changed files with 383 additions and 229 deletions

View File

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

View File

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

View File

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

View File

@ -1,8 +0,0 @@
package ru.windcorp.progressia.common.collision;
public interface CollisionClock {
float getTime();
void advanceTime(float change);
}

View File

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

View File

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

View File

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

View File

@ -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() {}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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