diff --git a/.gitignore b/.gitignore index 5240822ae..d4458fd04 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,6 @@ hs_err_pid* #Eclipse workspace/projects files .metadata/ -.recommenders/ \ No newline at end of file +.recommenders/ + +cubyz-client/logs/ \ No newline at end of file diff --git a/cubyz-common/src/io/cubyz/entity/Entity.java b/cubyz-common/src/io/cubyz/entity/Entity.java index 320c322a2..c415ee391 100644 --- a/cubyz-common/src/io/cubyz/entity/Entity.java +++ b/cubyz-common/src/io/cubyz/entity/Entity.java @@ -6,6 +6,7 @@ import org.joml.AABBf; import org.joml.Vector3f; import io.cubyz.IRenderablePair; +import io.cubyz.blocks.BlockInstance; import io.cubyz.world.World; public abstract class Entity { @@ -21,7 +22,7 @@ public abstract class Entity { protected IRenderablePair renderPair; - protected int width = 1, height = 2; + protected int width = 1, height = 2, depth = 1; public float getSpeed() { return entitySpeed; @@ -63,6 +64,156 @@ public abstract class Entity { return renderPair; } + // port of IntegratedQuantum's mathematical works for collision detection + // Thanks ;) + protected float _getX(float x) { + float wi = (float) width; + float he = (float) height; + int absX = (int) (position.x + 0.5F); + int absY = (int) (position.y + 0.5F); + int absZ = (int) (position.z + 0.5F); + float relX = position.x + 0.5F - absX; + float relZ = position.z + 0.5F - absZ; + if (x < 0) { + if (relX < 0.3F) { + relX++; + absX--; + } + + if (relX+x > 0.3F) { + return x; + } + + float maxX = 0.301F - relX; // This small deviation from the desired value is to prevent imprecision in float calculation to create bugs. + if (relZ < 0.3) { + for (int i = 0; i < 3; i++) { + if (checkBlock(absX - 1, absY + i, absZ - 1)) { + return maxX; + } + } + } + if (relZ > 0.7) { + for (int i = 0; i < 3; i++) { + if (checkBlock(absX - 1, absY + i, absZ + 1)) { + return maxX; + } + } + } + for (int i = 0; i < 3; i++) { + if (checkBlock(absX - 1, absY + i, absZ)) { + return maxX; + } + } + } + else { + if (relX > 0.7F) { + relX--; + absX++; + } + + if (relX+x < 0.7F) { + return x; + } + + float maxX = 0.699F - relX; + if (relZ < 0.3) { + for (int i = 0; i < 3; i++) { + if (checkBlock(absX + 1, absY + i, absZ - 1)) { + return maxX; + } + } + } + if (relZ > 0.7) { + for (int i = 0; i < 3; i++) { + if( checkBlock(absX + 1, absY + i, absZ + 1)) { + return maxX; + } + } + } + for (int i = 0; i < 3; i++) { + if (checkBlock(absX + 1, absY + i, absZ)) { + return maxX; + } + } + } + return x; + } + + protected float _getZ(float z) { + int absX = (int) (position.x + 0.5F); + int absY = (int) (position.y + 0.5F); + int absZ = (int) (position.z + 0.5F); + float relX = position.x + 0.5F - absX; + float relZ = position.z + 0.5F - absZ; + if(z < 0) { + if(relZ < 0.3F) { + relZ++; + absZ--; + } + if(relZ + z > 0.3F) { + return z; + } + float maxZ = 0.301F - relZ; + if(relX < 0.3) { + for(int i = 0; i < 3; i++) { + if (checkBlock(absX - 1, absY + i, absZ - 1)) { + return maxZ; + } + } + } + if(relX > 0.7) { + for(int i = 0; i < 3; i++) { + if(checkBlock(absX+1, absY+i, absZ-1)) { + return maxZ; + } + } + } + for(int i = 0; i < 3; i++) { + if(checkBlock(absX, absY+i, absZ-1)) { + return maxZ; + } + } + } + else { + if(relZ > 0.7F) { + relZ--; + absZ++; + } + if(relZ+z < 0.7F) { + return z; + } + float maxZ = 0.699F - relZ; + if(relX < 0.3) { + for(int i = 0; i < 3; i++) { + if(checkBlock(absX-width, absY+i, absZ+depth)) { + return maxZ; + } + } + } + if(relX > 0.7) { + for(int i = 0; i < height; i++) { + if(checkBlock(absX+width, absY+i, absZ+depth)) { + return maxZ; + } + } + } + for(int i = 0; i < height; i++) { + if(checkBlock(absX, absY+i, absZ+depth)) { + return maxZ; + } + } + } + return z; + } + + public boolean checkBlock(int x, int y, int z) { + BlockInstance bi = world.getBlock(x, y, z); + if(bi != null && bi.getBlock().isSolid()) { + return true; + } + return false; + } + public void update() { aabb.minX = position.x(); aabb.maxX = position.x() + width; @@ -70,8 +221,6 @@ public abstract class Entity { aabb.maxY = position.y() + height; aabb.minZ = position.z(); aabb.maxZ = position.z() + width; - //spatial.setPosition(position.x(), position.y(), position.z()); - //spatial.setRotation(rotation.x(), rotation.y(), rotation.z()); if (renderPair != null) { Consumer upd = (Consumer) renderPair.get("renderPairUpdate"); diff --git a/cubyz-common/src/io/cubyz/entity/Player.java b/cubyz-common/src/io/cubyz/entity/Player.java index 38b682064..7c03cf5d2 100644 --- a/cubyz-common/src/io/cubyz/entity/Player.java +++ b/cubyz-common/src/io/cubyz/entity/Player.java @@ -24,14 +24,14 @@ public class Player extends Entity implements ICommandSource { this.local = local; // try { // mesh = loadMesh("uglyplayer"); -// Material mat = new Material(new Vector4f(0.1F, 0.5F, 0.5F, 0.0F), 1.0F); //NOTE: Normal > 0.1F || 0.5F || 0.5F || 0.0F || 1.0F -// mesh.setBoundingRadius(10.0F); //NOTE: Normal > 10.0F +// Material mat = new Material(new Vector4f(0.1F, 0.5F, 0.5F, 0.0F), 1.0F); +// mesh.setBoundingRadius(10.0F); // mesh.setMaterial(mat); // } catch (Exception e) { // e.printStackTrace(); // } // spatial = new Spatial(mesh); -// spatial.setScale(0.5F); //NOTE: Normal > 0.5F +// spatial.setScale(0.5F); setRegistryName("cubz:player"); } @@ -41,12 +41,12 @@ public class Player extends Entity implements ICommandSource { public void move(Vector3f inc, Vector3f rot) { if (inc.z != 0) { - position.x += (float) Math.sin(Math.toRadians(rot.y)) * -1.0F * inc.z; //NOTE: Normal > -1.0F - position.z += (float) Math.cos(Math.toRadians(rot.y)) * inc.z; + position.x += _getX((float) Math.sin(Math.toRadians(rot.y)) * -1.0F * inc.z); + position.z += _getZ((float) Math.cos(Math.toRadians(rot.y)) * inc.z); } if (inc.x != 0) { - position.x += (float) Math.sin(Math.toRadians(rot.y - 90)) * -1.0F * inc.x; //NOTE: Normal > 90 || -1.0F - position.z += (float) Math.cos(Math.toRadians(rot.y - 90)) * inc.x; //NOTE: Normal > 90 + position.x += _getX((float) Math.sin(Math.toRadians(rot.y - 90)) * -1.0F * inc.x); + position.z += _getZ((float) Math.cos(Math.toRadians(rot.y - 90)) * inc.x); } if (inc.y != 0) { vy = inc.y; @@ -59,16 +59,40 @@ public class Player extends Entity implements ICommandSource { if (!flying) { vy -= 0.015F; } - Vector3i bp = new Vector3i((int) Math.ceil(position.x), (int) Math.ceil(position.y)-1, (int) Math.ceil(position.z)); - if (world.getBlock(bp) != null) { - AABBf other = new AABBf(); - other.setMin(new Vector3f(bp)); - other.setMax(new Vector3f(bp.x + 1.0F, bp.y + 1.0F, bp.z + 1.0F)); //NOTE: Normal > 1.0F || 1.0F || 1.0F - boolean b = aabb.testAABB(other); - if (b) { - if (vy < 0) { + if (vy < 0) { + Vector3i bp = new Vector3i((int) Math.round(position.x), (int) position.y, (int) Math.round(position.z)); + float relX = position.x + 0.5F - bp.x; + float relZ = position.z + 0.5F - bp.z; + if(checkBlock(bp.x, bp.y, bp.z)) { + vy = 0; + } + else if (relX < 0.3) { + if (checkBlock(bp.x - 1, bp.y, bp.z)) { vy = 0; } + else if (relZ < 0.3 && checkBlock(bp.x - 1, bp.y, bp.z - 1)) { + vy = 0; + } + else if (relZ > 0.7 && checkBlock(bp.x - 1, bp.y, bp.z + 1)) { + vy = 0; + } + } + else if (relX > 0.7) { + if (checkBlock(bp.x + 1, bp.y, bp.z)) { + vy = 0; + } + else if (relZ < 0.3 && checkBlock(bp.x + 1, bp.y, bp.z - 1)) { + vy = 0; + } + else if (relZ > 0.7 && checkBlock(bp.x + 1, bp.y, bp.z + 1)) { + vy = 0; + } + } + if (relZ < 0.3 && checkBlock(bp.x, bp.y, bp.z - 1)) { + vy = 0; + } + else if (relZ > 0.7 && checkBlock(bp.x, bp.y, bp.z + 1)) { + vy = 0; } } position.add(0, vy, 0); diff --git a/cubyz-common/src/io/cubyz/world/LocalWorld.java b/cubyz-common/src/io/cubyz/world/LocalWorld.java index 55a712e06..c31b808a8 100644 --- a/cubyz-common/src/io/cubyz/world/LocalWorld.java +++ b/cubyz-common/src/io/cubyz/world/LocalWorld.java @@ -59,13 +59,23 @@ public class LocalWorld extends World { if (!loadList.isEmpty()) { ChunkAction popped = loadList.pop(); if (popped.type == ChunkActionType.GENERATE) { - //CubzLogger.instance.fine("Generating " + popped.chunk); + CubzLogger.instance.fine("Generating " + popped.chunk.getX() + "," + popped.chunk.getZ()); if (!popped.chunk.isGenerated()) { synchronousGenerate(popped.chunk); + } else { + if (!popped.chunk.isLoaded()) { + + } } } else if (popped.type == ChunkActionType.UNLOAD) { - //CubzLogger.instance.fine("Unloading " + popped.chunk); + CubzLogger.instance.fine("Unloading " + popped.chunk.getX() + "," + popped.chunk.getZ()); + for (BlockInstance bi : popped.chunk.list()) { + Block b = bi.getBlock(); + visibleSpatials.get(b).remove(bi); + spatials.remove(bi); + } + popped.chunk.setLoaded(false); } } System.out.print(""); @@ -247,19 +257,18 @@ public class LocalWorld extends World { @Override public void seek(int x, int z) { - for (int x1 = x - 32; x1 < x + 32; x1++) { - for (int z1 = z - 32; z1 < z + 32; z1++) { + int renderDistance = 2-1; + int blockDistance = renderDistance*16; + for (int x1 = x - blockDistance-16; x1 < x + blockDistance+16; x1++) { + for (int z1 = z - blockDistance-16; z1 < z + blockDistance+16; z1++) { Chunk ch = getChunk(x1/16,z1/16); - if (!ch.isGenerated()) { - queueChunk(new ChunkAction(ch, ChunkActionType.GENERATE)); - } - } - } - for (int x1 = x - 48; x1 < x + 48; x1++) { - for (int z1 = z - 48; z1 < z + 48; z1++) { - if (x1 < x - 32 || x1 > x + 32) { - if (z1 < z - 32 || z1 > z + 32) { - //unload(x1 / 16, z1 / 16); + if (x1>x-blockDistance&&x1z-blockDistance&&z1