lpvec3d
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -284,3 +285,115 @@ func Bool2uint64(b bool) uint64 {
|
|||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LpVec3d struct {
|
||||||
|
X, Y, Z float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *LpVec3d) Encode(w io.Writer) error {
|
||||||
|
return writeVelocity(w, *v)
|
||||||
|
}
|
||||||
|
func (v *LpVec3d) Decode(r io.ReadSeeker) error {
|
||||||
|
v3, err := readVelocity(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.X = v3.X
|
||||||
|
v.Y = v3.Y
|
||||||
|
v.Z = v3.Z
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func readVelocity(r io.Reader) (LpVec3d, error) {
|
||||||
|
var marker, second uint8
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &marker); err != nil {
|
||||||
|
return LpVec3d{}, err
|
||||||
|
}
|
||||||
|
if marker == 0 {
|
||||||
|
return LpVec3d{}, nil
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &second); err != nil {
|
||||||
|
return LpVec3d{}, err
|
||||||
|
}
|
||||||
|
var packed uint32
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &packed); err != nil {
|
||||||
|
return LpVec3d{}, err
|
||||||
|
}
|
||||||
|
m := (uint64(packed) << 16) | (uint64(second) << 8) | uint64(marker)
|
||||||
|
n := int64(marker & 3)
|
||||||
|
if (marker & 4) != 0 {
|
||||||
|
// fast marker bit set, read varint for extended scale
|
||||||
|
scale, err := DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return LpVec3d{}, err
|
||||||
|
}
|
||||||
|
n |= (int64(scale) & 0xFFFFFFFF) << 2
|
||||||
|
}
|
||||||
|
x := fromLong(int64(m>>3), n)
|
||||||
|
y := fromLong(int64(m>>18), n)
|
||||||
|
z := fromLong(int64(m>>33), n)
|
||||||
|
return LpVec3d{X: x, Y: y, Z: z}, nil
|
||||||
|
}
|
||||||
|
func writeVelocity(w io.Writer, v LpVec3d) error {
|
||||||
|
const maxVal = 1.7179869183e10
|
||||||
|
const scaleMax = 32766.0
|
||||||
|
x := clamp(v.X, maxVal)
|
||||||
|
y := clamp(v.Y, maxVal)
|
||||||
|
z := clamp(v.Z, maxVal)
|
||||||
|
g := absMax(absMax(x, y), z)
|
||||||
|
if g < 3.051944088384301e-5 {
|
||||||
|
_, err := w.Write([]byte{0})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
l := int64(math.Ceil(g))
|
||||||
|
bl := (l & 3) != l
|
||||||
|
m := l
|
||||||
|
if bl {
|
||||||
|
m = (l & 3) | 4
|
||||||
|
}
|
||||||
|
lf := float64(l)
|
||||||
|
n := toLong(x/lf) << 3
|
||||||
|
o := toLong(y/lf) << 18
|
||||||
|
p := toLong(z/lf) << 33
|
||||||
|
q := m | n | o | p
|
||||||
|
var buf [7]byte
|
||||||
|
buf[0] = byte(q)
|
||||||
|
buf[1] = byte(q >> 8)
|
||||||
|
binary.BigEndian.PutUint32(buf[2:6], uint32(q>>16))
|
||||||
|
if _, err := w.Write(buf[:6]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if bl {
|
||||||
|
if err := EncodeVarInt(w, int32(l>>2)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func clamp(v, max float64) float64 {
|
||||||
|
if math.IsNaN(v) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if v > max {
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
if v < -max {
|
||||||
|
return -max
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
func absMax(a, b float64) float64 {
|
||||||
|
if math.Abs(a) > math.Abs(b) {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
func toLong(v float64) int64 {
|
||||||
|
return int64(math.Round((v*0.5 + 0.5) * 32766.0))
|
||||||
|
}
|
||||||
|
func fromLong(bits int64, scale int64) float64 {
|
||||||
|
v := bits & 0x7FFF
|
||||||
|
if v > 32766 {
|
||||||
|
v = 32766
|
||||||
|
}
|
||||||
|
return (float64(v)*2.0/32766.0 - 1.0) * float64(scale)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package v1_21_11
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/admin-else/strom/nbt"
|
"github.com/admin-else/strom/nbt"
|
||||||
"github.com/admin-else/strom/proto_base"
|
"github.com/admin-else/strom/proto_base"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"io"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArmorTrimMaterial struct {
|
type ArmorTrimMaterial struct {
|
||||||
@@ -16668,15 +16669,30 @@ func (ret *PlayToClientPacketEntityUpdateAttributes) Encode(w io.Writer) (err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PlayToClientPacketEntityVelocity struct {
|
type PlayToClientPacketEntityVelocity struct {
|
||||||
Val proto_base.ToDo
|
EntityId int32
|
||||||
|
Velocity proto_base.LpVec3d
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ret *PlayToClientPacketEntityVelocity) Decode(r io.ReadSeeker) (err error) {
|
func (ret *PlayToClientPacketEntityVelocity) Decode(r io.ReadSeeker) (err error) {
|
||||||
err = proto_base.ToDoError
|
ret.EntityId, err = proto_base.DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Velocity.Decode(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (ret *PlayToClientPacketEntityVelocity) Encode(w io.Writer) (err error) {
|
func (ret *PlayToClientPacketEntityVelocity) Encode(w io.Writer) (err error) {
|
||||||
err = proto_base.ToDoError
|
err = proto_base.EncodeVarInt(w, ret.EntityId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Velocity.Encode(w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20453,15 +20469,111 @@ func (ret *PlayToClientPacketSoundEffect) Encode(w io.Writer) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PlayToClientPacketSpawnEntity struct {
|
type PlayToClientPacketSpawnEntity struct {
|
||||||
Val proto_base.ToDo
|
EntityId int32
|
||||||
|
ObjectUUID uuid.UUID
|
||||||
|
Type int32
|
||||||
|
X float64
|
||||||
|
Y float64
|
||||||
|
Z float64
|
||||||
|
Velocity proto_base.LpVec3d
|
||||||
|
Pitch int8
|
||||||
|
Yaw int8
|
||||||
|
HeadPitch int8
|
||||||
|
ObjectData int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ret *PlayToClientPacketSpawnEntity) Decode(r io.ReadSeeker) (err error) {
|
func (ret *PlayToClientPacketSpawnEntity) Decode(r io.ReadSeeker) (err error) {
|
||||||
err = proto_base.ToDoError
|
ret.EntityId, err = proto_base.DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = io.ReadFull(r, ret.ObjectUUID[:])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret.Type, err = proto_base.DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.X)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.Y)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.Z)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Velocity.Decode(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.Pitch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.Yaw)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.HeadPitch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret.ObjectData, err = proto_base.DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (ret *PlayToClientPacketSpawnEntity) Encode(w io.Writer) (err error) {
|
func (ret *PlayToClientPacketSpawnEntity) Encode(w io.Writer) (err error) {
|
||||||
err = proto_base.ToDoError
|
err = proto_base.EncodeVarInt(w, ret.EntityId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = w.Write(ret.ObjectUUID[:])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = proto_base.EncodeVarInt(w, ret.Type)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.X)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.Y)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.Z)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Velocity.Encode(w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.Pitch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.Yaw)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.HeadPitch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = proto_base.EncodeVarInt(w, ret.ObjectData)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16491,15 +16491,30 @@ func (ret *PlayToClientPacketEntityUpdateAttributes) Encode(w io.Writer) (err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PlayToClientPacketEntityVelocity struct {
|
type PlayToClientPacketEntityVelocity struct {
|
||||||
Val proto_base.ToDo
|
EntityId int32
|
||||||
|
Velocity proto_base.LpVec3d
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ret *PlayToClientPacketEntityVelocity) Decode(r io.ReadSeeker) (err error) {
|
func (ret *PlayToClientPacketEntityVelocity) Decode(r io.ReadSeeker) (err error) {
|
||||||
err = proto_base.ToDoError
|
ret.EntityId, err = proto_base.DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Velocity.Decode(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (ret *PlayToClientPacketEntityVelocity) Encode(w io.Writer) (err error) {
|
func (ret *PlayToClientPacketEntityVelocity) Encode(w io.Writer) (err error) {
|
||||||
err = proto_base.ToDoError
|
err = proto_base.EncodeVarInt(w, ret.EntityId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Velocity.Encode(w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20276,15 +20291,111 @@ func (ret *PlayToClientPacketSoundEffect) Encode(w io.Writer) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PlayToClientPacketSpawnEntity struct {
|
type PlayToClientPacketSpawnEntity struct {
|
||||||
Val proto_base.ToDo
|
EntityId int32
|
||||||
|
ObjectUUID uuid.UUID
|
||||||
|
Type int32
|
||||||
|
X float64
|
||||||
|
Y float64
|
||||||
|
Z float64
|
||||||
|
Velocity proto_base.LpVec3d
|
||||||
|
Pitch int8
|
||||||
|
Yaw int8
|
||||||
|
HeadPitch int8
|
||||||
|
ObjectData int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ret *PlayToClientPacketSpawnEntity) Decode(r io.ReadSeeker) (err error) {
|
func (ret *PlayToClientPacketSpawnEntity) Decode(r io.ReadSeeker) (err error) {
|
||||||
err = proto_base.ToDoError
|
ret.EntityId, err = proto_base.DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = io.ReadFull(r, ret.ObjectUUID[:])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret.Type, err = proto_base.DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.X)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.Y)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.Z)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Velocity.Decode(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.Pitch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.Yaw)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Read(r, binary.BigEndian, &ret.HeadPitch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret.ObjectData, err = proto_base.DecodeVarInt(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (ret *PlayToClientPacketSpawnEntity) Encode(w io.Writer) (err error) {
|
func (ret *PlayToClientPacketSpawnEntity) Encode(w io.Writer) (err error) {
|
||||||
err = proto_base.ToDoError
|
err = proto_base.EncodeVarInt(w, ret.EntityId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = w.Write(ret.ObjectUUID[:])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = proto_base.EncodeVarInt(w, ret.Type)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.X)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.Y)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.Z)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Velocity.Encode(w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.Pitch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.Yaw)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = binary.Write(w, binary.BigEndian, ret.HeadPitch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = proto_base.EncodeVarInt(w, ret.ObjectData)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -634,7 +634,7 @@ func (g *Generator) RegisterDecoderNatives() {
|
|||||||
"varlong": VarLongDecoder,
|
"varlong": VarLongDecoder,
|
||||||
"anonymousNbt": DefaultDecoder,
|
"anonymousNbt": DefaultDecoder,
|
||||||
"anonOptionalNbt": DefaultDecoder, // I have no idea what the difference is between these two
|
"anonOptionalNbt": DefaultDecoder, // I have no idea what the difference is between these two
|
||||||
"lpVec3": ToDoDecoder,
|
"lpVec3": DefaultDecoder,
|
||||||
"UUID": UUIDDecoder,
|
"UUID": UUIDDecoder,
|
||||||
"restBuffer": DefaultDecoder,
|
"restBuffer": DefaultDecoder,
|
||||||
|
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ func (g *Generator) RegisterEncoderNatives() {
|
|||||||
"anonOptionalNbt": DefaultEncoder, // I have no idea what the difference is between these two
|
"anonOptionalNbt": DefaultEncoder, // I have no idea what the difference is between these two
|
||||||
"UUID": UUIDEncoder,
|
"UUID": UUIDEncoder,
|
||||||
"restBuffer": DefaultEncoder,
|
"restBuffer": DefaultEncoder,
|
||||||
"lpVec3": ToDoEncoder,
|
"lpVec3": DefaultEncoder,
|
||||||
"string": StringEncoder,
|
"string": StringEncoder,
|
||||||
|
|
||||||
"f32": SimpleTypeEncoder,
|
"f32": SimpleTypeEncoder,
|
||||||
|
|||||||
@@ -225,6 +225,6 @@ func (g *Generator) RegisterNatives() {
|
|||||||
"bitflags": VisitBitFlagsType,
|
"bitflags": VisitBitFlagsType,
|
||||||
"topBitSetTerminatedArray": VisitToDoType,
|
"topBitSetTerminatedArray": VisitToDoType,
|
||||||
"todo": VisitToDoType,
|
"todo": VisitToDoType,
|
||||||
"lpVec3": VisitToDoType,
|
"lpVec3": MakeSelectorVisitor("proto_base", "LpVec3d"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user