feat: Started on palette implementation
This commit is contained in:
parent
88100b58ea
commit
255475c77c
26
hashserver.txt
Normal file
26
hashserver.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
goos: linux
|
||||||
|
goarch: amd64
|
||||||
|
pkg: git.nicholasnovak.io/nnovak/spatial-db
|
||||||
|
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
|
||||||
|
BenchmarkInsertClusteredPoints-8 7030724 294.0 ns/op 139 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5987259 198.1 ns/op 10 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5793637 484.0 ns/op 337 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5644594 207.5 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5815582 211.0 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5618958 211.7 ns/op 2 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5603455 215.2 ns/op 10 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5454136 223.0 ns/op 13 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5391891 694.1 ns/op 718 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertClusteredPoints-8 5574357 228.4 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 5355165 218.3 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 5385463 221.0 ns/op 1 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 5265614 224.1 ns/op 2 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 5269447 229.2 ns/op 7 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 5167845 231.7 ns/op 19 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 4997976 240.3 ns/op 23 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 4914524 772.6 ns/op 1584 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 1535679 692.3 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 1852569 617.0 ns/op 0 B/op 0 allocs/op
|
||||||
|
BenchmarkInsertSparserPoints-8 2007783 568.2 ns/op 1 B/op 0 allocs/op
|
||||||
|
PASS
|
||||||
|
ok git.nicholasnovak.io/nnovak/spatial-db 114.742s
|
@ -25,7 +25,7 @@ func (hs *HashServer) SetStorageRoot(path string) {
|
|||||||
for _, section := range data.Sections {
|
for _, section := range data.Sections {
|
||||||
for blockIndex, blockState := range section.BlockStates {
|
for blockIndex, blockState := range section.BlockStates {
|
||||||
pos := data.IndexToBlockPos(blockIndex)
|
pos := data.IndexToBlockPos(blockIndex)
|
||||||
hs.blocks[pos] = blockState
|
hs.blocks[pos] = section.Palette.State(blockState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,17 @@ const (
|
|||||||
// `ChunkData` represents the contents of a "chunk", which is a column of voxels
|
// `ChunkData` represents the contents of a "chunk", which is a column of voxels
|
||||||
// in world space
|
// in world space
|
||||||
type ChunkData struct {
|
type ChunkData struct {
|
||||||
Pos ChunkPos `json:"pos"`
|
// The position of the chunk, in world space
|
||||||
|
Pos ChunkPos `json:"pos"`
|
||||||
|
// The column of sections
|
||||||
Sections [ChunkSectionCount]ChunkSection `json:"sections"`
|
Sections [ChunkSectionCount]ChunkSection `json:"sections"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// `ChunkSection' is a fixed-size cube that stores the data in a chunk
|
// `ChunkSection' is a fixed-size cube that stores the data in a chunk
|
||||||
type ChunkSection struct {
|
type ChunkSection struct {
|
||||||
// The count of full blocks in the chunk
|
// A look-up-table of each section index to its value
|
||||||
BlockCount uint `json:"block_count"`
|
Palette SectionPalette `json:"palette"`
|
||||||
BlockStates [16 * 16 * 16]BlockID `json:"block_states"`
|
BlockStates [16 * 16 * 16]PaletteIndex `json:"block_states"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func rem_euclid(a, b int) int {
|
func rem_euclid(a, b int) int {
|
||||||
@ -39,18 +41,12 @@ func IndexOfBlock(pos BlockPos) int {
|
|||||||
return (baseY * chunkSliceSize) + (baseZ * 16) + baseX
|
return (baseY * chunkSliceSize) + (baseZ * 16) + baseX
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChunkSection) UpdateBlockAtIndex(index int, targetState BlockID) {
|
|
||||||
// TODO: Keep track of the block count
|
|
||||||
|
|
||||||
cs.BlockStates[index] = targetState
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cs *ChunkSection) UpdateBlock(pos BlockPos, targetState BlockID) {
|
func (cs *ChunkSection) UpdateBlock(pos BlockPos, targetState BlockID) {
|
||||||
cs.BlockStates[IndexOfBlock(pos)] = targetState
|
cs.BlockStates[IndexOfBlock(pos)] = cs.Palette.IndexFor(targetState)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChunkSection) FetchBlock(pos BlockPos) BlockID {
|
func (cs *ChunkSection) FetchBlock(pos BlockPos) BlockID {
|
||||||
return cs.BlockStates[IndexOfBlock(pos)]
|
return cs.Palette.State(cs.BlockStates[IndexOfBlock(pos)])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cd *ChunkData) SectionFor(pos BlockPos) *ChunkSection {
|
func (cd *ChunkData) SectionFor(pos BlockPos) *ChunkSection {
|
||||||
@ -68,6 +64,8 @@ func (cd *ChunkData) IndexToBlockPos(index int) BlockPos {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conversion from Minecraft chunks
|
||||||
|
|
||||||
func extractPaletteIndexes(compressed int64) [16]byte {
|
func extractPaletteIndexes(compressed int64) [16]byte {
|
||||||
var outputs [16]byte
|
var outputs [16]byte
|
||||||
var outputIndex int
|
var outputIndex int
|
||||||
@ -113,13 +111,12 @@ func (cd *ChunkData) FromMCAChunk(other save.Chunk) {
|
|||||||
if section.BlockStates.Palette[paletteIndex].Name == "minecraft:air" {
|
if section.BlockStates.Palette[paletteIndex].Name == "minecraft:air" {
|
||||||
state = Empty
|
state = Empty
|
||||||
} else {
|
} else {
|
||||||
cd.Sections[sectionIndex].BlockCount += 1
|
|
||||||
state = Generic
|
state = Generic
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this workaround for larger bit sizes in palettes
|
// TODO: Remove this workaround for larger bit sizes in palettes
|
||||||
if blockIndex < 4096 {
|
if blockIndex < 4096 {
|
||||||
currentSection.BlockStates[blockIndex] = state
|
currentSection.BlockStates[blockIndex] = currentSection.Palette.IndexFor(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
51
world/palette.go
Normal file
51
world/palette.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package world
|
||||||
|
|
||||||
|
// `SectionPalette` is a "palette", which is a sort of look-up-table (LUT) between
|
||||||
|
// an index into the LUT, and the resulting `BlockID`
|
||||||
|
//
|
||||||
|
// This palette is unique to each section, and allows ranges of blocks to be
|
||||||
|
// changed in constant time, with the downside of having to "compact" the palette
|
||||||
|
type SectionPalette []BlockID
|
||||||
|
|
||||||
|
// `Compact` removes all duplicate states from a palette and returns a new palette
|
||||||
|
func (p SectionPalette) Compact() SectionPalette {
|
||||||
|
ids := make(map[BlockID]bool)
|
||||||
|
|
||||||
|
// Filter out the duplicate block ids
|
||||||
|
for _, blockId := range p {
|
||||||
|
ids[blockId] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var np SectionPalette
|
||||||
|
|
||||||
|
for blockId := range ids {
|
||||||
|
np = append(np, blockId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return np
|
||||||
|
}
|
||||||
|
|
||||||
|
// `IndexFor` returns the palette index for a specified block id
|
||||||
|
//
|
||||||
|
// If the block id does not exist, it is placed in the palette and the index
|
||||||
|
// is returned
|
||||||
|
func (p SectionPalette) IndexFor(state BlockID) PaletteIndex {
|
||||||
|
// If the state is already in the palette, return it
|
||||||
|
for index, blockId := range p {
|
||||||
|
if state == blockId {
|
||||||
|
return PaletteIndex(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, insert it into the palette and return the index
|
||||||
|
p = append(p, state)
|
||||||
|
|
||||||
|
return PaletteIndex(len(p) - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// `State` returns the state for a palette's index
|
||||||
|
func (p SectionPalette) State(index PaletteIndex) BlockID {
|
||||||
|
return p[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
type PaletteIndex byte
|
Loading…
Reference in New Issue
Block a user