Faster loading & geometry fixes

This commit is contained in:
Paul Mathieu 2021-12-22 02:32:08 -08:00
parent eec60fcc91
commit 6f66e4f131
2 changed files with 49 additions and 26 deletions

View File

@ -341,9 +341,9 @@ export function tick(time, gl, params) {
// expensive stuff, can take several cycles
try {
// frame time is typically 16.7ms, so this may lag a bit
let timeLeft = 30;
let timeLeft = 10;
const start = performance.now();
generateMissingChunks(params.world, campos[2], campos[0], 5);
generateMissingChunks(params.world, campos[2], campos[0], timeLeft);
timeLeft -= performance.now() - start;
updateWorldGeometry(gl, params.world, campos[2], campos[0], timeLeft);

View File

@ -250,26 +250,28 @@ export function generateMissingChunks(world, z, x, timeLimit = 10000) {
const start = performance.now();
for (let i = ic - 8; i < ic + 8; i++) {
for (let j = jc - 8; j < jc + 8; j++) {
if (world.chunkMap.has(i, j)) {
continue;
}
const chunk = makeChunk(i * 16, j * 16);
world.chunks.push(chunk);
world.chunkMap.set(i, j, chunk);
for (let radius = 1; radius < 8; radius++) {
invalidateChunkGeometry(world, i - 1, j);
invalidateChunkGeometry(world, i + 1, j);
invalidateChunkGeometry(world, i, j - 1);
invalidateChunkGeometry(world, i, j + 1);
for (let i = ic - radius; i < ic + radius; i++) {
for (let j = jc - radius; j < jc + radius; j++) {
if (world.chunkMap.has(i, j)) {
continue;
}
const chunk = makeChunk(i * 16, j * 16);
world.chunks.push(chunk);
world.chunkMap.set(i, j, chunk);
if (performance.now() - start > timeLimit) {
throw 'timesup';
invalidateChunkGeometry(world, i - 1, j);
invalidateChunkGeometry(world, i + 1, j);
invalidateChunkGeometry(world, i, j - 1);
invalidateChunkGeometry(world, i, j + 1);
if (radius > 2 && performance.now() - start > timeLimit) {
return;
}
}
}
}
return world;
}
@ -278,6 +280,10 @@ function invalidateChunkGeometry(world, i, j) {
if (chunk === undefined) {
return;
}
if (chunk.faces === undefined) {
return;
}
delete chunk.faces;
if (chunk.buffer === undefined) {
return;
}
@ -285,7 +291,21 @@ function invalidateChunkGeometry(world, i, j) {
delete chunk.buffer;
}
export function createChunkFace(block, dir) {
function addFace(chunk, block, dir) {
if (block.type === BlockType.WATER) {
const face = createChunkFace(block, dir);
if (dir === '+y') {
face[1] -= 0.15;
}
chunk.transparentFaces.push(face);
} else {
chunk.faces.push(createChunkFace(block, dir));
}
}
export function createChunkFace(block, dir, center = null) {
center = center ?? faceCenter(block.centerPosition, dir);
return {
dir,
blockIndex: block.blockIndex,
@ -306,7 +326,7 @@ export function updateWorldGeometry(gl, world, z, x, timeLimit = 10000) {
for (let j = jc - radius; j < jc + radius; j++) {
const chunk = world.chunkMap.get(i, j);
if (chunk.buffer !== undefined) {
if (chunk === undefined || chunk.buffer !== undefined) {
continue;
}
@ -324,8 +344,8 @@ export function updateWorldGeometry(gl, world, z, x, timeLimit = 10000) {
chunk.transparentBuffer = makeBufferFromFaces(gl, chunk.transparentFaces.map(f => f.face));
// throttle this for fluidity
if (performance.now() - start > timeLimit) {
throw 'timesup';
if (radius > 2 && performance.now() - start > timeLimit) {
return;
}
}
}
@ -491,7 +511,9 @@ export function destroyBlock(world, block) {
.filter(({ block }) => block.type !== BlockType.AIR &&
block.type !== BlockType.UNDEFINED)
.forEach(({ block, dir }) => {
block.chunk.faces.push(createChunkFace(block, dir));
// TODO: don't add transparent faces twice
// since we "forget" to trim them
addFace(block.chunk, block, dir);
trimFaces(block.chunk);
if (block.chunk.buffer !== undefined) {
@ -529,15 +551,16 @@ export function makeBlock(world, position, type) {
neighbors
.filter(({ block }) => block.type !== BlockType.UNDEFINED)
.forEach(({ block: nblock, dir, ndir }) => {
if (nblock.type === BlockType.AIR) {
block.chunk.faces.push(createChunkFace(block, dir));
} else {
if (nblock.type === BlockType.AIR ||
nblock.type === BlockType.WATER) {
addFace(block.chunk, block, dir);
}// else {
nblock.chunk.faces = nblock.chunk.faces.filter(f => (
f.blockIndex !== nblock.blockIndex ||
f.dir !== ndir
));
refresh(nblock.chunk);
}
//}
});
refresh(block.chunk);