|
|
@@ -1,6 +1,7 @@
|
|
|
import numpy as np
|
|
|
import pyrr
|
|
|
from collections import defaultdict
|
|
|
+import copy
|
|
|
|
|
|
|
|
|
def getRay(x, y):
|
|
|
@@ -38,17 +39,42 @@ def heuristic_fun(initparams, k, t=None):
|
|
|
t = initparams.goal
|
|
|
return max([abs(t[0] - k[0]), abs(t[1] - k[1]), abs(t[2] - k[2])])
|
|
|
|
|
|
-def isinbound(i, x):
|
|
|
+def isinbound(i, x, mode=False):
|
|
|
+ if mode == 'obb':
|
|
|
+ return isinobb(i, x)
|
|
|
if i[0] <= x[0] < i[3] and i[1] <= x[1] < i[4] and i[2] <= x[2] < i[5]:
|
|
|
return True
|
|
|
return False
|
|
|
|
|
|
-
|
|
|
def isinball(i, x):
|
|
|
if getDist(i[0:3], x) <= i[3]:
|
|
|
return True
|
|
|
return False
|
|
|
|
|
|
+def isinobb(i, x):
|
|
|
+ # pt = i.O.T@np.array(x) # transform the point from {W} to {body}
|
|
|
+ # minx,miny,minz,maxx,maxy,maxz = i.P[0] - i.E[0],i.P[1] - i.E[1],i.P[2] - i.E[2],i.P[0] + i.E[0],i.P[1] + i.E[1],i.P[2] + i.E[2]
|
|
|
+ T = np.vstack([np.column_stack([i.O.T,-i.O.T@i.P]),[0,0,0,1]])
|
|
|
+ pt = T@np.append(x,1) # transform the point from {W} to {body}
|
|
|
+ minx,miny,minz,maxx,maxy,maxz = - i.E[0],- i.E[1],- i.E[2],+ i.E[0],+ i.E[1],+ i.E[2]
|
|
|
+ block = [minx,miny,minz,maxx,maxy,maxz]
|
|
|
+ return isinbound(block, pt)
|
|
|
+
|
|
|
+def OBB2AABB(obb):
|
|
|
+ # https://www.gamasutra.com/view/feature/131790/simple_intersection_tests_for_games.php?print=1
|
|
|
+ aabb = copy.deepcopy(obb)
|
|
|
+ P = obb.P
|
|
|
+ a = obb.E
|
|
|
+ A = obb.O
|
|
|
+ # a1(A1 dot x) + a2(A2 dot x) + a3(A3 dot x)
|
|
|
+ Ex = a[0]*abs(A[0][0]) + a[1]*abs(A[1][0]) + a[2]*abs(A[2][0])
|
|
|
+ Ey = a[0]*abs(A[0][1]) + a[1]*abs(A[1][1]) + a[2]*abs(A[2][1])
|
|
|
+ Ez = a[0]*abs(A[0][2]) + a[1]*abs(A[1][2]) + a[2]*abs(A[2][2])
|
|
|
+ E = np.array([Ex, Ey, Ez])
|
|
|
+ aabb.P = P
|
|
|
+ aabb.E = E
|
|
|
+ aabb.O = np.array([[1,0,0],[0,1,0],[0,0,1]])
|
|
|
+ return aabb
|
|
|
|
|
|
def lineSphere(p0, p1, ball):
|
|
|
# https://cseweb.ucsd.edu/classes/sp19/cse291-d/Files/CSE291_13_CollisionDetection.pdf
|
|
|
@@ -68,7 +94,6 @@ def lineSphere(p0, p1, ball):
|
|
|
if (k[0] * k[0] + k[1] * k[1] + k[2] * k[2]) <= r ** 2: return True
|
|
|
return False
|
|
|
|
|
|
-
|
|
|
def lineAABB(p0, p1, dist, aabb):
|
|
|
# https://www.gamasutra.com/view/feature/131790/simple_intersection_tests_for_games.php?print=1
|
|
|
# aabb should have the attributes of P, E as center point and extents
|
|
|
@@ -94,6 +119,12 @@ def lineAABB(p0, p1, dist, aabb):
|
|
|
|
|
|
return True
|
|
|
|
|
|
+def lineOBB(p0, p1, dist, obb):
|
|
|
+ T = np.vstack([np.column_stack([obb.O.T,-obb.O.T@obb.P]),[0,0,0,1]])
|
|
|
+ p0 = T@np.append(p0,1) # transform the points to the box
|
|
|
+ p1 = T@np.append(p1,1)
|
|
|
+ return lineAABB(p0[0:3],p1[0:3],dist,obb)
|
|
|
+
|
|
|
def OBBOBB(obb1, obb2):
|
|
|
# https://www.gamasutra.com/view/feature/131790/simple_intersection_tests_for_games.php?print=1
|
|
|
# each obb class should contain attributes:
|
|
|
@@ -147,7 +178,6 @@ def OBBOBB(obb1, obb2):
|
|
|
#L = A0 x B2
|
|
|
ra = a[1]*abs(R[2][2]) + a[2]*abs(R[1][2])
|
|
|
rb = b[0]*abs(R[0][1]) + b[1]*abs(R[0][0])
|
|
|
-
|
|
|
t = abs(T[2]*R[1][2] - T[1]*R[2][2])
|
|
|
if t > ra + rb:
|
|
|
return False
|
|
|
@@ -155,7 +185,6 @@ def OBBOBB(obb1, obb2):
|
|
|
#L = A1 x B0
|
|
|
ra = a[0]*abs(R[2][0]) + a[2]*abs(R[0][0])
|
|
|
rb = b[1]*abs(R[1][2]) + b[2]*abs(R[1][1])
|
|
|
-
|
|
|
t = abs( T[0]*R[2][0] - T[2]*R[0][0] )
|
|
|
if t > ra + rb:
|
|
|
return False
|
|
|
@@ -198,9 +227,6 @@ def OBBOBB(obb1, obb2):
|
|
|
# no separating axis found,
|
|
|
# the two boxes overlap
|
|
|
return True
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
|
|
|
def StateSpace(env, factor=0):
|
|
|
boundary = env.boundary
|
|
|
@@ -234,18 +260,21 @@ def isCollide(initparams, x, child, dist):
|
|
|
'''specified for expansion in A* 3D lookup table'''
|
|
|
if dist==None:
|
|
|
dist = getDist(x, child)
|
|
|
+ # check in bound
|
|
|
if not isinbound(initparams.env.boundary, child):
|
|
|
return True, dist
|
|
|
+ # check collision in AABB
|
|
|
for i in range(len(initparams.env.AABB)):
|
|
|
- # if isinbound(initparams.env.blocks[i], child):
|
|
|
- # return True, dist
|
|
|
if lineAABB(x, child, dist, initparams.env.AABB[i]):
|
|
|
return True, dist
|
|
|
+ # check collision in ball
|
|
|
for i in initparams.env.balls:
|
|
|
- # if isinball(i, child):
|
|
|
- # return True, dist
|
|
|
if lineSphere(x, child, i):
|
|
|
return True, dist
|
|
|
+ # check collision with obb
|
|
|
+ for i in initparams.env.OBB:
|
|
|
+ if lineOBB(x, child, dist, i):
|
|
|
+ return True, dist
|
|
|
return False, dist
|
|
|
|
|
|
|
|
|
@@ -256,6 +285,8 @@ def children(initparams, x, settings = 0):
|
|
|
resolution = initparams.env.resolution
|
|
|
for direc in initparams.Alldirec:
|
|
|
child = tuple(map(np.add, x, np.multiply(direc, resolution)))
|
|
|
+ if any([isinobb(i, child) for i in initparams.env.OBB]):
|
|
|
+ continue
|
|
|
if any([isinball(i ,child) for i in initparams.env.balls]):
|
|
|
continue
|
|
|
if any([isinbound(i ,child) for i in initparams.env.blocks]):
|
|
|
@@ -303,13 +334,8 @@ def initcost(initparams):
|
|
|
c[xi][child] = cost(initparams, xi, child)
|
|
|
return c
|
|
|
|
|
|
-class obb(object):
|
|
|
- def __init__(self, P, E, O):
|
|
|
- self.P = P
|
|
|
- self.E = E
|
|
|
- self.O = O
|
|
|
-
|
|
|
if __name__ == "__main__":
|
|
|
- obb1 = obb([0,0,0],[1,1,1],[[1,0,0],[0,1,0],[0,0,1]])
|
|
|
- obb2 = obb([1,1,0],[1,1,1],[[1/np.sqrt(3)*1,1/np.sqrt(3)*1,1/np.sqrt(3)*1],[np.sqrt(3/2)*(-1/3),np.sqrt(3/2)*2/3,np.sqrt(3/2)*(-1/3)],[np.sqrt(1/8)*(-2),0,np.sqrt(1/8)*2]])
|
|
|
- print(OBBOBB(obb1, obb2))
|
|
|
+ pass
|
|
|
+ # obb1 = obb([0,0,0],[1,1,1],[[1,0,0],[0,1,0],[0,0,1]])
|
|
|
+ # obb2 = obb([1,1,0],[1,1,1],[[1/np.sqrt(3)*1,1/np.sqrt(3)*1,1/np.sqrt(3)*1],[np.sqrt(3/2)*(-1/3),np.sqrt(3/2)*2/3,np.sqrt(3/2)*(-1/3)],[np.sqrt(1/8)*(-2),0,np.sqrt(1/8)*2]])
|
|
|
+ # print(OBBOBB(obb1, obb2))
|