Implemented Albert IntegratedQuantum's Theory of Collisions

This commit is contained in:
Randy 2019-03-18 19:45:08 +01:00
parent 25775236fa
commit b82f682745
4 changed files with 217 additions and 33 deletions

4
.gitignore vendored
View File

@ -24,4 +24,6 @@ hs_err_pid*
#Eclipse workspace/projects files
.metadata/
.recommenders/
.recommenders/
cubyz-client/logs/

View File

@ -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<Entity> upd = (Consumer<Entity>) renderPair.get("renderPairUpdate");

View File

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

View File

@ -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&&x1<x+blockDistance&&z1>z-blockDistance&&z1<z+blockDistance) {
if (!ch.isGenerated()) {
queueChunk(new ChunkAction(ch, ChunkActionType.GENERATE));
}
} else {
if (ch.isLoaded()) {
queueChunk(new ChunkAction(ch, ChunkActionType.UNLOAD));
}
}
}