diff --git a/022/world.go b/022/world.go index 4ae90a4..9d1d4f1 100644 --- a/022/world.go +++ b/022/world.go @@ -1,7 +1,7 @@ package main import ( - "fmt" + "fmt" ) const Meter = int64(1000000) @@ -13,412 +13,433 @@ const Micrometer = Meter / 1000000 // --------------------------------------------------------- type Vector struct { - x int64 - y int64 - z int64 + x int64 + y int64 + z int64 +} + +func (value *Vector) Equal(other *Vector) bool { + return value.x == other.x && value.y == other.y && value.z == other.z } func (value *Vector) Write(data []byte, index *int) { - WriteInt64(data, index, value.x) - WriteInt64(data, index, value.y) - WriteInt64(data, index, value.z) + WriteInt64(data, index, value.x) + WriteInt64(data, index, value.y) + WriteInt64(data, index, value.z) } func (value *Vector) Read(data []byte, index *int) bool { - if !ReadInt64(data, index, &value.x) { - return false - } - if !ReadInt64(data, index, &value.y) { - return false - } - if !ReadInt64(data, index, &value.z) { - return false - } - return true + if !ReadInt64(data, index, &value.x) { + return false + } + if !ReadInt64(data, index, &value.y) { + return false + } + if !ReadInt64(data, index, &value.z) { + return false + } + return true } // --------------------------------------------------------- func Dot(x int64, y int64, z int64, nx int64, ny int64, nz int64) int64 { - dx := ( x * nx ) / Meter - dy := ( y * ny ) / Meter - dz := ( z * nz ) / Meter - return dx + dy + dz + dx := (x * nx) / Meter + dy := (y * ny) / Meter + dz := (z * nz) / Meter + return dx + dy + dz } // --------------------------------------------------------- type Plane struct { - normal Vector - d int64 + // plane: normal.x * x + normal.y * y + normal.z * z = d + normal Vector + d int64 } func (value *Plane) Write(data []byte, index *int) { - value.normal.Write(data, index) - WriteInt64(data, index, value.d) + value.normal.Write(data, index) + WriteInt64(data, index, value.d) } func (value *Plane) Read(data []byte, index *int) bool { - if !value.normal.Read(data, index) { - return false - } - if !ReadInt64(data, index, &value.d) { - return false - } - return true + if !value.normal.Read(data, index) { + return false + } + if !ReadInt64(data, index, &value.d) { + return false + } + return true +} + +// Is the point in front of the plane, according to the normal direction. Inclusive. +func (value *Plane) InFront(x int64, y int64, z int64) bool { + return Dot(x, y, z, value.normal.x, value.normal.y, value.normal.z) >= value.d } // --------------------------------------------------------- type AABB struct { - min Vector - max Vector + min Vector + max Vector } func (value *AABB) Write(data []byte, index *int) { - value.min.Write(data, index) - value.max.Write(data, index) + value.min.Write(data, index) + value.max.Write(data, index) } func (value *AABB) Read(data []byte, index *int) bool { - if !value.min.Read(data, index) { - return false - } - if !value.max.Read(data, index) { - return false - } - return true + if !value.min.Read(data, index) { + return false + } + if !value.max.Read(data, index) { + return false + } + return true } // --------------------------------------------------------- type Volume struct { - bounds AABB - planes []Plane + bounds AABB + planes []Plane } func (volume *Volume) Inside(x int64, y int64, z int64) bool { - for i := range volume.planes { - if Dot(x, y, z, volume.planes[i].normal.x, volume.planes[i].normal.y, volume.planes[i].normal.z) < volume.planes[i].d { - return false - } - } - return true + for _, plane := range volume.planes { + if !plane.InFront(x, y, z) { + return false + } + } + return true } func (value *Volume) Write(data []byte, index *int) { - value.bounds.Write(data, index) - numPlanes := len(value.planes) - WriteInt(data, index, numPlanes) - for i := 0; i < numPlanes; i++ { - value.planes[i].Write(data, index) - } + value.bounds.Write(data, index) + numPlanes := len(value.planes) + WriteInt(data, index, numPlanes) + for i := 0; i < numPlanes; i++ { + value.planes[i].Write(data, index) + } } func (value *Volume) Read(data []byte, index *int) bool { - if !value.bounds.Read(data, index) { - return false - } - var numPlanes int - if !ReadInt(data, index, &numPlanes) { - return false - } - value.planes = make([]Plane, numPlanes) - for i := 0; i < numPlanes; i++ { - if !value.planes[i].Read(data, index) { - return false - } - } - return true + if !value.bounds.Read(data, index) { + return false + } + var numPlanes int + if !ReadInt(data, index, &numPlanes) { + return false + } + value.planes = make([]Plane, numPlanes) + for i := 0; i < numPlanes; i++ { + if !value.planes[i].Read(data, index) { + return false + } + } + return true } // --------------------------------------------------------- type Zone struct { - id uint32 - origin Vector - bounds AABB - volumes []Volume + id uint32 + origin Vector + bounds AABB + volumes []Volume } func (zone *Zone) Inside(x int64, y int64, z int64) bool { - for i := range zone.volumes { - if zone.volumes[i].Inside(x, y, z) { - return true - } - } - return false + for _, volume := range zone.volumes { + if volume.Inside(x, y, z) { + return true + } + } + return false } func (value *Zone) Write(data []byte, index *int) { - WriteUint32(data, index, value.id) - value.origin.Write(data, index) - value.bounds.Write(data, index) - numVolumes := len(value.volumes) - WriteInt(data, index, numVolumes) - for i := 0; i < numVolumes; i++ { - value.volumes[i].Write(data, index) - } + WriteUint32(data, index, value.id) + value.origin.Write(data, index) + value.bounds.Write(data, index) + numVolumes := len(value.volumes) + WriteInt(data, index, numVolumes) + for i := 0; i < numVolumes; i++ { + value.volumes[i].Write(data, index) + } } func (value *Zone) Read(data []byte, index *int) bool { - if !ReadUint32(data, index, &value.id) { - return false - } - if !value.origin.Read(data, index) { - return false - } - if !value.bounds.Read(data, index) { - return false - } - var numVolumes int - if !ReadInt(data, index, &numVolumes) { - return false - } - value.volumes = make([]Volume, numVolumes) - for i := 0; i < numVolumes; i++ { - if !value.volumes[i].Read(data, index) { - return false - } - } - return true + if !ReadUint32(data, index, &value.id) { + return false + } + if !value.origin.Read(data, index) { + return false + } + if !value.bounds.Read(data, index) { + return false + } + var numVolumes int + if !ReadInt(data, index, &numVolumes) { + return false + } + value.volumes = make([]Volume, numVolumes) + for i := 0; i < numVolumes; i++ { + if !value.volumes[i].Read(data, index) { + return false + } + } + return true } // --------------------------------------------------------- type World struct { - bounds AABB - zones []Zone - zoneMap map[uint32]*Zone + bounds AABB + zones []Zone + zoneMap map[uint32]*Zone } func (world *World) Fixup() { - world.zoneMap = make(map[uint32]*Zone, len(world.zones)) - for i := range world.zones { - world.zoneMap[world.zones[i].id] = &world.zones[i] - } + world.zoneMap = make(map[uint32]*Zone, len(world.zones)) + for i := range world.zones { + world.zoneMap[world.zones[i].id] = &world.zones[i] + } } func (world *World) Print() { - fmt.Printf("world bounds are (%d,%d,%d) -> (%d,%d,%d)\n", - world.bounds.min.x, - world.bounds.min.y, - world.bounds.min.z, - world.bounds.max.x, - world.bounds.max.y, - world.bounds.max.z, - ) - - fmt.Printf("world has %d zones:\n", len(world.zones)) - - for i := range world.zones { - fmt.Printf(" + 0x%08x: (%d,%d,%d) -> (%d,%d,%d)\n", - world.zones[i].id, - world.zones[i].bounds.min.x, - world.zones[i].bounds.min.y, - world.zones[i].bounds.min.z, - world.zones[i].bounds.max.x, - world.zones[i].bounds.max.y, - world.zones[i].bounds.max.z, - ) - } + fmt.Printf("world bounds are (%d,%d,%d) -> (%d,%d,%d)\n", + world.bounds.min.x, + world.bounds.min.y, + world.bounds.min.z, + world.bounds.max.x, + world.bounds.max.y, + world.bounds.max.z, + ) + + fmt.Printf("world has %d zones:\n", len(world.zones)) + + for i := range world.zones { + fmt.Printf(" + 0x%08x: (%d,%d,%d) -> (%d,%d,%d)\n", + world.zones[i].id, + world.zones[i].bounds.min.x, + world.zones[i].bounds.min.y, + world.zones[i].bounds.min.z, + world.zones[i].bounds.max.x, + world.zones[i].bounds.max.y, + world.zones[i].bounds.max.z, + ) + } } func (value *World) Write(data []byte, index *int) { - value.bounds.Write(data, index) - numZones := len(value.zones) - WriteInt(data, index, numZones) - for i := 0; i < numZones; i++ { - value.zones[i].Write(data, index) - } + value.bounds.Write(data, index) + numZones := len(value.zones) + WriteInt(data, index, numZones) + for i := 0; i < numZones; i++ { + value.zones[i].Write(data, index) + } } func (value *World) Read(data []byte, index *int) bool { - if !value.bounds.Read(data, index) { - return false - } - var numZones int - if !ReadInt(data, index, &numZones) { - return false - } - value.zones = make([]Zone, numZones) - for i := 0; i < numZones; i++ { - if !value.zones[i].Read(data, index) { - return false - } - } - value.Fixup() - return true + if !value.bounds.Read(data, index) { + return false + } + var numZones int + if !ReadInt(data, index, &numZones) { + return false + } + value.zones = make([]Zone, numZones) + for i := 0; i < numZones; i++ { + if !value.zones[i].Read(data, index) { + return false + } + } + value.Fixup() + return true +} + +func (value *World) FindZoneId(x int64, y int64, z int64, zone_id *uint32) bool { + for _, zone := range value.zones { + fmt.Printf("id=%d\n", zone.id) + if zone.Inside(x, y, z) { + *zone_id = zone.id + return true + } + } + return false } // --------------------------------------------------------- func generateWorld_Grid(i int64, j int64, k int64, cellSize int64) *World { - fmt.Printf("generating grid world: %dx%dx%d\n", i, j, k) - - world := World{} + fmt.Printf("generating grid world: %dx%dx%d\n", i, j, k) + + world := World{} - world.bounds.max.x = i * int64(cellSize) - world.bounds.max.y = j * int64(cellSize) - world.bounds.max.z = k * int64(cellSize) + world.bounds.max.x = i * int64(cellSize) + world.bounds.max.y = j * int64(cellSize) + world.bounds.max.z = k * int64(cellSize) - numZones := i * j * k + numZones := i * j * k - world.zones = make([]Zone, numZones) + world.zones = make([]Zone, numZones) - index := 0 + index := 0 - for y := int64(0); y < j; y++ { + for y := int64(0); y < j; y++ { - for z := int64(0); z < k; z++ { + for z := int64(0); z < k; z++ { - for x := int64(0); x < i; x++ { + for x := int64(0); x < i; x++ { - world.zones[index].id = uint32(index) + 1 + world.zones[index].id = uint32(index) + 1 - world.zones[index].bounds.min.x = x * int64(cellSize) - world.zones[index].bounds.min.y = y * int64(cellSize) - world.zones[index].bounds.min.z = z * int64(cellSize) + world.zones[index].bounds.min.x = x * int64(cellSize) + world.zones[index].bounds.min.y = y * int64(cellSize) + world.zones[index].bounds.min.z = z * int64(cellSize) - world.zones[index].bounds.max.x = (x+1) * int64(cellSize) - world.zones[index].bounds.max.y = (y+1) * int64(cellSize) - world.zones[index].bounds.max.z = (z+1) * int64(cellSize) + world.zones[index].bounds.max.x = (x + 1) * int64(cellSize) + world.zones[index].bounds.max.y = (y + 1) * int64(cellSize) + world.zones[index].bounds.max.z = (z + 1) * int64(cellSize) - world.zones[index].origin.x = ( world.zones[index].bounds.min.x + world.zones[index].bounds.max.x ) / 2 - world.zones[index].origin.y = ( world.zones[index].bounds.min.y + world.zones[index].bounds.max.y ) / 2 - world.zones[index].origin.z = ( world.zones[index].bounds.min.z + world.zones[index].bounds.max.z ) / 2 + world.zones[index].origin.x = (world.zones[index].bounds.min.x + world.zones[index].bounds.max.x) / 2 + world.zones[index].origin.y = (world.zones[index].bounds.min.y + world.zones[index].bounds.max.y) / 2 + world.zones[index].origin.z = (world.zones[index].bounds.min.z + world.zones[index].bounds.max.z) / 2 - world.zones[index].volumes = make([]Volume, 1) + world.zones[index].volumes = make([]Volume, 1) - world.zones[index].volumes[0].bounds = world.zones[index].bounds + world.zones[index].volumes[0].bounds = world.zones[index].bounds - world.zones[index].volumes[0].planes = make([]Plane, 6) + world.zones[index].volumes[0].planes = make([]Plane, 6) - // left plane + // left plane - world.zones[index].volumes[0].planes[0].normal.x = Meter - world.zones[index].volumes[0].planes[0].normal.y = 0 - world.zones[index].volumes[0].planes[0].normal.z = 0 - world.zones[index].volumes[0].planes[0].d = x * Meter + world.zones[index].volumes[0].planes[0].normal.x = Meter + world.zones[index].volumes[0].planes[0].normal.y = 0 + world.zones[index].volumes[0].planes[0].normal.z = 0 + world.zones[index].volumes[0].planes[0].d = x * Meter - // right plane + // right plane - world.zones[index].volumes[0].planes[1].normal.x = -Meter - world.zones[index].volumes[0].planes[1].normal.y = 0 - world.zones[index].volumes[0].planes[1].normal.z = 0 - world.zones[index].volumes[0].planes[1].d = x * Meter + int64(cellSize) + world.zones[index].volumes[0].planes[1].normal.x = -Meter + world.zones[index].volumes[0].planes[1].normal.y = 0 + world.zones[index].volumes[0].planes[1].normal.z = 0 + world.zones[index].volumes[0].planes[1].d = -(x*Meter + int64(cellSize)) - // bottom plane + // bottom plane - world.zones[index].volumes[0].planes[2].normal.x = 0 - world.zones[index].volumes[0].planes[2].normal.y = Meter - world.zones[index].volumes[0].planes[2].normal.z = 0 - world.zones[index].volumes[0].planes[2].d = y * Meter + world.zones[index].volumes[0].planes[2].normal.x = 0 + world.zones[index].volumes[0].planes[2].normal.y = Meter + world.zones[index].volumes[0].planes[2].normal.z = 0 + world.zones[index].volumes[0].planes[2].d = y * Meter - // top plane + // top plane - world.zones[index].volumes[0].planes[3].normal.x = 0 - world.zones[index].volumes[0].planes[3].normal.y = -Meter - world.zones[index].volumes[0].planes[3].normal.z = 0 - world.zones[index].volumes[0].planes[3].d = y * Meter + int64(cellSize) + world.zones[index].volumes[0].planes[3].normal.x = 0 + world.zones[index].volumes[0].planes[3].normal.y = -Meter + world.zones[index].volumes[0].planes[3].normal.z = 0 + world.zones[index].volumes[0].planes[3].d = -(y*Meter + int64(cellSize)) - // front plane + // front plane - world.zones[index].volumes[0].planes[4].normal.x = 0 - world.zones[index].volumes[0].planes[4].normal.y = 0 - world.zones[index].volumes[0].planes[4].normal.z = Meter - world.zones[index].volumes[0].planes[4].d = z * Meter + world.zones[index].volumes[0].planes[4].normal.x = 0 + world.zones[index].volumes[0].planes[4].normal.y = 0 + world.zones[index].volumes[0].planes[4].normal.z = Meter + world.zones[index].volumes[0].planes[4].d = z * Meter - // back plane + // back plane - world.zones[index].volumes[0].planes[5].normal.x = 0 - world.zones[index].volumes[0].planes[5].normal.y = 0 - world.zones[index].volumes[0].planes[5].normal.z = -Meter - world.zones[index].volumes[0].planes[5].d = z * Meter + int64(cellSize) + world.zones[index].volumes[0].planes[5].normal.x = 0 + world.zones[index].volumes[0].planes[5].normal.y = 0 + world.zones[index].volumes[0].planes[5].normal.z = -Meter + world.zones[index].volumes[0].planes[5].d = -(z*Meter + int64(cellSize)) - index++ - } + index++ + } - } + } - } - - return &world + } + + return &world } // --------------------------------------------------------- type WorldGridCell struct { - zones []*Zone + zones []*Zone } type WorldGrid struct { - i int32 - j int32 - k int32 - cellSize int64 - bounds AABB - cells [][][]WorldGridCell + i int32 + j int32 + k int32 + cellSize int64 + bounds AABB + cells [][][]WorldGridCell } func createWorldGrid(world *World, cellSize int64) *WorldGrid { - - dx := world.bounds.max.x - world.bounds.min.x - dy := world.bounds.max.y - world.bounds.min.y - dz := world.bounds.max.z - world.bounds.min.z - cx := dx / int64(cellSize) - cy := dy / int64(cellSize) - cz := dz / int64(cellSize) + dx := world.bounds.max.x - world.bounds.min.x + dy := world.bounds.max.y - world.bounds.min.y + dz := world.bounds.max.z - world.bounds.min.z + + cx := dx / int64(cellSize) + cy := dy / int64(cellSize) + cz := dz / int64(cellSize) - if dx % int64(cellSize) != 0 { - cx++ - } + if dx%int64(cellSize) != 0 { + cx++ + } - if dy % int64(cellSize) != 0 { - cy++ - } + if dy%int64(cellSize) != 0 { + cy++ + } - if dz % int64(cellSize) != 0 { - cz++ - } + if dz%int64(cellSize) != 0 { + cz++ + } - cellCount := cx * cy * cz + cellCount := cx * cy * cz - fmt.Printf("world grid has %d cells\n", cellCount) + fmt.Printf("world grid has %d cells\n", cellCount) - grid := &WorldGrid{} + grid := &WorldGrid{} - grid.cells = make([][][]WorldGridCell, cz) + grid.cells = make([][][]WorldGridCell, cz) - numZones := len(world.zones) + numZones := len(world.zones) - inside := make([]bool, numZones) + inside := make([]bool, numZones) - for k := 0; k < int(cz); k++ { - z := world.bounds.min.z + int64(cellSize) * int64(k) - grid.cells[k] = make([][]WorldGridCell, cy) - for j := 0; j < int(cy); j++ { - y := world.bounds.min.y + int64(cellSize) * int64(j) - grid.cells[k][j] = make([]WorldGridCell, cx) - for i := 0; i < int(cx); i++ { - x := world.bounds.min.x + int64(cellSize) * int64(i) - for n := 0; n < numZones; n++ { - if world.zones[i].Inside(x, y, z) { - inside[n] = true - } else { - inside[n] = false - } - } - } - } - } + for k := 0; k < int(cz); k++ { + z := world.bounds.min.z + int64(cellSize)*int64(k) + grid.cells[k] = make([][]WorldGridCell, cy) + for j := 0; j < int(cy); j++ { + y := world.bounds.min.y + int64(cellSize)*int64(j) + grid.cells[k][j] = make([]WorldGridCell, cx) + for i := 0; i < int(cx); i++ { + x := world.bounds.min.x + int64(cellSize)*int64(i) + for n := 0; n < numZones; n++ { + if world.zones[i].Inside(x, y, z) { + inside[n] = true + } else { + inside[n] = false + } + } + } + } + } - fmt.Printf("finished crunching world grid\n") + fmt.Printf("finished crunching world grid\n") - return grid + return grid } // --------------------------------------------------------- diff --git a/022/world_test.go b/022/world_test.go index f3c7439..b635b93 100644 --- a/022/world_test.go +++ b/022/world_test.go @@ -7,6 +7,33 @@ import ( "github.com/stretchr/testify/assert" ) +func Test_Equal_Vector(t *testing.T) { + + type In struct { + u Vector + v Vector + } + + type Params struct { + in In + out bool + } + + var parameters = []Params{ + {In{Vector{Meter, 0, 0}, Vector{Meter, 0, 0}}, true}, + {In{Vector{0, -Meter, 0}, Vector{0, -Meter, 0}}, true}, + {In{Vector{-Meter, 0, 0}, Vector{Meter, 0, 0}}, false}, + {In{Vector{Meter, 0, 0}, Vector{0, 0, Meter}}, false}, + } + + for index, parameter := range parameters { + t.Run(fmt.Sprintf("equal_vector_%d", index), func(t *testing.T) { + assert.Equal(t, parameter.out, parameter.in.u.Equal(¶meter.in.v)) + }) + } + +} + func Test_Dot(t *testing.T) { type In struct { @@ -35,6 +62,38 @@ func Test_Dot(t *testing.T) { } +func Test_InFront_Plane(t *testing.T) { + + type In struct { + plane Plane + point Vector + } + + type Params struct { + in In + out bool + } + + var parameters = []Params{ + {In{Plane{Vector{Meter, 0, 0}, 0}, Vector{0, 0, 0}}, true}, + {In{Plane{Vector{Meter, 0, 0}, 0}, Vector{Meter, 0, 0}}, true}, + {In{Plane{Vector{Meter, 0, 0}, 0}, Vector{-Meter, 0, 0}}, false}, + {In{Plane{Vector{Meter, 0, 0}, 0}, Vector{0, Meter, 0}}, true}, + {In{Plane{Vector{Meter, 0, 0}, 0}, Vector{0, Meter, -Meter}}, true}, + {In{Plane{Vector{0, Meter, 0}, 0}, Vector{0, Meter, -Meter}}, true}, + {In{Plane{Vector{-Meter, 0, 0}, -Meter}, Vector{0, 0, 0}}, true}, + {In{Plane{Vector{-Meter, 0, 0}, -Meter}, Vector{Meter, 0, 0}}, true}, + {In{Plane{Vector{-Meter, 0, 0}, -Meter}, Vector{2 * Meter, 0, 0}}, false}, + } + + for index, parameter := range parameters { + t.Run(fmt.Sprintf("infront_plane_%d", index), func(t *testing.T) { + assert.Equal(t, parameter.out, parameter.in.plane.InFront(parameter.in.point.x, parameter.in.point.y, parameter.in.point.z)) + }) + } + +} + func Test_Inside_Volume(t *testing.T) { type Params struct { @@ -93,17 +152,151 @@ func Test_Inside_Volume(t *testing.T) { } } +func Test_Inside_Zone(t *testing.T) { + + type Params struct { + in Vector + out bool + } + + var parameters = []Params{ + {Vector{0, 0, 0}, true}, + {Vector{Meter / 2, Meter / 2, Meter / 2}, true}, + {Vector{Meter, Meter, Meter}, true}, + {Vector{Meter * 2, Meter, Meter}, true}, + {Vector{Meter * 2, Meter * 2, Meter}, false}, + {Vector{-Meter * 2, 0, 0}, false}, + } + + volume_1 := Volume{} + + volume_1.planes = make([]Plane, 6) + + // back + volume_1.planes[0].normal.x = Meter + volume_1.planes[0].normal.y = 0 + volume_1.planes[0].normal.z = 0 + volume_1.planes[0].d = 0 + // front + volume_1.planes[1].normal.x = -Meter + volume_1.planes[1].normal.y = 0 + volume_1.planes[1].normal.z = 0 + volume_1.planes[1].d = -Meter + // left + volume_1.planes[2].normal.x = 0 + volume_1.planes[2].normal.y = Meter + volume_1.planes[2].normal.z = 0 + volume_1.planes[2].d = 0 + // right + volume_1.planes[3].normal.x = 0 + volume_1.planes[3].normal.y = -Meter + volume_1.planes[3].normal.z = 0 + volume_1.planes[3].d = -Meter + // bottom + volume_1.planes[4].normal.x = 0 + volume_1.planes[4].normal.y = 0 + volume_1.planes[4].normal.z = Meter + volume_1.planes[4].d = 0 + // top + volume_1.planes[5].normal.x = 0 + volume_1.planes[5].normal.y = 0 + volume_1.planes[5].normal.z = -Meter + volume_1.planes[5].d = -Meter + + volume_2 := Volume{} + + volume_2.planes = make([]Plane, 6) + // back + volume_2.planes[0].normal.x = Meter + volume_2.planes[0].normal.y = 0 + volume_2.planes[0].normal.z = 0 + volume_2.planes[0].d = Meter + // front + volume_2.planes[1].normal.x = -Meter + volume_2.planes[1].normal.y = 0 + volume_2.planes[1].normal.z = 0 + volume_2.planes[1].d = -Meter * 2 + // left + volume_2.planes[2].normal.x = 0 + volume_2.planes[2].normal.y = Meter + volume_2.planes[2].normal.z = 0 + volume_2.planes[2].d = 0 + // right + volume_2.planes[3].normal.x = 0 + volume_2.planes[3].normal.y = -Meter + volume_2.planes[3].normal.z = 0 + volume_2.planes[3].d = -Meter + // bottom + volume_2.planes[4].normal.x = 0 + volume_2.planes[4].normal.y = 0 + volume_2.planes[4].normal.z = Meter + volume_2.planes[4].d = 0 + // top + volume_2.planes[5].normal.x = 0 + volume_2.planes[5].normal.y = 0 + volume_2.planes[5].normal.z = -Meter + volume_2.planes[5].d = -Meter + + zone := Zone{} + + zone.volumes = make([]Volume, 2) + zone.volumes[0] = volume_1 + zone.volumes[1] = volume_2 + + for index, parameter := range parameters { + t.Run(fmt.Sprintf("inside_zone_%d", index), func(t *testing.T) { + assert.Equal(t, parameter.out, zone.Inside(parameter.in.x, parameter.in.y, parameter.in.z)) + }) + } +} + func Test_Grid_World(t *testing.T) { - world := generateWorld_Grid(10, 10, 10, Meter) + world := generateWorld_Grid(10, 10, 10, Meter) - _ = world + _ = world - for k := 0; k < 10; k++ { - for j := 0; j < 10; j++ { - for i := 0; i < 10; i++ { - // ... - } - } - } + for k := 0; k < 10; k++ { + for j := 0; j < 10; j++ { + for i := 0; i < 10; i++ { + // ... + } + } + } +} + +func Test_FindZoneId_World(t *testing.T) { + + type In struct { + i int64 + j int64 + k int64 + cellSize int64 + position Vector + } + + type Out struct { + found bool + zone_id uint32 + } + + type Params struct { + in In + out Out + } + + var parameters = []Params{ + {In{2, 2, 2, Meter, Vector{Meter, Meter, Meter}}, Out{true, 1}}, + {In{2, 2, 2, Meter, Vector{-Meter, -Meter, -Meter}}, Out{false, 0}}, + } + + for index, parameter := range parameters { + t.Run(fmt.Sprintf("inside_volume_%d", index), func(t *testing.T) { + world := generateWorld_Grid(parameter.in.i, parameter.in.j, parameter.in.k, parameter.in.cellSize) + var zone_id uint32 + found := world.FindZoneId(parameter.in.position.x, parameter.in.position.y, parameter.in.position.z, &zone_id) + assert.Equal(t, parameter.out.found, found) + assert.Equal(t, parameter.out.zone_id, zone_id) + }) + } }