Move to our own vector module instead of Panda3D

This commit is contained in:
Tanner Collin 2021-03-23 21:01:48 +00:00
parent 2fa3044acb
commit 0bdae1f775
3 changed files with 137 additions and 13 deletions

21
bot.py
View File

@ -24,7 +24,7 @@ from minecraft.networking.packets import Packet, clientbound, serverbound
from protocol.managers import DataManager, ChunksManager, ChatManager, ChunkNotLoadedException from protocol.managers import DataManager, ChunksManager, ChatManager, ChunkNotLoadedException
from munch import Munch from munch import Munch
from panda3d.core import LPoint3f, LVector3f from vector import Point3D, Vector3D
import game import game
importlib.reload(game) importlib.reload(game)
@ -41,9 +41,9 @@ importlib.reload(mcdata)
last_tick = time.time() last_tick = time.time()
PITCH_ANGLE_DIR = LVector3f(x=0, y=1, z=0) PITCH_ANGLE_DIR = Vector3D((0, 1, 0))
YAW_ANGLE_DIR = LVector3f(x=0, y=0, z=-1) YAW_ANGLE_DIR = Vector3D((0, 0, -1))
YAW_ANGLE_REF = LVector3f(x=0, y=1, z=0) YAW_ANGLE_REF = Vector3D((0, 1, 0))
YAW_LOOK_AHEAD = 4 YAW_LOOK_AHEAD = 4
@ -105,7 +105,7 @@ def tick(global_state):
########## player physics ########## ########## player physics ##########
if g.path and len(g.path): if g.path and len(g.path):
target = LPoint3f(g.path[0]) target = Point3D(g.path[0])
target.x += 0.5 target.x += 0.5
target.z += 0.5 target.z += 0.5
@ -158,11 +158,11 @@ def tick(global_state):
g.y_a = 0 g.y_a = 0
if g.look_at: if g.look_at:
look_at = LPoint3f(g.look_at) look_at = Point3D(g.look_at)
elif g.path and len(g.path) > YAW_LOOK_AHEAD: elif g.path and len(g.path) > YAW_LOOK_AHEAD:
look_at = LPoint3f(g.path[YAW_LOOK_AHEAD]) look_at = Point3D(g.path[YAW_LOOK_AHEAD])
elif g.path and len(g.path): elif g.path and len(g.path):
look_at = LPoint3f(g.path[-1]) look_at = Point3D(g.path[-1])
else: else:
look_at = None look_at = None
@ -177,9 +177,10 @@ def tick(global_state):
target_pitch_d = target_pitch - g.pitch target_pitch_d = target_pitch - g.pitch
g.pitch += utils.cap(target_pitch_d, 10) g.pitch += utils.cap(target_pitch_d, 10)
# remove vertical component for yaw calculation # remove vertical component for yaw calculation
look_at_d.y = 0 look_at_d.y = 0
if look_at_d.length() > 0.6:
target_yaw = look_at_d.normalized().signedAngleDeg(other=YAW_ANGLE_DIR, ref=YAW_ANGLE_REF) target_yaw = look_at_d.normalized().signedAngleDeg(other=YAW_ANGLE_DIR, ref=YAW_ANGLE_REF)
target_yaw_d = target_yaw - g.yaw target_yaw_d = target_yaw - g.yaw
target_yaw_d = (target_yaw_d + 180) % 360 - 180 target_yaw_d = (target_yaw_d + 180) % 360 - 180

View File

@ -8,7 +8,7 @@ from itertools import count
from munch import Munch from munch import Munch
from copy import copy from copy import copy
from panda3d.core import LPoint3f from vector import Point3D
from minecraft.networking.packets import Packet, clientbound, serverbound from minecraft.networking.packets import Packet, clientbound, serverbound
from minecraft.networking.types import BlockFace from minecraft.networking.types import BlockFace
@ -392,7 +392,7 @@ class Game:
def handle_block_change(self, packet): def handle_block_change(self, packet):
if packet.block_state_id == blocks.SOUL_TORCH: if packet.block_state_id == blocks.SOUL_TORCH:
try: try:
self.g.goal = LPoint3f(x=packet.location[0], y=packet.location[1], z=packet.location[2]) self.g.goal = Point3D((packet.location[0], packet.location[1], packet.location[2]))
print('new waypoint:', self.g.goal) print('new waypoint:', self.g.goal)
start = time.time() start = time.time()
@ -419,7 +419,7 @@ class Game:
def handle_position_and_look(self, packet): def handle_position_and_look(self, packet):
print(packet) print(packet)
p = LPoint3f(x=packet.x, y=packet.y, z=packet.z) p = Point3D((packet.x, packet.y, packet.z))
self.g.pos = p self.g.pos = p
confirm_packet = serverbound.play.TeleportConfirmPacket() confirm_packet = serverbound.play.TeleportConfirmPacket()

