Advertisement
MrCheeze

polyoverflow.py for Dolphin (Felk's python build)

Feb 10th, 2024
1,202
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.38 KB | None | 1 0
  1. from dolphin import event, gui, controller, memory, registers, savestate
  2.  
  3. addr_globalContext = 0x801C9660 + 0xB1C140
  4. addr_colCtx = addr_globalContext + 0x7C0
  5. addr_exitList = addr_globalContext + 0x11E04
  6. colCtx_colHeader = memory.read_u32(addr_colCtx) + 0xB1C140
  7. exitList = memory.read_u32(addr_exitList) + 0xB1C140
  8. colCtx_colHeader_vtxList = memory.read_u32(colCtx_colHeader + 0x10) + 0xB1C140
  9. colCtx_colHeader_polyList = memory.read_u32(colCtx_colHeader + 0x18) + 0xB1C140
  10. colCtx_colHeader_surfaceTypeList = memory.read_u32(colCtx_colHeader + 0x1C) + 0xB1C140
  11. '''
  12. def sign(p1x, p1z, p2x, p2z, p3x, p3z):
  13.    return (p1x - p3x) * (p2z - p3z) - (p2x - p3x) * (p1z - p3z)
  14.  
  15. def pointInTriangle(px, pz, v1x, v1z, v2x, v2z, v3x, v3z):
  16.  
  17.    if v1x==v2x and v1z == v2z:
  18.        return False
  19.    if v2x==v3x and v2z == v3z:
  20.        return False
  21.    if v3x==v1x and v3z == v1z:
  22.        return False
  23.  
  24.    d1 = sign(px, pz, v1x, v1z, v2x, v2z)
  25.    d2 = sign(px, pz, v2x, v2z, v3x, v3z)
  26.    d3 = sign(px, pz, v3x, v3z, v1x, v1z)
  27.    has_neg = (d1 < 0) or (d2 < 0) or (d3 < 0)
  28.    has_pos = (d1 > 0) or (d2 > 0) or (d3 > 0)
  29.    return not (has_neg and has_pos)
  30.  
  31. def findYPosOfTriangleForXZ(x, z, p1x, p1y, p1z, p2x, p2y, p2z, p3x, p3y, p3z):
  32.    b = (x*(p2z-p1z) - p1x*(p2z-p1z) - z*(p2x-p1x) + p1z*(p2x-p1x))/((p3x-p1x)*(p2z-p1z) - (p3z-p1z)*(p2x-p1x))
  33.    a = (x - p1x - b*(p3x-p1x))/(p2x-p1x)
  34.    return p1y + a*(p2y-p1y) + b*(p3y-p1y)
  35. '''
  36.  
  37. def IS_ZERO(f):
  38.     return abs(f) < 0.008
  39.  
  40. def SQ(x):
  41.     return x*x
  42.  
  43. def Math3D_CirSquareVsTriSquare(x0, y0, x1, y1, x2, y2, centerX, centerY, radius):
  44.     minX = maxX = x0
  45.     minY = maxY = y0
  46.     if x1 < minX:
  47.         minX = x1
  48.     elif maxX < x1:
  49.         maxX = x1
  50.     if y1 < minY:
  51.         minY = y1
  52.     elif maxY < y1:
  53.         maxY = y1
  54.     if x2 < minX:
  55.         minX = x2
  56.     elif maxX < x2:
  57.         maxX = x2
  58.     if y2 < minY:
  59.         minY = y2
  60.     elif maxY < y2:
  61.         maxY = y2
  62.     return (minX - radius) <= centerX and (maxX + radius) >= centerX and (minY - radius) <= centerY and (maxY + radius) >= centerY
  63.    
  64. def Math3D_PointDistSqToLine2D(x0, y0, x1, y1, x2, y2):
  65.     ret = False
  66.     xDiff = x2 - x1
  67.     yDiff = y2 - y1
  68.     distSq = SQ(xDiff) + SQ(yDiff)
  69.     if IS_ZERO(distSq):
  70.         return False, 0.0
  71.     perpendicularRatio = (((x0 - x1) * xDiff) + (y0 - y1) * yDiff) / distSq
  72.     if perpendicularRatio >= 0.0 and perpendicularRatio <= 1.0:
  73.         ret = True
  74.     perpendicularPoint = [(xDiff * perpendicularRatio) + x1, (yDiff * perpendicularRatio) + y1]
  75.     lineLenSq = SQ(perpendicularPoint[0] - x0) + SQ(perpendicularPoint[1] - y0)
  76.     return ret, lineLenSq
  77.  
  78. def Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, detMax, chkDist, ny):
  79.     if not Math3D_CirSquareVsTriSquare(v0[2], v0[0], v1[2], v1[0], v2[2], v2[0], z, x, chkDist):
  80.         return False
  81.     chkDistSq = SQ(chkDist)
  82.     if ((SQ(v0[2] - z) + SQ(v0[0] - x)) < chkDistSq) or ((SQ(v1[2] - z) + SQ(v1[0] - x)) < chkDistSq) or ((SQ(v2[2] - z) + SQ(v2[0] - x)) < chkDistSq):
  83.         return True
  84.     detv0v1 = ((v0[2] - z) * (v1[0] - x)) - ((v0[0] - x) * (v1[2] - z))
  85.     detv1v2 = ((v1[2] - z) * (v2[0] - x)) - ((v1[0] - x) * (v2[2] - z))
  86.     detv2v0 = ((v2[2] - z) * (v0[0] - x)) - ((v2[0] - x) * (v0[2] - z))
  87.     if ((detMax >= detv0v1) and (detMax >= detv1v2) and (detMax >= detv2v0)) or ((-detMax <= detv0v1) and (-detMax <= detv1v2) and (-detMax <= detv2v0)):
  88.         return True
  89.     if abs(ny) > 0.5:
  90.         ret, distToEdgeSq = Math3D_PointDistSqToLine2D(z, x, v0[2], v0[0], v1[2], v1[0])
  91.         if ret and distToEdgeSq < chkDistSq:
  92.             return True
  93.         ret, distToEdgeSq = Math3D_PointDistSqToLine2D(z, x, v1[2], v1[0], v2[2], v2[0])
  94.         if ret and distToEdgeSq < chkDistSq:
  95.             return True
  96.         ret, distToEdgeSq = Math3D_PointDistSqToLine2D(z, x, v2[2], v2[0], v0[2], v0[0])
  97.         if ret and distToEdgeSq < chkDistSq:
  98.             return True
  99.     return False
  100.  
  101. def Math3D_TriChkPointParaYIntersectInsideTri(v0, v1, v2, nx, ny, nz, originDist, z, x, chkDist):
  102.     if IS_ZERO(ny):
  103.         return False, None
  104.     if Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, 0.0, chkDist, ny):
  105.         yIntersect = (((-nx * x) - (nz * z)) - originDist) / ny
  106.         return True, yIntersect
  107.     return False, None
  108.  
  109. def CollisionPoly_CheckYIntersect(polyVertA, polyVertB, polyVertC, polyNormX, polyNormY, polyNormZ, polyDist, x, z, chkDist):
  110.     return Math3D_TriChkPointParaYIntersectInsideTri(polyVertA, polyVertB, polyVertC, polyNormX, polyNormY, polyNormZ, polyDist, z, x, chkDist)
  111.  
  112. framecount = 0
  113. while True:
  114.     await event.frameadvance()
  115.     framecount = (framecount+1)%2
  116.     if framecount == 0:
  117.         memory.write_u16(0x80CE4340, 1)
  118.     else:
  119.         memory.write_u16(0x80CE4340, 0)
  120.     for i,polyAddr in enumerate([0x80F0CE28-0x25800,0x80F0CE28]):
  121.         polySurfaceTypeId = memory.read_u16(polyAddr)
  122.         vertIdAHex = memory.read_u16(polyAddr+2)
  123.         vertIdBHex = memory.read_u16(polyAddr+4)
  124.         vertIdC = memory.read_u16(polyAddr+6)
  125.         normXHex = memory.read_s16(polyAddr+8)
  126.         normYHex = memory.read_s16(polyAddr+10)
  127.         normZHex = memory.read_s16(polyAddr+12)
  128.         dist = memory.read_s16(polyAddr+14)
  129.        
  130.         good = True
  131.         surfaceExitIndex = memory.read_u8(colCtx_colHeader_surfaceTypeList + 8*polySurfaceTypeId + 2) & 0x1F
  132.         if surfaceExitIndex == 0 or memory.read_u16(exitList + 2*(surfaceExitIndex-1)) != 0x1E00:
  133.             good = False
  134.         ignoreEntity = vertIdAHex & 0x4000
  135.         if ignoreEntity:
  136.             good = False
  137.         vertAX = memory.read_s16(colCtx_colHeader_vtxList + 6*(vertIdAHex&0x1FFF) + 0)
  138.         vertAY = memory.read_s16(colCtx_colHeader_vtxList + 6*(vertIdAHex&0x1FFF) + 2)
  139.         vertAZ = memory.read_s16(colCtx_colHeader_vtxList + 6*(vertIdAHex&0x1FFF) + 4)
  140.         vertBX = memory.read_s16(colCtx_colHeader_vtxList + 6*(vertIdBHex&0x1FFF) + 0)
  141.         vertBY = memory.read_s16(colCtx_colHeader_vtxList + 6*(vertIdBHex&0x1FFF) + 2)
  142.         vertBZ = memory.read_s16(colCtx_colHeader_vtxList + 6*(vertIdBHex&0x1FFF) + 4)
  143.         vertCX = memory.read_s16(colCtx_colHeader_vtxList + 6*vertIdC + 0)
  144.         vertCY = memory.read_s16(colCtx_colHeader_vtxList + 6*vertIdC + 2)
  145.         vertCZ = memory.read_s16(colCtx_colHeader_vtxList + 6*vertIdC + 4)
  146.         if vertAY > 25 and vertBY > 25 and vertCY > 25:
  147.             good = False
  148.         normX = normXHex / 0x7FFF
  149.         normY = normYHex / 0x7FFF
  150.         normZ = normZHex / 0x7FFF
  151.         if -0.008 < normY < 0.008:
  152.             good = False
  153.         ret, ypos = CollisionPoly_CheckYIntersect([vertAX,vertAY,vertAZ],[vertBX,vertBY,vertBZ],[vertCX,vertCY,vertCZ],normX,normY,normZ,dist,494,-1214,1.0)
  154.         if not ret:
  155.             good = False
  156.             ypos = 9999
  157.         if ypos > 25 or ypos < -32000:
  158.             good = False
  159.        
  160.         polystr = "%04X %04X(%d,%d,%d) %04X(%d,%d,%d) %04X(%d,%d,%d) %04X %04X %04X %04X - %d"%(polySurfaceTypeId,vertIdAHex,vertAX,vertAY,vertAZ,vertIdBHex,vertBX,vertBY,vertBZ,vertIdC,vertCX,vertCY,vertCZ,normXHex,normYHex,normZHex,dist,ypos)
  161.         if good:
  162.             gui.draw_text((10, 100+10*i), 0xFF00FF00, polystr)
  163.             print("%08X %08X %08X %04X - %s"%(memory.read_u32(0x80CF7D14), memory.read_u32(0x80CF7D18), memory.read_u32(0x80CF7D1C), memory.read_u16(0x80CF7DA6), polystr))
  164.         else:
  165.             gui.draw_text((10, 100+10*i), 0xFFFF0000, polystr)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement