[video 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]