world view ray casting
This commit is contained in:
@ -23,7 +23,8 @@ type BlockAppearance struct {
|
||||
NotSolid bool // Is block not solid, i.e., has no hitbox at all? (this makes the zero value reasonable)
|
||||
Light int // The light level it emits, 0 is none
|
||||
|
||||
Hitbox []itype.Boxd // Hitbox, in block-local coordinates; empty slice means a default hitbox of 1x1x1
|
||||
Hitbox []itype.Boxd // Hitbox, in block-local coordinates; empty slice means a default hitbox of 1x1x1
|
||||
Lookbox []itype.Boxd // Selection hitbox, hit only by the view ray; empty means Hitbox[]
|
||||
|
||||
RenderType BlockRenderType // Rendering type, defaults to OneTexture (zero value)
|
||||
|
||||
@ -130,6 +131,9 @@ func GetBlockAppearance(position itype.Vec3i, id, aux int, data itype.Dataset, w
|
||||
SizeX: 1, SizeY: 1, SizeZ: 1,
|
||||
}}
|
||||
}
|
||||
if len(app.Lookbox) == 0 {
|
||||
app.Lookbox = app.Hitbox
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
@ -146,6 +150,9 @@ func GetBlockAppearance(position itype.Vec3i, id, aux int, data itype.Dataset, w
|
||||
SizeX: 1, SizeY: 1, SizeZ: 1,
|
||||
}}
|
||||
}
|
||||
if len(app.Lookbox) == 0 {
|
||||
app.Lookbox = app.Hitbox
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
@ -172,6 +179,16 @@ func (b Block) Appearance(position itype.Vec3i) BlockAppearance {
|
||||
SizeX: 1, SizeY: 1, SizeZ: 1,
|
||||
}}
|
||||
}
|
||||
if len(app.Lookbox) == 0 {
|
||||
if len(app.Hitbox) == 0 {
|
||||
app.Lookbox = []itype.Boxd{{
|
||||
OffX: 0, OffY: 0, OffZ: 0,
|
||||
SizeX: 1, SizeY: 1, SizeZ: 1,
|
||||
}}
|
||||
} else {
|
||||
app.Lookbox = app.Hitbox
|
||||
}
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
|
48
internal/world/viewray.go
Normal file
48
internal/world/viewray.go
Normal file
@ -0,0 +1,48 @@
|
||||
package world
|
||||
|
||||
import "edgaru089.ml/go/gl01/internal/util/itype"
|
||||
|
||||
// CastViewRay
|
||||
func (w *World) CastViewRay(from, dir itype.Vec3d, maxlen float64) (ok bool, blockcoord itype.Vec3i, face itype.Direction, where itype.Vec3d, dist float64) {
|
||||
|
||||
bfrom := from.Floor()
|
||||
bfromdir := itype.Direction(-1)
|
||||
for bfrom.ToFloat64().Addv(0.5, 0.5, 0.5).Add(from.Negative()).Length() < maxlen {
|
||||
for todir := itype.Direction(0); todir < 6; todir++ {
|
||||
if todir == bfromdir {
|
||||
continue
|
||||
}
|
||||
|
||||
bto := bfrom.Add(itype.DirectionVeci[todir])
|
||||
block := w.Block(bto)
|
||||
|
||||
if block.Id != 0 {
|
||||
outbox := itype.Boxd{
|
||||
OffX: float64(bto[0]),
|
||||
OffY: float64(bto[1]),
|
||||
OffZ: float64(bto[2]),
|
||||
SizeX: 1,
|
||||
SizeY: 1,
|
||||
SizeZ: 1,
|
||||
}
|
||||
var outface itype.Direction
|
||||
if ok, outface, _, _ = outbox.IntersectRay(from, dir, maxlen); ok {
|
||||
app := block.Appearance(bto)
|
||||
for _, lb := range app.Lookbox {
|
||||
if ok, face, where, dist = lb.IntersectRay(from, dir, maxlen); ok {
|
||||
blockcoord = bto
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bfromdir = outface.Opposite()
|
||||
bfrom = bto
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok = false
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user