fenomas / noa

Experimental voxel game engine.
MIT License
611 stars 87 forks source link

TypeError: world._storage.worldCoordToChunkIndex is not a function #138

Closed Trenki closed 3 years ago

Trenki commented 3 years ago
TypeError: world._storage.worldCoordToChunkIndex is not a function

when trying to using the noa.world.invalidateVoxelsInAABB(box) I get that error.

let box = {
    base: [Infinity, Infinity, Infinity],
    max: [-Infinity, -Infinity, -Infinity]
}
let set = new Set()
data.values.forEach(ele => {
    if(!set.has(ele.i)){
        noa.registry.registerBlock(ele.i, { material: `${name}-${ele.i}` })
    } 
    let key = `${ele.x}-${ele.y}-${ele.z}`
    box.base[0]=Math.min(box.base[0],ele.x)
    box.base[1]=Math.min(box.base[1],ele.y)
    box.base[2]=Math.min(box.base[2],ele.z)
    box.max[0]=Math.max(box.max[0],ele.x)
    box.max[1]=Math.max(box.max[1],ele.y)
    box.max[2]=Math.max(box.max[2],ele.z)
    voxMap.set(key, ele.i)
})
noa.world.invalidateVoxelsInAABB(box)
fenomas commented 3 years ago

Whoops, overlooked that. Can you check the version I just pushed and let me know if it works? invalidateChunks is a feature that I don't personally use so it's not easy for me to test it rigorously.

Trenki commented 3 years ago

I used it and found it useless. I found this method in issues, but I don't know the specific usage.Do you have any good suggestions if I want to load .vox files asynchronously from the network? thanks :)

fenomas commented 3 years ago

Hmm, this function seems to have been broken even before I changed it the other day. I've pushed another fix, which for me locally appears to work.

Here's a description of how it's supposed to work. In a single player game with no server, worldgen looks like this:

  1. the game engine sees that there are unloaded chunks within range of the player, and emits worldDataNeeded
  2. the game client catches that, generates the world data, and calls noa.world.setChunkData
  3. the engine takes that data and meshes it, etc.

Then later if the game client decides that voxel data has changed, it just calls noa.setBlock for that voxel.

However if you have a server providing world data, you'll probably have cases where the server sends you updated data, and you want noa to refresh a whole chunk, rather than updating things voxel by voxel. In that case you can call noa.world.invalidateVoxelsInAABB for the affected area, and noa will mark those chunks to be de-meshed and disposed. After that's done, if they're within range of the player the engine will issue new worldDataNeeded events, and the client can supply the fresh data.

Hope that makes sense!

Trenki commented 3 years ago

Thank you very much for your help. Using Noa. setBlock achieved the effect I wanted.

By the way, I found that in the API document, noa.setBlock has only x,y, and z parameters, not id. I don't know if it's a document error.

Thanks again!

fenomas commented 3 years ago

Cheers! I will push a fix on the docs.