[video output=day642 member=cmuratori stream_platform=twitch stream_username=handmade_hero  project=code title="Debugging Voxel Collision Bounds" vod_platform=youtube id=qDFhSyS6kes annotator=Miblo]
[0:00][Recap and set the stage for the day][:speech]
[1:03][Demo our incomplete :collision detector][:run]
[3:29][Reacquaint ourselves with the :collision detector in MoveEntity()][:research]
[5:19][Thoughts on allowing for buggy gameplay code][:collision :speech]
[9:03][Reacquaint ourselves with the :collision detector in MoveEntity() (cont.)][:research]
[11:44][A* and Dijkstra's algorithm][:pathfinding :speech]
[16:49][@thesandvichmaker][@handmade_hero Dijkstra?]
[17:02][@fda0][Dijkstra's algorithm seems like a bad name when the guy created, like, 50 algorithms]
[18:48][Reacquaint ourselves with the :collision detector in MoveEntity() (cont.)][:research]
[20:19][TODO([@cmuratori casey]): We should probably store corners and only test when they are untested][:collision :optimisation]
[22:12][Reacquaint ourselves with the :collision detector in MoveEntity() (cont.)][:research]
[23:03][@dedknd][Photolithography machines manufacturer ASML is also Dutch, supplying TSMC and Samsung]
[23:07][@thesandvichmaker][If you tell me your name and date of birth my brain will actually process what you sound like]
[23:30][@thesandvichmaker][Dutch national pride]
[26:35][TODO([@cmuratori casey]): We need to think through the way we handle embedding…][:collision]
[27:37][Reacquaint ourselves with the :collision detector in MoveEntity() (cont.)][:research]
[29:01][Investigate why the glove did not move][:collision :research]
[30:05][The glove's :collision search doesn't go beyond the "home" voxel][:collision :run]
[31:22][Make MoveEntity() diagram the full voxel span][:collision :"debug visualisation"]
[33:13][The glove's :collision search doesn't touch the full voxel span][:collision :run]
[34:06][Make MoveEntity() diagram the line from FromP to ToP][:collision :"debug visualisation"]
[34:23][The glove's full voxel span does not encompass the whole line from FromP to ToP][:collision :run]
[35:10][Make MoveEntity() colour in grey the line from FromP to ToP][:collision :"debug visualisation"]
[35:16][Clean out old code from MoveEntity() and correctly set the VoxelEndingCorner][:collision]
[39:25][The glove's full voxel span correctly encompasses the whole line from FromP to ToP][:collision :run]
[39:58][Start to investigate why the flood search doesn't work][:collision :research]
[40:48][Make MoveEntity() diagram the tested voxel][:collision :"debug visualisation"]
[41:52][The glove's :collision search tests one cell][:run]
[42:04][Investigate why MoveEntity() never calls PushVoxelStack() in the "Flip" loop][:collision :research]
[44:00][Step in to MoveEntity()][:collision :run]
[44:34][Flip the Occupied tests in MoveEntity()][:collision]
[45:20][Step in to MoveEntity() to find that it now calls PushVoxelStack()][:collision :run]
[45:33][Our glove's :collision flood search now permits :movement][:run]
[45:48][Our :collision erroneously permits embedding and corner roll-off doesn't happen][:run]
[47:09][Increase the :collision search space by one voxel in MoveEntity()]
[47:50][Our corner roll-off now works][:collision :run]
[48:00][We must fix embedding and :performance][:collision :run]
[48:29][Plan to fix embedding][:collision :research]
[49:48][Plan to fix embedding: 1) Track tested voxel corners][:collision :research]
[49:58][Plan to fix embedding: 2) Track embedding, to prevent movement to an embedded cell][:collision :research]
[51:00][Disable the embedding recovery code in MoveEntity()][:collision]
[51:17][Our :collision still permits embedding][:run]
[51:25][Scrutinise MoveEntity() for code that permits embedding][:collision :research]
[53:38][Make MoveEntity() test for embedding before considering a cell][:collision]
[54:29][Our :collision still permits embedding][:run]
[55:09][Scrutinise MoveEntity() for code that permits embedding][:collision :research]
[55:39][Fix the embedding test loop in MoveEntity() to use Cell.Min][:collision]
[56:11][Our :collision now prevents embedding][:run]
[56:39][Our glove gets stuck on a corner][:collision :run]
[57:31][Relieve MoveEntity() of testing for embedding before considering a cell][:collision]
[57:47][Our :collision continues to prevent embedding, but we can get stuck in the doorway][:run]
[59:31][Optimising the :collision routine][:optimisation :research]
[1:00:37][Let MoveEntity() early-out of the :collision voxel pushing loop if BestDistanceSq == 0][:collision :optimisation]
[1:01:15][Our glove can get embedded in the hero][:collision :optimisation :run]
[1:01:42][Our :collision flood search tests all voxels in a clear straight line][:optimisation :run]
[1:03:20][Determine to push :collision voxels closest-first][:optimisation :research]
[1:04:31][Determine to improve our early-out condition in MoveEntity()][:collision :optimisation :research]
[1:05:32][Change MoveEntity() to early-out if the BestCellI and TargetCellI match, introducing ClampToVoxelDim()][:collision :optimisation]
[1:08:37][Our :collision is more efficient][:optimisation :run]
[1:09:12][Rephrase the :collision voxel expansion in MoveEntity()]
[1:10:00][The glove can penetrate right through the wall][:collision :run]
[1:10:34][Scan MoveEntity() for code that permits through-embedding][:collision :research]
[1:11:00][The glove can penetrate right through the wall when turning][:collision :run]
[1:11:40][Scrutinise MoveEntity() for code that permits embedding][:collision :research]
[1:12:33][Try to single-step the :collision detector][:run]
[1:14:53][Walk into the wall, getting the glove embedded][:collision :run]
[1:15:43][Introduce Round() for MoveEntity() to use when setting VoxelStartingCorner and VoxelEndingCorner[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:collision :mathematics]
[1:20:20][Our glove's and the expanded :collision search voxels are not aligned][:run]
[1:21:15][Investigate our voxel misalignment in MoveEntity()][:collision :research]
[1:22:08][Revert MoveEntity() to use Floor() when setting VoxelStartingCorner and VoxelEndingCorner][:collision]
[1:22:48][Increase the VoxelMaxCorner by 2× the CellDim][:collision]
[1:23:35][Our :performance has tanked][:collision :run]
[1:24:05][Reduce VOXEL_STACK_DIM from 16 to 8][:collision]
[1:24:26][Our :collision voxels remain misaligned][:run]
[1:25:50][Change MoveEntity() to include the starting point, factoring in a DeltaPClamp to the VoxelEndingCorner][:collision]
[1:31:44][Our :collision search bounds and embedding are improved][:run]
[1:32:56][Continue to optimise the :collision routine, augmenting voxel_stack with Repulsion and introducing voxel_corners and CheckCorners() for MoveEntity() to use][:"data structure" :optimisation]
[1:52:49][Hit an assertion on CornerI in CheckCorners()][:collision :run]
[1:53:32][Rephrase assertions in CheckCorners()][:collision]
[1:54:06][Add assertions in CheckCorners on the incoming CellI dimensions][:collision]
[1:55:18][Hit an assertion on CellI in CheckCorners()][:collision :run]
[1:55:28][Investigate our out-of-bounds :collision voxel push in MoveEntity()][:research]
[1:56:52][Respecify MaxVoxelDim as MaxDeltaDim in MoveEntity()][:collision]
[1:57:33][Hit an assertion on CellI in CheckCorners()][:collision :run]
[1:57:43][Continue to investigate our out-of-bounds :collision voxel push in MoveEntity()][:research]
[1:58:18][Change MoveEntity() to use FloorToV3S() when setting VoxelDim][:collision]
[1:58:34][Hit an assertion on CellI in CheckCorners()][:collision :run]
[1:58:49][Add assertions on the VoxelDim in MoveEntity()][:collision]
[1:59:24][Hit an assertion on VoxelDim in MoveEntity()][:collision :run]
[1:59:44][:Run in -Od, hit an assertion on VoxelDim in MoveEntity() and inspect the values][:collision]
[2:01:53][Fix our assertions on the VoxelDim in MoveEntity()][:collision]
[2:02:08][Hit an assertion on VoxelDim in MoveEntity() and inspect the values][:collision :run]
[2:03:27][Decrease the MaxDeltaDim by 3 per axis in MoveEntity()][:collision]
[2:03:39][No longer hit that assertion on VoxelDim in MoveEntity()][:collision :run]
[2:04:02][:Run in -O2, and no longer hit that assertion on VoxelDim in MoveEntity()][:collision]
[2:04:34][Corner roll-off now works, we no longer embed, but we can still get stuck on corners][:collision :run]
[2:07:04][TODO([@cmuratori casey]): Do initial check to see if we're embedded...][:collision]
[2:07:52][Q&A][:speech]
[2:09:24][@insobot][Q: Polling raw input make it reasonable to give it a coincidence that we do not worry about the nail salon?][:"input handling"]
[2:10:28][@thesandvichmaker][@handmade_hero, @insobot has cheered me up, but I've been real down on programming lately. Have you ever had a phase where you were just totally over computers?]
[2:16:24][@mindmark42][Q: Do you think it is safe to assume if a CPU has AVX2 it has FMA, or should I always check the cpuflags? I'm not sure where to look if such a thing is true[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:isa]
[2:21:19][@mindmark42][Ya, I was wondering if all AVX2 CPUs on the market have the FMA extensions because all two of mine have them[ref
    site=uops.info
    url=https://uops.info/table.html][ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:isa]
[2:29:22][We're done][:speech]
[/video]
