Use block bounding boxes
This commit is contained in:
@ -38,6 +38,7 @@ var (
|
|||||||
safeWalkBlocks = make(map[world.BlockStatus]struct{}, 128)
|
safeWalkBlocks = make(map[world.BlockStatus]struct{}, 128)
|
||||||
walkBlocks = []block.Block{
|
walkBlocks = []block.Block{
|
||||||
block.Air,
|
block.Air,
|
||||||
|
block.CaveAir,
|
||||||
block.Grass,
|
block.Grass,
|
||||||
block.Torch,
|
block.Torch,
|
||||||
block.OakSign,
|
block.OakSign,
|
||||||
@ -53,6 +54,7 @@ var (
|
|||||||
block.JungleWallSign,
|
block.JungleWallSign,
|
||||||
block.DarkOakWallSign,
|
block.DarkOakWallSign,
|
||||||
block.Cornflower,
|
block.Cornflower,
|
||||||
|
block.TallGrass,
|
||||||
}
|
}
|
||||||
|
|
||||||
additionalCostBlocks = map[*block.Block]int{
|
additionalCostBlocks = map[*block.Block]int{
|
||||||
@ -92,3 +94,7 @@ func AirLikeBlock(bID world.BlockStatus) bool {
|
|||||||
_, ok := safeWalkBlocks[bID]
|
_, ok := safeWalkBlocks[bID]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsLadder(bID world.BlockStatus) bool {
|
||||||
|
return uint32(bID) >= block.Ladder.MinStateID && uint32(bID) <= block.Ladder.MaxStateID
|
||||||
|
}
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
package phy
|
package phy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/Tnze/go-mc/bot/path"
|
"github.com/Tnze/go-mc/bot/path"
|
||||||
"github.com/Tnze/go-mc/bot/world"
|
"github.com/Tnze/go-mc/bot/world"
|
||||||
"github.com/Tnze/go-mc/bot/world/entity/player"
|
"github.com/Tnze/go-mc/bot/world/entity/player"
|
||||||
|
"github.com/Tnze/go-mc/data/block/shape"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -18,8 +20,9 @@ const (
|
|||||||
maxYawChange = 33
|
maxYawChange = 33
|
||||||
maxPitchChange = 11
|
maxPitchChange = 11
|
||||||
|
|
||||||
stepHeight = 0.6
|
stepHeight = 0.6
|
||||||
minJumpTicks = 14
|
minJumpTicks = 14
|
||||||
|
ladderMaxSpeed = 0.15
|
||||||
|
|
||||||
gravity = 0.08
|
gravity = 0.08
|
||||||
drag = 0.98
|
drag = 0.98
|
||||||
@ -59,6 +62,7 @@ func (s *State) ServerPositionUpdate(player player.Pos, w World) error {
|
|||||||
s.Pos = path.Point{X: player.X, Y: player.Y, Z: player.Z}
|
s.Pos = path.Point{X: player.X, Y: player.Y, Z: player.Z}
|
||||||
s.Yaw, s.Pitch = float64(player.Yaw), float64(player.Pitch)
|
s.Yaw, s.Pitch = float64(player.Yaw), float64(player.Pitch)
|
||||||
s.Vel = path.Point{}
|
s.Vel = path.Point{}
|
||||||
|
fmt.Println("TELEPORT!")
|
||||||
s.onGround, s.collision.vertical, s.collision.horizontal = false, false, false
|
s.onGround, s.collision.vertical, s.collision.horizontal = false, false, false
|
||||||
s.Run = true
|
s.Run = true
|
||||||
return nil
|
return nil
|
||||||
@ -76,12 +80,24 @@ func (s *State) surroundings(query AABB, w World) Surrounds {
|
|||||||
minZ, maxZ := int(math.Floor(query.Z.Min)), int(math.Floor(query.Z.Max))+1
|
minZ, maxZ := int(math.Floor(query.Z.Min)), int(math.Floor(query.Z.Max))+1
|
||||||
minX, maxX := int(math.Floor(query.X.Min)), int(math.Floor(query.X.Max))+1
|
minX, maxX := int(math.Floor(query.X.Min)), int(math.Floor(query.X.Max))+1
|
||||||
|
|
||||||
out := Surrounds(make([]AABB, 0, abs(maxY, minY)*abs(maxZ, minZ)*abs(maxX, minX)))
|
out := Surrounds(make([]AABB, 0, abs(maxY, minY)*abs(maxZ, minZ)*abs(maxX, minX)*2))
|
||||||
for y := minY; y < maxY; y++ {
|
for y := minY; y < maxY; y++ {
|
||||||
for z := minZ; z < maxZ; z++ {
|
for z := minZ; z < maxZ; z++ {
|
||||||
for x := minX; x < maxX; x++ {
|
for x := minX; x < maxX; x++ {
|
||||||
if block := w.GetBlockStatus(x, y, z); !path.AirLikeBlock(block) {
|
bStateID := w.GetBlockStatus(x, y, z)
|
||||||
out = append(out, AABB{X: MinMax{Max: 1}, Y: MinMax{Max: 1}, Z: MinMax{Max: 1}, Block: block}.Offset(float64(x), float64(y), float64(z)))
|
if !path.AirLikeBlock(bStateID) {
|
||||||
|
bbs, err := shape.CollisionBoxes(bStateID)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for _, box := range bbs {
|
||||||
|
out = append(out, AABB{
|
||||||
|
X: MinMax{Min: box.Min.X, Max: box.Max.X},
|
||||||
|
Y: MinMax{Min: box.Min.Y, Max: box.Max.Y},
|
||||||
|
Z: MinMax{Min: box.Min.Z, Max: box.Max.Z},
|
||||||
|
Block: bStateID,
|
||||||
|
}.Offset(float64(x), float64(y), float64(z)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,7 +140,7 @@ func (s *State) Tick(input path.Inputs, w World) error {
|
|||||||
}
|
}
|
||||||
//fmt.Printf("pY = %.2f, maxblockY = %.1f (delta = %.1f)\n", bb.Y.Min, y, bb.Y.Min-y)
|
//fmt.Printf("pY = %.2f, maxblockY = %.1f (delta = %.1f)\n", bb.Y.Min, y, bb.Y.Min-y)
|
||||||
if d := bb.Y.Min - y; d >= -stepHeight && d < stepHeight-1 {
|
if d := bb.Y.Min - y; d >= -stepHeight && d < stepHeight-1 {
|
||||||
bb := player.Offset(0, stepHeight, 0)
|
bb := player.Offset(0, -d, 0)
|
||||||
player, newVel = s.computeCollision(bb, bb.Extend(s.Vel.X, s.Vel.Y, s.Vel.Z), w)
|
player, newVel = s.computeCollision(bb, bb.Extend(s.Vel.X, s.Vel.Y, s.Vel.Z), w)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +211,14 @@ func (s *State) tickVelocity(input path.Inputs, w World) {
|
|||||||
s.Vel.Y *= drag
|
s.Vel.Y *= drag
|
||||||
s.Vel.X *= inertia
|
s.Vel.X *= inertia
|
||||||
s.Vel.Z *= inertia
|
s.Vel.Z *= inertia
|
||||||
|
|
||||||
|
lower := w.GetBlockStatus(int(math.Floor(s.Pos.X)), int(math.Floor(s.Pos.Y)), int(math.Floor(s.Pos.Z)))
|
||||||
|
if path.IsLadder(lower) {
|
||||||
|
s.Vel.X = math.Min(math.Max(-ladderMaxSpeed, s.Vel.X), ladderMaxSpeed)
|
||||||
|
s.Vel.Z = math.Min(math.Max(-ladderMaxSpeed, s.Vel.Z), ladderMaxSpeed)
|
||||||
|
s.Vel.Y = math.Min(math.Max(-ladderMaxSpeed, s.Vel.Y), ladderMaxSpeed)
|
||||||
|
fmt.Println(s.Vel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) computeCollision(bb, query AABB, w World) (outBB AABB, outVel path.Point) {
|
func (s *State) computeCollision(bb, query AABB, w World) (outBB AABB, outVel path.Point) {
|
||||||
|
@ -43,6 +43,7 @@ func main() {
|
|||||||
package shape
|
package shape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/Tnze/go-mc/bot/world"
|
||||||
"github.com/Tnze/go-mc/data/block"
|
"github.com/Tnze/go-mc/data/block"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -63,6 +64,27 @@ type BoundingBox struct {
|
|||||||
Min,Max BoundingTriplet
|
Min,Max BoundingTriplet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CollisionBoxes returns the set of bounding boxes for that block state ID.
|
||||||
|
func CollisionBoxes(bStateID world.BlockStatus) ([]BoundingBox, error) {
|
||||||
|
bID := block.StateID[uint32(bStateID)]
|
||||||
|
if bID == 0 {
|
||||||
|
return nil, fmt.Errorf("unknown state ID: %v", bStateID)
|
||||||
|
}
|
||||||
|
b, ok := block.ByID[bID]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unknown block ID: %v", bID)
|
||||||
|
}
|
||||||
|
shapes, ok := ByBlockID[bID]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unknown shape for block ID: %v", bID)
|
||||||
|
}
|
||||||
|
shapeIdx := (uint32(bStateID) - b.MinStateID) % uint32(len(shapes))
|
||||||
|
if int(shapeIdx) > len(shapes) {
|
||||||
|
return nil, fmt.Errorf("shape index out of bounds: %v >= %v", shapeIdx, len(shapes))
|
||||||
|
}
|
||||||
|
return Dimensions[shapes[shapeIdx]].Boxes, nil
|
||||||
|
}
|
||||||
|
|
||||||
`)
|
`)
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user