[video output=day376 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Drawing Debug Volumes" vod_platform=youtube id=L68VR5VuwnI annotator=Miblo]
[0:02][Recap and set the stage for the day]
[3:06][Consider approaching alpha fade and upgrading our understanding of the camera]
[5:48][Run the game to assess our current situation]
[8:44][Determine to fix the camera code]
[9:41][handmade_world_mode.cpp and handmade_render_group.cpp: Make PlayWorld() generate fewer rooms and SetCameraTransform() disable the fog in debug mode]
[12:39][Run the game to see that the fog is disabled, and consider how to define the extents of a room]
[16:10][Determine to extend the debug rectangles into the third dimension as per @Miblo's request]
[17:39][Blackboard: Drawing rectangles on sheets]
[18:29][handmade_render_group.cpp: Introduce PushVolumeOutline() based on PushCube()]
[22:06][Blackboard: Cube edges, faces and vertices]
[23:09][handmade_render_group.cpp: Enable PushVolumeOutline() to set the cube vertices]
[25:16][Blackboard: Defining cube vertices and edges]
[28:14][handmade_render_group.cpp: Enable PushVolumeOutline() to call PushLineSegment() for each edge]
[31:18][Blackboard: Cube edges]
[36:03][handmade_render_group.cpp: Introduce PushLineSegment()]
[41:36][Blackboard: Computing thickness for our line segment, an end user-facing approach being to use a distance field in a shader, but using the cross product in a debug scenario]
[45:03][Blackboard: Differential Geometry (gradient, divergence and curl) and Geometric Algebra (dot and cross product)]
[51:00][Blackboard: Inner / dot product]
[53:04][Blackboard: Cross product]
[1:00:07][Blackboard: Solving for the cross product vectors that go in the same direction]
[1:06:15][Hunt for a computer algebra system to solve our equation]
[1:13:31][Consult the documentation for YACAS[ref
    site="YACAS"
    page="Solvers"
    url="http://yacas.readthedocs.io/en/latest/reference_manual/solvers.html"]]
[1:15:20][Try to plug our equations into YACAS]
[1:17:00][Blackboard: Computing the angle between two vectors]
[1:19:41][Try to prescribe the angle between the vectors]
[1:20:35][View the supposed solution to our equations]
[1:22:22][Continue the hunt for a computer algebra system]
[1:25:12][Consult the documentation for Maxima]
[1:27:36][Try to plug our equations into Maxima]
[1:29:18][View the non-solution]
[1:30:09][Prescribe that the sine must be 1 and view this solution]
[1:30:36][Reflect on our foray into computer algebra systems]
[1:32:50][Cross product[ref
    site="Wikipedia"
    page="Cross product"
    url="https://en.wikipedia.org/wiki/Cross_product"]]
[1:35:43][handmade_math.h: Introduce Cross()]
[1:39:17][Blackboard: How the cross product helps us to produce thickness]
[1:41:31][handmade_render_group.cpp: Enable PushLineSegment() to compute the normalised perpendicular using Cross() and NOZ()]
[1:44:58][handmade_render_group.cpp: Enable PushVolumeOutline() to pass the C and Thickness to PushLineSegment()]
[1:46:55][handmade_world_mode.cpp: Enable PlayWorld() to call PushVolumeOutline()]
[1:47:55][Run the game to see our 3D debug cube]
[1:48:47][handmade_render_group.cpp: Sanity check PushLineSegment()]
[1:49:39][Blackboard: Pre-projecting down to the screen]
[1:50:57][handmade_render_group.cpp: Temporarily make PushLineSegment() keep the Line in line with the camera's Z axis]
[1:51:39][Run the game to see that debug cube]
[1:52:06][handmade_math.h: Sanity check Cross() and consider what is happening]
[1:53:49][handmade_render_group.cpp: Temporarily make PushVolumeOutline() only draw one segment, and run the game to see how that looks]
[1:56:33][handmade_world_mode.cpp: Reduce the thickness and run the game to see the problem when the line is head-on]
[1:57:34][handmade_render_group.cpp: Enable PushLineSegment() to compensate for the LinePerpLength]
[1:59:31][Blackboard: On losing our length as the angle between the edges reduces to 0]
[2:00:21][handmade_render_group.cpp: Continue to enable PushLineSegment() to compensate for the LinePerpLength]
[2:02:24][Run the game to see our current problematic behaviour]
[2:03:43][Blackboard: Computing the perpendicular to the CameraZ]
[2:05:09][Q&A][:speech]
[2:06:24][@insofaras][hmd_bot handles the Q&A message and seems to be dead]
[2:06:54][@desuused][Here's your equations solved in Maxima \[image\], and here's your equations solved with expanding (sinθ)^2 through dot product: \[image\]. I think this approach is completely wrong when trying to derive cross product]
[2:07:50][@ingenero][What would be the downside of drawing your debug lines as 3D cylinders or extruded rectangles? It seems like that would look a little nice when viewed from all angles]
[2:10:18][@vaualbus][Also shall we draw the cubes around the room?]
[2:10:47][handmade_entity.cpp: Make UpdateAndRenderEntities() draw collision volumes]
[2:12:06][Run the game to see what that does]
[2:12:37][handmade_render_group.cpp: Make PushVolumeOutline() take the ObjectTransform into account]
[2:13:32][Run the game to see the collision volumes]
[2:15:10][handmade_render_group.cpp: Enable SetCameraTransform() to set the DebugXForm in both modes, and run the game to see the collision volumes in the game mode]
[2:16:44][@desuused][You mentioned that you use discriminated unions. Have you seen Rust's implementation of sum types?]
[2:16:59][@jezzi23][I was looking at how the vector types are set up in Handmade Hero as unions. As far as I know, it's undefined behaviour to write value to one type of a union and then read as another type. Is doing something like this well defined - vec1.x = 5.0f and then read as vec1.E\[0\] - or is it one of the cases where we rely that a reasonable compiler will do the right thing?]
[2:20:39][@desuused][Would you describe discriminated union to the general public?]
[2:20:50][Blackboard: Struct, as a representations of data in memory]
[2:24:12][Blackboard: Union, as a combination of structs]
[2:26:21][Blackboard: Discriminated union, as a union containing a type field]
[2:30:03][Blackboard: Inheritance in C++]
[2:32:32][@graham1642][Can you give a motivating example for these discriminating unions?]
[2:33:11][Blackboard: A "single dispatch" example in which a discriminated union and inheritance work equally well]
[2:38:54][Blackboard: The tractability of Single vs Double Dispatch]
[2:40:00][Blackboard: A "double dispatch" example in which a discriminated union excels]
[2:46:06][Blackboard: Generating a sparse matrix containing the cases you care about]
[2:49:34][Blackboard: Discriminated unions shine in enabling the ability to write code which looks at the way in which types are set among more than one object]
[2:53:44][@cubercaleb][How would you feel if you wrote the functions for colliding each pair or types, and allowed the compiler to generate the sparse matrix of function calls for you?]
[2:55:09][Recommend researching category theory, with a call for @Pseudonym73]
[3:00:12][@cynokron][Are you hoping JAI will have discriminated unions?]
[3:00:32][Wind down here][:speech]
[/video]
