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 // expensive stuff, can take several cycles
try { try {
// frame time is typically 16.7ms, so this may lag a bit // frame time is typically 16.7ms, so this may lag a bit
let timeLeft = 30; let timeLeft = 10;
const start = performance.now(); const start = performance.now();
generateMissingChunks(params.world, campos[2], campos[0], 5); generateMissingChunks(params.world, campos[2], campos[0], timeLeft);
timeLeft -= performance.now() - start; timeLeft -= performance.now() - start;
updateWorldGeometry(gl, params.world, campos[2], campos[0], timeLeft); updateWorldGeometry(gl, params.world, campos[2], campos[0], timeLeft);

View File

@ -250,8 +250,10 @@ export function generateMissingChunks(world, z, x, timeLimit = 10000) {
const start = performance.now(); const start = performance.now();
for (let i = ic - 8; i < ic + 8; i++) { for (let radius = 1; radius < 8; radius++) {
for (let j = jc - 8; j < jc + 8; j++) {
for (let i = ic - radius; i < ic + radius; i++) {
for (let j = jc - radius; j < jc + radius; j++) {
if (world.chunkMap.has(i, j)) { if (world.chunkMap.has(i, j)) {
continue; continue;
} }
@ -264,12 +266,12 @@ export function generateMissingChunks(world, z, x, timeLimit = 10000) {
invalidateChunkGeometry(world, i, j - 1); invalidateChunkGeometry(world, i, j - 1);
invalidateChunkGeometry(world, i, j + 1); invalidateChunkGeometry(world, i, j + 1);
if (performance.now() - start > timeLimit) { if (radius > 2 && performance.now() - start > timeLimit) {
throw 'timesup'; return;
}
} }
} }
} }
return world; return world;
} }
@ -278,6 +280,10 @@ function invalidateChunkGeometry(world, i, j) {
if (chunk === undefined) { if (chunk === undefined) {
return; return;
} }
if (chunk.faces === undefined) {
return;
}
delete chunk.faces;
if (chunk.buffer === undefined) { if (chunk.buffer === undefined) {
return; return;
} }
@ -285,7 +291,21 @@ function invalidateChunkGeometry(world, i, j) {
delete chunk.buffer; 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 { return {
dir, dir,
blockIndex: block.blockIndex, 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++) { for (let j = jc - radius; j < jc + radius; j++) {
const chunk = world.chunkMap.get(i, j); const chunk = world.chunkMap.get(i, j);
if (chunk.buffer !== undefined) { if (chunk === undefined || chunk.buffer !== undefined) {
continue; continue;
} }
@ -324,8 +344,8 @@ export function updateWorldGeometry(gl, world, z, x, timeLimit = 10000) {
chunk.transparentBuffer = makeBufferFromFaces(gl, chunk.transparentFaces.map(f => f.face)); chunk.transparentBuffer = makeBufferFromFaces(gl, chunk.transparentFaces.map(f => f.face));
// throttle this for fluidity // throttle this for fluidity
if (performance.now() - start > timeLimit) { if (radius > 2 && performance.now() - start > timeLimit) {
throw 'timesup'; return;
} }
} }
} }
@ -491,7 +511,9 @@ export function destroyBlock(world, block) {
.filter(({ block }) => block.type !== BlockType.AIR && .filter(({ block }) => block.type !== BlockType.AIR &&
block.type !== BlockType.UNDEFINED) block.type !== BlockType.UNDEFINED)
.forEach(({ block, dir }) => { .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); trimFaces(block.chunk);
if (block.chunk.buffer !== undefined) { if (block.chunk.buffer !== undefined) {
@ -529,15 +551,16 @@ export function makeBlock(world, position, type) {
neighbors neighbors
.filter(({ block }) => block.type !== BlockType.UNDEFINED) .filter(({ block }) => block.type !== BlockType.UNDEFINED)
.forEach(({ block: nblock, dir, ndir }) => { .forEach(({ block: nblock, dir, ndir }) => {
if (nblock.type === BlockType.AIR) { if (nblock.type === BlockType.AIR ||
block.chunk.faces.push(createChunkFace(block, dir)); nblock.type === BlockType.WATER) {
} else { addFace(block.chunk, block, dir);
}// else {
nblock.chunk.faces = nblock.chunk.faces.filter(f => ( nblock.chunk.faces = nblock.chunk.faces.filter(f => (
f.blockIndex !== nblock.blockIndex || f.blockIndex !== nblock.blockIndex ||
f.dir !== ndir f.dir !== ndir
)); ));
refresh(nblock.chunk); refresh(nblock.chunk);
} //}
}); });
refresh(block.chunk); refresh(block.chunk);