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

View File

@ -1,93 +1,111 @@
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 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(
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),
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)
);
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() {
return origin;
}
@Override
public void getOrigin(Vec3 output) {
output.set(origin);
}
@Override
public void setOrigin(Vec3 origin) {
for (CollisionWall wall : getFaces()) {
wall.getOrigin().sub(this.origin).add(origin);
}
this.origin.set(origin);
}
@Override
public void moveOrigin(Vec3 displacement) {
for (CollisionWall wall : getFaces()) {
wall.getOrigin().add(displacement);
}
this.origin.add(displacement);
}
public Vec3 getSize() {
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];
}
}

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

View File

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

View File

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

View File

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

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