123
vector.py Normal file
View File

@ -0,0 +1,123 @@
import math
class Vector3D:
def __init__(self, vector):
self.x = vector[0]
self.y = vector[1]
self.z = vector[2]
@property
def xz(self):
return Vector3D((self.x, 0, self.z))
def tuple(self):
return (self.x, self.y, self.z)
def __getitem__(self, key):
return self.tuple()[key]
def length(self):
return math.hypot(self.x, self.y, self.z)
def normalized(self):
x = self.x / self.length()
y = self.y / self.length()
z = self.z / self.length()
return Vector3D((x, y, z))
def dot(self, other):
return self.x * other.x + self.y * other.y + self.z * other.z
def cross(self, other):
a1, a2, a3 = self.tuple()
b1, b2, b3 = other.tuple()
return Vector3D((a2*b3-a3*b2, a3*b1-a1*b3, a1*b2-a2*b1))
def angleDeg(self, other):
ratio = self.dot(other) / (self.length() * other.length())
rads = math.acos(ratio)
return math.degrees(rads)
def signedAngleDeg(self, other, ref):
angle1 = self.angleDeg(other)
cross = self.cross(ref)
angle2 = other.angleDeg(cross)
if angle2 < 90:
return -angle1
else:
return angle1
def __repr__(self):
return 'Vector3D(x={}, y={}, z={})'.format(self.x, self.y, self.z)
def __str__(self):
return '[{}, {}, {}]'.format(self.x, self.y, self.z)
class Point3D:
def __init__(self, point):
self.x = point[0]
self.y = point[1]
self.z = point[2]
def __sub__(self, other):
#x = other.x - self.x
#y = other.y - self.y
#z = other.z - self.z
x = self.x - other.x
y = self.y - other.y
z = self.z - other.z
return Vector3D((x, y, z))
def tuple(self):
return (self.x, self.y, self.z)
def __getitem__(self, key):
return self.tuple()[key]
def __repr__(self):
return 'Point3D(x={}, y={}, z={})'.format(self.x, self.y, self.z)
def __str__(self):
return '({}, {}, {})'.format(self.x, self.y, self.z)
if __name__ == '__main__':
# test to make sure our Vector module is the same as Panda3D
from panda3d.core import LPoint3f, LVector3f
import random
pPITCH_ANGLE_DIR = LVector3f(x=0, y=1, z=0)
pYAW_ANGLE_DIR = LVector3f(x=0, y=0, z=-1)
pYAW_ANGLE_REF = LVector3f(x=0, y=1, z=0)
PITCH_ANGLE_DIR = Vector3D((0, 1, 0))
YAW_ANGLE_DIR = Vector3D((0, 0, -1))
YAW_ANGLE_REF = Vector3D((0, 1, 0))
for _ in range(1000):
r = lambda: random.uniform(-10, 10)
a, b, c = r(), r(), r()
plook_at_d = LVector3f(x=a, y=b, z=c)
look_at_d = Vector3D((a, b, c))
ptarget_pitch = plook_at_d.normalized().angleDeg(pPITCH_ANGLE_DIR)
target_pitch = look_at_d.normalized().angleDeg(PITCH_ANGLE_DIR)
if round(ptarget_pitch) != round(target_pitch):
print('mismatch:', ptarget_pitch, target_pitch)
break
else: # for
print('no mismatches')
for _ in range(1000):
r = lambda: random.uniform(-10, 10)
a, b, c = r(), r(), r()
plook_at_d = LVector3f(x=a, y=b, z=c)
look_at_d = Vector3D((a, b, c))
ptarget_yaw = plook_at_d.normalized().signedAngleDeg(other=pYAW_ANGLE_DIR, ref=pYAW_ANGLE_REF)
target_yaw = look_at_d.normalized().signedAngleDeg(other=YAW_ANGLE_DIR, ref=YAW_ANGLE_REF)
if round(ptarget_yaw) != round(target_yaw):
print('mismatch:', ptarget_yaw, target_yaw)
break
else: # for
print('no mismatches')