As some of you have pointed out, I made a few minor mistakes while talking about the math. I want to summarize them in this comment. First, at 26:06 I inserted the rewritten vector triple product into the integral without putting parenthesis around the expression. So in every following expression, it looks like rho(r) is only multiplied with the right addend, when it actually must be multiplied with both of them. However, if you imagine that there are brackets around the sum expression or think about rho(r)dV as being the differential mass element of r, which is what I did and how this mistake even occurred, then everything is still correct. 26:06 TL;DR: brackets missing visually, maths still handled correctly (as if they were there) Secondly, at 26:15 I moved some parenthesis and said that this was possible because matrix multiplication is commutative. I meant to say associative of course. Matrix multiplication is not commutative in general. 26:15 TL;DR: is used a wrong word Thanks to @bartoszstyperek6306 and @jaborl mentioning these and sorry for any possible confusion. If you find further errors, I would appreciate them being pointed out as a reply to this comment, so they are easier to find. UPDATE 2024-06-30 As @notu483 pointed out, the explanation prior to the conversion step done at 7:41 is a bit vague. If you want to do this more formally and correctly, I suggest to use a function w(x, t) to have a better distinction between the resulting time dependent world position w and the local position x that is being integrated. Then you can use Leibniz integral rule (specifically the one for higher dimensions aka Reynolds transport theorem) to do this conversion. Thanks for mentioning. 7:41 TL;DR: only important if you're interested in the specific mathematic details
@@matthiasmax2849 Hey, I feel what you're saying. Unfortunately, I'm not really sure what to recommend. I didn't read one specific thing that taught me all of this, rather I picked up some things here and there. Are you studying computer science? That would definitely be a good starting point. I feel like what helped me was working through exercises and writing down derivations step by step, even if it felt kind of pointless. And I would still recommend to attend the available simulation lectures, regardless of whether you have all the necessary prior knowledge. If that is possible. I picked up most of the math I present in these videos because of the animation and simulation lectures. I felt damn hopeless in the beginning, but because I was so interested in this topic I learned much by googling the little things or watching a few niche RUclips videos. Also, don't be afraid to ask your professors stuff. By the way, I also have a discord server now if you're interested, the link is in the comments of my second livestream. We could discuss this further over there. Man, do I sound that german 🙈I hope my english is still okay to listen to haha
@@PerriPaprikash in some way true but unfortunately that kills the momentum of the video. and I would lie if I said that I don't care how many people I reach with these videos. after all I make them so people watch them. so that's a bit of a dilemma. additionally the comments would be lost
I want to understand this video, yet my calculus knowledge is limited to a highschool-level course. Please remind me in 2-3 years to come back and rewatch this video so I can actually understand all the math
you don't need calculus yet,you must be good at linear algebra and geometry.Programming is not easy as mathematical imagination,one logic goes wrong and the rest of the system will be ruined.
It's always interesting seeing these types of videos, which are always rare to come across without obnoxious over-the-top narrating, I'm glad I subscribed :)
I’ve been working on my own physics simulation engine as an opportunity to brush up on my understanding of physics as well as practice coding some more interesting projects. This video is phenomenal! The intuition presented here is so much easier to make sense of than everything else I’ve seen for handling 3D angular momentum. Part of the simulation that I’m interested in is handling a dynamic model that does not stay as a rigid body, but if I’ve internalized this intuition correctly, I should be able to use conservation of angular momentum combined with time dependent inertial tensor calculations to accurately model rotations in my simulation.
That's great, thank you so much. I am not exactly sure if this is applicable in your case, I mean the total angular momentum of the dynamic model must stay constant, but that is not true for any part of it, since they might exchange energy.
I’m a mechanical engineering student and I didn’t really understand the whole inverting/ shifting axis of rotation thing until I watched this, excellent work!
I really love the quality of the video. The explanation is also really good. These types of tutorials give me motivation to challenge myself with programming projects I've never tried before. I hope you continue making videos!
This is over my head but I’m trying to learn it. Your videos are gold for helping me make that leap. Thank you! I am very much looking forward to the next one. Please don’t stop! Your efforts are greatly appreciated!
Thanks, glad to hear that :) I would recommend working through some exercises to get more comfortable with these concepts. Or even just writing down the derivations and trying to understand each step.
What an incredible presentation. Taught in such a way I alllllmost feel like I could've gotten there myself. Such is the mark of all excellent explanations as well as the excellent teachers behind them. Excellent job and thank you for this gem!
Thanks man, finally a video that not just scratches the topic of rigid bodies. After reading through a paper, watching this video makes me understand what I have read better. Thanks!
Very nice, i can see how statics, dynamics, and some coding/matrix knowledge is used. And the first half of a transcendental calculus textbook should be sufficient for anybody looking to learn.
Very nice video on such an interesting topic. You've actually explained the spin instead of the angular momentum since you were using r and not x. In your notation it would be the angular momentum L = x x p and the spin N = r x p (with integrals). The problem you've faced with the referential density also holds for the integration limits. They would be also dependant on the actual rotation when you are using the inertial basis as coordinate representation. I made the observation, that many people get problems with rotations and transfomration matrices. The vectors r, r-~ and r-v all refere to the same vector in space, namely the vector from CM to the particle, but only represented in other coordinate systems. There isn't something rotated, it's just an projection to other basis vectors. You could try to store the Omega and N in body fixed coordinates, how it is often done in mechanical simulations. I guess that could save some matrix multiplications. Thanks for the video, I like to see you making progress. I liked the explanation to get the angular velocity with the rescaling, made it more intuitive what's inside the inertia tensor.
Thank you :) Definitely interesting, I didn't know there was a differentiation between the spin angular momentum and the orbital angular momentum. But I don't think it's necessarily wrong to still call it angular momentum, just a matter of which origin point is used. How would the density be dependent on the rotation in an inertia basis? I am not sure I understand. Also, while r, r-~and r-v refer to the same vectors in local coordinates, I am not sure this is the case for global coordinates. Maybe you have another intuition than I have? I thought about storing the angular momentum in local coordinates, this might be a good idea. Though I am not exactly sure because then you might have to rotate the torque vector. What would be the benefit of storing omega in local coordinates? I really appreciate your remarks, thanks
@@blackedoutk Thanks for your reply. I wasn't conscious of these english expressions for spin angular momentum and orbital momentum. For kinematics, you have to use the same reference point for induced torques, which is anyway convinient to take the center of mass for that. Something that really improved my unterstanding of physics and especially mechanics, was to think of vectors as arrows in the space instead of putting three number on top of each other. Mechanics works as well with these arrows, but we need number to describe these arrows. For that we can use a inertial fixed basis or any other, like body fixed. Then, r, r-tilde and r-v describe the same arrow in space, but with other numbers. After rewatching your the sequence I think I got it better. Your density function (rho) takes the vector in global coordinates and rho-tilde takes it in body fixed coordinates, which would be the only possibility to give a proper definition of the function. Lastly, I have never thought about integrating the angular momentum instead of the angular velocity. This could simplify many things and removes some exhausting derivatives and materix multiplications. I think expressing the torque vector in local coordinates could be already cheaper. Force elements are mostly mounted body fixed, so for rotaional springs/dampers, their force contributions are already in local coordinates. For induced torques by a globally given force, you either have to take force into local coordaintes or calculate r in global coordinates. Would be interesting to see some benchmark experiments with both approaches and whether you face any other problems like in time integration. Anyways, I am curious see the progress you're making :)
@@niklaswagner6191 Such benchmarks would definitely be interesting. Though later I will probably stick to storing and integrating the angular velocity anyway, because that's how the XPBD paper does it. Your understanding of the density functions is how I imagined it, so the definition would then be rho(R, r) = rho-tilde(R^T*r). I try to think of vectors as arrows in space too. And even matrices as multiple arrows if applicable. I believe understanding these concepts is much easier with a visual intuition and find it quite unsatisfying when people introduce some theory (for example the inertia tensor) without providing an intuition for it. In my opinion, there should be some amount of focus on teaching that as well
Amazing video. Really well done and I loved how you approached the topic. It was also really funny at times! I was laughing when the tension over baiting an explanation on quaternions over matrices scene happened, and I was genuinely lol'ing when the terminal started showing random strings of characters as the guy in the clip smashed the keyboard. If there's any criticism I can make is that you sound a bit monotone. Many of the jokes would have been 10x better with some small comedic performance. Dude, you are funny and great! I know you can do a version with slightly more energy even if just for the joke parts. Please keep this content up! Subscribed.
love your comment, made me happy thank you :)) I agree with the monotone bit but it's hard for me to change that. sometimes I think I already bore people when I'm just telling them stories but it's the worst when I'm reading out loud 💀 plus this is english and I have to calm myself because somehow I get stressed when recording the script and then I sound like in the first or second epsiode. I'll see if I can do something, though doubt it. but definitely a fair point, appreciate it
@@弘睿甫 no worries I am the same. part of why I am so slow to answer is because I overthink what to say. sometimes I respond faster and cringe a month later lol. I thought your comment was funny
Ah interesting. Sometimes I just use non technical terms to make the stuff I say more relatable or easier to understand. Though admittedly I didn't know it was called newton's notation
So far I've found Verlet to be better than Euler. It's more stable. I've been building a cloth simulation, and with Euler it explodes way too often. Verlet doesn't use an explicit velocity, it calculates it from the previous position: vel = pos - prev prev = pos pos += vel + acc * dt * dt
They are template structs for vectors (tvn) and matrices (tmn) where the parameter T is the scalar type and U is the number of elements per row or column. The data is stored in an array named E, hence why in code you always see .E[] instead of x, y and z for example. To make these easier to use I then typedefed them like this: typedef tvn v3; and with a prefix d for 64 bit floats.
@@blackedoutk I wrote a game engine for a uni project and the physics transforms really tripped me up. But this video and the follow up one on inertia made everything so much clearer. Do you have another dev log planned soon for fixing the determinant bug and other juicy stuff?
@@MrBomberman11 Planned yes, but without date. So next video would be intertia tensor decomposition and then the next I wanted to fix the determinant using quaternions
@@blackedoutk I have a pet project in C from scratch, where I learn things. Based on handmade hero, but with my own twist. I have an idea for a game that is reachable for my abilities, I think, but it's still a huge amount of work, and it's really hard to combine with a full time job.
@@slavicradko9846 oh cool, I also watched handmade hero, but only the first 200 episodes or so. it's really great. did you watch the whole thing? I can imagine the difficulty when having a full time job. I don't have one but still struggle with time management :/
@@blackedoutk no, I did not, I watched around 100 and then selectively some of the later. It was enough to get me a well paid job though, so I greatly appreciate Casey for his efforts 🙏
I have a problem at 09:44. As a theoretical physics graduate student I'm used to C and Python so I understand the idea behind your struct, but what kind of libraries are you using? I've never seen "dv3" as a datatype to define 3D vectors as well as the datatype "mesh''. Can you provide some info? Beautiful video by the way!
Thank you, glad you like the visuals! The data structures you're seeing are part of the game and not from a library. I talk a little bit about the general vector type in my first episode, but really they are just structs that hold the coordinate data in an array. Then I wrote all of the functions needed to work with them, like operators, dot products and so on. The mesh struct I don't think I have mentioned in detail in any episode. It holds all of the data for a model, like vertex positions, normals, tex coords, colors, face indices and textures, and the handles that are needed for the OpenGL rendering, meaning vertex array object, vertex buffer object and texture handles. It also contains some less relevant stuff like the models name or edge information which lets me draw a wireframe model without using wireframe mode. Lastly it contains the original center of mass and decomposed intertia tensor of the model as it was exported from blender for example. Though this I plan on explaining in the next episode. I updated the description with the libraries the game uses in its state of the video. Let me know in case you have further questions about this
I am loving all of the explanations! Can you share the source code of the animations in the video? How do you do the voiceovers? Will you share your right body simulator code as well?
that's great, thank you. sharing the 3d animations is difficult because they are part of the game, so for anyone to understand the code I would have to share parts of the game code aswell. the manim animations I could share but I'm not sure I want to, what would you want to do with them? for the voice overs I just record me reading the script and then fiddle the stuff together in DaVinci Resolve. I will share the rigid body code eventually in the library I talk about in the episode 6, but the game code for now I don't want to share. my goal is to explain the important parts, so that viewers can implement it themselves or at least know where to look for
tl;dw Let me try to make it shorter. Body has linear and angular momentum. Divide linear momentum by mass to get linear velocity. Transform angular momentum into local frame of reference, divide each component by one of 3 angular masses, and transform it back into global reference frame to get angular velocity (which doesn't always ends up aligned with angular momentum, creating interesting dynamics). Or compose it all in it's entirety into a single momentum->velocity transformation, if you so desire, which ends up as a symmetric matrix - matrix that resizes space relatively to some orthonormal basis. Now move your position by vel*time and rotate your rotation by angVel*time. The tricky part here is actually calculating next rotation, since it is represented *either* with geometric algebra rotors and bivectors, or using matrices. (And no, euler angles don't count, they are just funny useless parametrization, that can't do anything on it's own) Anyway, long story short(er): Angular velocity (or momentum) is a bivector - a quantity, where each component is associated with 2 coordinates. Kinda non-diagonal elements in a matrix. But here, instead of linear mapping, they represent oriented quantity from one axis to another one - for example "+5xy" shows rotation around "z" axis. Easiest way to turn them into actual rotation is by viewing them through the lense of VGA. In it, vector is used to represent reflection around a plane, and so a composition of two of them gives us a rotative transformation twice that of angle between them. This is called a rotor (in 2d only it's a complex number, in 3d it's quaternion). Composition rules are pretty simple (read left to right): "x*x = 1", "x*y = xy". So "(1x + 0y) * (0x + 1y) = 1xy". "1xy" in this case is just a bivector, since vectors were orthogonal to each other, and it represents a +180 degree rotation. But reflections generally don't commute, so composing them backwards will give us opposite rotation "y*x = -1xy", which is -180 degree rotation around z (in 3d). Now, these bivectors can be composition-exponentiated, which gives us a rotor (in 2d and 3d you can implement exponentiation using very simple trig, and for other dimensions there is a more general formula). In other words, we just turned rotation direction into a rotation. Compose it with our original rotation, and you're good to go. In any amount of dimensions, at that. Have fun rotating hypercubes! Now, in order to render vertices and whatnot, just transform your vector represented as a reflection-operation into a global frame. How? The same exact way we did with local angular mass (which is just an operation converting local momentum into local velocity) and rotation. "[madeupArgument]*reverse(rotation)*reflection*rotation" "[madeupArgument]*reflectionOutsideRotation". Anyway, I'll go into more detail and fill in the gaps, if anyone ever reads this and wants to know more. Could as well touch on PGA rigidbody dynamics too, since they are quite elegant and interesting, although their math is a bit too big-brained and not as general purpose, as concepts I discussed.
I think covering this in depth needs a bit of time, hence the length of the video. And while I appreciate you trying to explain rotors and bivectors, I don't understand this purely in a short comment. Why don't you make a video about it?
@@blackedoutk Uhhh.. Yeah, making videos is not mine kind of thing. I'd probably just write an article series in couple years, after my current projects are over
@@blackedoutk Just check out materials created by bivector community, to fill in the gaps. My goal was just to give a rough intuition, which those materials on their own do not fully provide. They are more focused on algebraic aspect, and working with transformations as if they're objects (by talking about transformation's invarient subspaces).
@@Waffle4569 Ah I see. But I think that's more of a problem with the build tools rather than the language itself. Maybe it's because I have never worked on big enterprise software, but I really don't understand the need for all of the complexity in build tools. For small to medium sized projects, using shell scripts is definitely superior imo. Also because you say "even you", I don't think I am a good reference for comparison when it comes to building projects, I'm horrible at that. I tried rust recently because I have to use it for a project and I get really angry about the borrow checker all the time lol, but I know that's probably a skill issue
@@blackedoutk I think it stems from the simplicity of the old days when compiling was just calling an exe with arguments, but its horrendously overgrown now. The build system was never intended for more than one person's personal computer, absurd amounts of build config are defined by command line variables and dependency directories that might not be present. Not to mention there is no real compiler standardization, so even the compiler becomes a dependency that might not be listed. Pretty much every language after C++ realized they need to define how the build system and dependencies should work. Rust has a very steep learning curve, but ironically it has the easiest dependency/build system I have ever used.
14:30 Why not just use trapeziums to calculate the approx. area? You can calculate the next v 1 iteration before, store it, calculate the correct trapezium area, and then the next iteration you already have the current v.
Yes that would be better, however keep in mind that you need the right end value to do that, which means it's an implicit method and thus way harder than explicit. It's a bit difficult to see with the linear velocity example because the velocity does not depend on the position, so you can just compute it here. But try to write down the same thing for the angular velocity. This one depends on the current orientation. So to get the exact right end value you need the angular velocity there. However this velocity depends on the orientation at that point in time. It's a cyclic dependency. Does that make sense? There are explicit methods that do kind of what you suggested for simple functions, like the midpoint method which is second order explicit. But of course the formula looks more complicated so I wanted to stick with something simple here.
thanks. currently more interested in rigid and soft body physics. but I'm not opposed to other simulation topics, just already so many things to learn. do you know more about these other topics? or do you wish to watch videos about them?:D
@@blackedoutk Yes I know more about these topics and I wish to watch videos about them too. There are channels that do something similar but I thought why not ask you about your interest to understand you area of expertise.
What a coincidence! I've also been working on implementing some rigidbody physics. I am currently trying to implement angular motion with a constant angular velocity, just for simplicity. I have a question: I have tried updating the rotation matrix as you did in the video: Cuboid->R += DeltaTime*Cross(Omega)*R (with a constant omega vector) However, when I do that, my rotation matrix is no longer a rotation matrix after a few thousand simulation steps (The determinant explodes into values like 200). I'm using a DeltaTime of 0.01, but I have the same problem with a DeltaTime of 0.001. Am I missing something? Do you normalize at some point? Thanks for the video btw
Cool! The problem you are facing is completely normal, I talk very briefly about this at the end of the video. But to add to that, you can even make intuitive sense of it. What you are trying to do by adding Cross(Omega)*R to R itself is move the axes of R along their respective circular paths. As explained in the video, Cross(Omega)*R contains the velocities of each axis vector of R, which are tangent to the circles. Regardless of how small your step is, if you move some epsilon > 0 along the tangent line of a circle, you will always leave the circle. Resulting in a larger radius than previously. The axes increase in length. You can fix this by reorthogonalizing R after each simulation step if you wanted to continue to work with a rotation matrix. Another, probably better fix would be to use quaternions instead. I didn't do any of that in the video, for some of the footage I just used an even smaller time step 😅
@@blackedoutk Thanks for the answer. Yeah, I figured out that it was normal but I didn't think the drift would happen so fast especially because it seemed to work well in your video 😅. I implemented a solution using quaternion too but can't seem to figure out what to do with the derivative of the quaternion after computing it. Simply adding the derivative x DeltaTime doesn't seem to give any good results...
@@Shikinoe93 Probably because the captures weren't very long. I think I used 1ms for most of it and only 0.01 ms for the "phone" and the screw thing. Adding the derivative x DeltaTime should work. Though similar to how only orthogonal matrices (with a determinant of 1) describe rotations, only quaternions of unit length describe rotations. So you might want to normalize your quaternion after adding its delta value.
@@blackedoutk I'm getting much more stable results now with quaternions. The previous implementation with rotation matrices would explode depending on the DeltaTime. Still not getting to the precision I need though, I don't know what more I could do to improve the accuracy of the simulation. Even increasing the deltatime doesn't seem to change much...
Nice! So basically the video is a collection of images, screen recordings, manim animations for the equations and custom animations that I made in my game itself. All of these I then put into DaVinci Resolve with my voice and added some further texts, emojis and stuff. The custom animations are also screen recordings because I didn't want to spent even more time trying to export the rendered images as a video. You can see this even at 32:49 where I struggled to remove the background from the object when its duplicate slides over 😅 But they are in game renders. Was a bit of a pain at first because I had to write the internal animation framework while creating the final animations for consistent playback, mouse handling and stuff. I hope this answers your question. At first I was thinking about using blender for the custom animations but I wanted to use my physics code in them
Perhaps some parts weren’t too rigorous (such as the part where you exchange the derivative and integral operator, which is actually a specific case of the Leibniz integration rule where the region is constant), but it is very valuable nonetheless. Thank you! ❤
Interesting, I should do some more checking instead of relying on intuitions too much maybe. So the explanation for the factoring out isn't really correct, right? I looked at the Leibnitz integration rule for higher dimensions on Wikipedia (it also says Reynolds transport theorem on there) and noticed that I probably should have been more specific what the x really is because it doesn't distinguish between the x of the domain of integration and the resulting x in world coordinates. But when I do that (e.g. use w(x, t) instead of x(t)) then I think the "factoring out" step still works because the velocity of the domain's boundary is zero (since it's static) and the partial derivative equals the total derivative again because x doesn't change over time. Really appreciate your remark thank you, and I'm also happy you still think it's valuable. Now I'm curious, are you a mathematician?
hm it's hard for me to answer because there isn't one specific book I read or course I watched, rather it's small bits from everywhere. one commenter said the first half of a transcendental calculus book should be sufficient for anybody looking to learn. but I can't verify this. definitely a bit of calculus, linear algebra, numerics (ode and linear algebra) and a mix of calculus and linear algebra, so multidimensional calculus, where you learn about the jacobian matrix. maybe the "essence of" series by 3blue1brown is a good start?
I use some libraries like SDL for window and input, stb image for image loading, ImGui for debug user interface and glad for loading the OpenGL functions but other than that I wrote the code myself. Or what exactly do you mean with simulation platform?
Great video, I have a question though, didn't you mention in one of the soft body videos that you can use a constraint to essentially have the effect of rigid body?
Thanks :) I don't think this would work using a single constraint, but with multiple it might be somewhat possible, like for the "rigid" cube in episode 1. Are you referring to that? There are a few problems when using multiple constraints to make an object rigid like in previous episodes. First, the mass properties aren't exactly correct, because you are dealing with point masses instead of a contiuous body. If you didn't tetrahedralize your mesh, the mass would even only lie on the surface of the model. Secondly, it is probably inaccurate and or very expensive, depending on the complexity of the model and how many iterations you perform. In comparison, simulating the dynamics of a rigid body like in this episode is almost free and independent of the model's complexity (assuming the initial inertia tensor is given). As an example, in the previous episode, if the solver was perfect, the tire wouldn't have been soft at all, because I set its inverse stiffness to zero. But since I only performed a limited number of iterations, which were already pretty expensive, the tire appeared to be soft.
I'm having some trouble implementing this into a blender simulation with simulation nodes. I've been trying for about a month, I keep coming back to this video as it is describes a simulation with assumptions very similar to mine such as using only point masses, constant density, etc. I was wondering if I could send an annotated photo of my simulation setup to you through email. I know you're using c++ but the node I'm using in blender are quite simple so I'm sure you'd be able to understand them. If not no worries though. Either way thanks for this video it explains it very concisely!
Unfortunately I don't have much time at the moment, but you can still send it to the email that is listed in the channel details/info. In a month or so I might be able to take a look at it. Apart from that you can also join my discord server and post it on there if it's not something that you wish to be kept private. Maybe somebody over there has an idea why it's not working
i'm working on a physics engine for my game engine using projective geometric algebra so that rotation and translation can be combined into one object and torques just magically happen
I've been trying to learn some PGA, but I don't have a good intuition for it yet. I really like how it feels, but I always revert back to linear algebra when I'm doing work. Another problem for me is the code. Should I just be working with multi-vectors, or should I have separate objects for each element?
@@blackedoutk I thought I replied but it seems youtube ate my reply. Freya Holmer's video on why we can't multiply vectors is a good intro, followed by sudgylacmoe's videos called a swift introduction to geometric algebra and one for projective geometric algebra
@@Hector-bj3ls You generally need for physics a few types: general multivectors, motors which are the even subalgebra, bivectors for momentum and velocity, and in pga trivectors for positions. more than that is useful but probably unnecessary
@@keldwikchaldain9545 Unfortunately I've seen comments disappear quite often with youtube, it's really annoying. I remember watching this one talk about pga on youtube (can't find it right now) and it seemed to make a lot of sense but just like Hector said, I find it hard to translate these ideas to code. What datastructures to create and what can I do with them. But maybe that's because I haven't watched enough of it, so thanks for these resources
I can take a look if you want, but I am actually learning these things roughly at the same time as I am making the videos about it. So I haven't implemented joints myself and I am not sure if I can validate your implementation
To ensure the determinant of the rotation matrix remains at 1.00000 can you not simply normalize the x y and z components before applying it to the mesh? Loving the videos, i am trying to create my own N-body gravity simulation in C++/OpenGL, and have been trying to wrap my head around rotation natrices and this video helped perfectly.
That's great to hear :) I haven't tried anything to fix the rotation matrix so far, but I think that while just normalizing the axes might help, it doesn't guarantee orthogonality. So you also need to ensure that all axes are perpendicular to each other. For that you could use cross products (normalized) or something like Gram-Schmidt. But I don't know which approach works best.
@@blackedoutk The book Game Programming Gems 1 for which you find a pdf online has a chapter 2.2 on "Integrating the Equations of Rigid Body motion" by Miguel Gomez on this subject. This chapter proposes a different integration variable "q" and also some references because it claims that the rotation-matrix method introduces error and requires regular reorthogonalization. BTW a lot of this rigid body math is also present in university level courses on mechanics, robotics and aerospace engineering.
@@richardbloemenkamp8532 Nice, thanks for sharing the resource. They use a unit quaternion q instead of a rotation matrix to avoid having to do a reorthogonalization. The quaternion just needs to be normalized after the update, which is easier. In the future I want to use quaternions too, but here I wanted to start with the basics. I noticed that too, that rigid body math is part of quite a few university lectures. Currently I am attending a robotics lecture and a lot of the stuff I researched for this video helped me to understand some of the topics faster. They also presented algorithms that build on top of these basics, like for chains of rigid bodies with joints (robots).
Best way is not to use rotation matrices. Just use rotors. Uhhh, most people aren't educated about them, though, right? Yeah, they call them quaternions/complex numbers :d
Happy you think so it was quite a bit of work, thanks. The equation animations are made with manim in python and the renders are from my game actually. At first I thought about using blender but I wanted to use my simulation code, so I wrote a small internal animation framework alongside of programming the animations itself. In the end I opened up the timeline in the game and hit space while screen recording to start the automatic playback. You can even see where I struggled a bit at 32:49 because I couldn't figure out how to remove the background of the object in video:D I used DaVinci Resolve to put everything together
@@blackedoutk Haha, don't worry it's so minor I barely noticed 😃 The video is still top quality btw, found this video by accident, but I think I'll check out your other videos
So at the timestamp you've given bold x would be the column vector of x, y and z. And because we integrate over the domain Omega (the cube) bold x is the position of every point inside of Omega
Humble asking, I’m not an engineer degree student, what knowledge should I learn in order to understand this video content? Calculus and Linear Algebra? If so how deep should I go?
I am actually not even an engineering degree student myself, just computer science. I think it's enough to understand the basics of both calculus and linear algebra and a bit of physics maybe but I would say having an intuition is important. Like thinking about what does a matrix represent in space or what does it mean to take an integral. And then there's a mix of the two which is also important, deriving vector functions results in a jacobian matrix etc. The latter is a bit of a matter of practice, meaning writing down and rearranging equations. I hope this helps, it's hard to say exactly what is needed imo. I just attended the basic math lecutures that mathematicians attend and even thought that some of it was overly theoretical. Maybe because of the proofs. A lot of the knowledge comes from working with matrices and vectors like when doing a lot of graphics programming. The calc and linear algebra mix I learned because I attended some animation and simulation lectures, where you have to derive vector functions because of 3d physics and stuff
yes, the in game ui I made with a library called ImGui. I have more details about this in episode two. I will consider to update the description, it's a good suggestion thanks
@@blackedoutk The structure of the problem is so straightforward that calling out its fancy name seems unnecessary, especially when it tends to be only mentioned once and then never brought up again. Just a curiosity though, the video is great and I can't wait for the Quaternions to show up!
@@LarsDonner The reason I mentioned it is so that viewers have something to look up if they want to learn more about it. The problem itself may be easy to understand, but there are a lot of other things associated with it and many different, not necessarily straightforward ways to solve it. Though I know what you mean and would probably agree with you in some other cases. I remember seeing the Schur complement being mentioned in the XPBD paper for example and initially thought it was really complicated because it looked like that on Wikipedia. After writing the derivation down step by step though, it turned out to be just some simple equation rearrangements.
At 29:57 you had Matrix1 - Matrix2 * g(r) . Then you just subtracted these Mat1 - Mat2 , ignoring that second matrix is multiplied by g(r). Is this legal? If g(r) is constant then at least it should be M1 - M2*g
@@bartoszstyperek6306 Yes exactly. But you‘re right, I should‘ve included brackets there, thanks for pointing that out. I was thinking about the rho to be associated with the dV
Hi, im currently learning phyiscs, math and i solve c++ problem solving and now i came across few physics simulations and i would love to learn it my self what framework do you use?😊
Hi, in my game I am using SDL for windowing and inputs, glad for loading the OpenGL functions, Dear ImGui for displying a debug gui and stb for loading images. I have a very basic version of the program on my GitHub in a repo called cg-papers if you want to try it out
Basically the SDL library to create a window and handle inputs, OpenGL to render (with the glad library to load the OpenGL functions), the ImGui library to create a debug user interface and a bunch of C/C++ code that I wrote. The program started pretty simple in my first episode, if you'd like to see Edit: Forgot to mention the stb image library for loading images
Instead of using a rotation matrix could you define a set of pure quaternions x,y,z. Where the components of these pure quaternion encode an angular velocity vector for them. After which you multiply the vector component by delta time and then perform quaternion multiplication. Then you add the result of a new delta rotation to the current rotation of the ridged body? Example of an arcade way. void QuatApplyYaw(float DeltaTime) { float NewYawSpeed = YawVelocity.Z; float YawSpeedCoeficent = NewYawSpeed / MaxYawSpeed; float YawAccelRad = FMath::DegreesToRadians(MaxYawAccel); FVector AngularYawAccel = FVector(0.0f, 0.0f, YawAccelRad * GetLastYawInput()); FVector YawDrag = FVector(0.0f, 0.0f, YawSpeedCoeficent * MaxYawDrag); YawVelocity += (AngularYawAccel - YawDrag) * DeltaTime; FQuat AngularYawVelocity = FQuat(0.0f, 0.0f, YawVelocity.Z, 0.0f); YawQuat = FQuat(AngularYawVelocity) * DeltaTime; } Then you take it this and stuff into another Quat FinalQuat = FQuat(RollQuat.X, PitchQuat.Y, YawQuat.Z, 0.0); WorldDeltaRotation += WorldDeltaRotation * FinalQuat ; is this a correct approach?
Hm, so what exactly are you trying to achieve? You can definitely replace the rotation matrix by a unit quaternion, but why do you want to use x, y and z quaternions separately?
@@blackedoutk When I initially coded a plane game I had to obviously deal with Gimbal Lock issues. When I visualized it in my head I imagined Unit Quats for the yaw pitch and roll. Then the final rotation would be the composition of those quats. The reason I separated I guess was because I had different inputs for Yaw Pitch and Roll. So I wanted to control angular acceleration per axis using just a quat for each axis.
@@julianpopa-liesz3345 So I think for implementing the physics of a rigid body using multiple quaternions is not the right thing, just use a single quaternion and accelerate using torque. However in some cases like for camera control it might make sense to use x, y, z quaternions to describe delta movements. But I would still store the orientation of the camera as a single quaternion. I hope you understand I don't have the time to understand and assess the correctness of your code. Just one thing I noticed, to apply a quaternion to another one you can imagine them to be like a series of matrix multiplications, so apply the newer ones to the left of the old one (using the quaternion multiplication operator of course) and then don't add, just assign, meaning TotalQ = QuatMult(DeltaQ, TotalQ)
@@blackedoutk I agree with you fully for rigged body its a bit different. One thing I might add if you do go down that route which I've been looking into and trying to understand the precision from taking derivatives and Integrals of Quats. More specifically the best way to apply a delta over time. It gets into the weeds with Lie Algebra (since you're taking about tangent space for Unit Quat of the hypersphere) but for computation, the question is what would the best way to apply the final rotation in a error free manner. Apparently taking the k=1 Taylor series is enough to approximate the orientation delta when doing the integral. So I found out two ways you take the integral, You can Multiply the quats to the final orientation or multiply then add. The issue with the addition path is you really need to normalize the quat every iteration because there is error that accumulates overtime. When I get the time I will be testing this to see what the best way to apply the discrete steps should be.
@@blackedoutk it's for people who got into the mythical math school, and understand the arbitrary kabbalistic notation and symbol. It took me a while to understand than 3d matrix were just 3 or 4 vector literally duck tape together. Most concept are simple but damn if math people got years of brainwashing about poorly thought notation. Proof there is equivalence between math and programming, technically they are the same thing, but it's way easier to learn programming than math, and programming can surely be improve more.
@@timmygilbert4102 Interesting, do you have other examples of math notation being poor? Not that I necessarily disagree, just curious. A matrix being a series of vectors in space is probably the best inution in many cases, but for example like the undecomposed inertia tensor it's hard to make sense of it when just reading it as its 3 column vectors
@@blackedoutk just an opinion but basically all if it, we can probably redesign number to more intuitive, like actually representing of the quantity, like actually many number system beside the Arab numeral we use. It's been proven these alternative are better cognitively. Redefining naming convention to not be the patronyms of mathematician would help, I know it's about showing appreciation for people who help discovering the math principles but I'm doing math, if I need to learn history I'll use the proper course. Also all symbol were basically randomly chosen on a whim and barely represent what they are doing, even if I'm comfortable with big pi, Big sigma, and integral schwa, doesn't mean they aren't arbitrary. Proof is that programming is the little twin brother of math, and started with the same convention, but quickly diverge toward sanity, loop, function, variable, clearly spell what they do and avoid ambiguity and arbitrariness. And when mathism come biting back, like with adoption of functional programming, we clear the nerd and their monoid, morphism and functor, to replace it with clear explanation like 'do not have side effect in your damn function'. These functional programming term aren't even hard, category theory isn't even hard, the hardest part is to remember which terms map to which concept in an insane cascade of arbitrariness that prevent making connection across discipline sharing pattern. Fir example, the AI hype is making everyone nervous to appear not smart enough to understand what's going on, so people cling to term as a replacement to understanding, oh it's a Markov process, congrats it mean nothing, a computer is a Markov process when observed from outside, that say nothing, it's s stack of matrix tensor, so is my Photoshop drawing what's the point? Arbitrariness if term came as a crunch to socially signal you recognize reference as a replacement for understanding, as people might not know the word despite being intelligent to process the concept behind the words. So when I try to point that, despite neural network being thought as black box, the fact they are oriented graph severely limit what can be done, especially if we realize single neuron can only perform 4 fundamental operation, we can infer general mechanism from these constraints on any observed performance or quirk. For example, chat like AI have to encode sequence, how does a DAG support this functionally, it shed light on how all of this works because there is a limited way in which you can do so, you can derive first principle to discover how neural network get their performance. But not you just have to bake hebbian and that's the end of the discussion. Which lead to people doing absurd thing like looking semantics in single network, like as if inspecting transistor in a microchip to find the one that do math, instead of figure out what an adder is, IE a network of transistor performing a function collectively. Imagine these optimisation of circuitry where a transistor reused and belong to two cluster of function, then inhibiting it people realize the chip no longer perform two operations and call that transistor 'polysemantic', that would be pure buffoonery 🤡
@@claudiopisa2043 nice, computer engineering is also a bit of physics, is it? if you read the papers just don't stress to understand it all the first time, it definitely takes time and sometimes going through the equations by hand
@@blackedoutk yeah we have two physics exams, the former focuses on the basics of kinematics to mechanics, the latter is about electromagnetism. The hard part of this paper is to understand all the linear algebra notations, you need to get used to them
Good video, but I don't know why you spent so much time talking about density. It is not the job of rigid body simulations to compute mass given an arbitrary density function. Everyone just assumes density is uniform and mass is given as an independent variable, just like the geometry of the object.
Sorry :/ Unfortunately I have to start somewhere, else the video would be wayy too long. What exactly would you like to have explained in more depth or which prerequisite knowledge should I not assume to be given?
Here is code for calculating mass of any triangular mesh with uniform density. def get_volume(indices:list, vertices:list) -> float: volume = 0.0 for i,j,k in indices: a = vertices[i] b = vertices[j] c = vertices[k] e0y = b[1] - a[1] e0z = b[2] - a[2] e1y = c[1] - a[1] e1z = c[2] - a[2] volume += (e0y * e1z - e0z * e1y) * (a[0] + b[0] + c[0]) volume /= 6.0 return volume def get_mass(indices:list, vertices:list, density:float) -> float: return density * get_volume(indices, vertices) If you need Inertia tensor as well, it could be calculated at the same time with some changes. Note: triangle winding must be CCW.
@@rizohashimi Ah nice! That reminds me of the paper "Fast and Accurate Computation of Polyhedral Mass Properties" by Brian Mirtich where he uses the divergence theorem to compute the inertia tensor. It was actually the first method I tried to use, but found it to be a bit too complicated 😅 Although the volume computation you posted looks quite cheap. I wonder how it performs in contrast to the scalar triple product version
@@blackedoutk By the scalar triple product version you mean the one where you calculate volume of each tetrahedron? What's cool about this version is with some changes it could calculate the intertia tensor at the same time. IIRC it's from a paper "Polyhedral Mass Properties (Revisited)" by David Eberly.
@@rizohashimi Yeah the volume for each tetrahedron one. Yours has 2 subtractions more but only 3 multiplies instead of 9. But it's probably more about how simd compatible they are. You can actually combine the inertia combinutation with the volume for each tetrahedron version as well. In fact, that's what I did. Hopefully I can talk about that in the next episode.
I would say a bit of calculus, linear algebra, numerics of odes (maybe also numerics of linear algebra), and a mix of calculus and linear algebra, so multidimensional calculus, where you learn about the jacobian matrix. one commenter said the first half of a transcendental calculus book should be sufficient for anybody looking to learn. but I can't verify this. numerics is probably the least important of these. the most important is getting intuitive understandings of vectors, matrices, derivatives and integrals
Hey! This video just now popped up in my recommended videos. It was really good and I watched it all, understanding most I'd say. It has really helped me. Thanks a lot! I will be watching the next one(s) too.
Thank you for this video! I've always enjoyed math and physics applied in programming. Btw at 26:14 , matrix multiplication is NOT commutative, (AB≠BA (usually)), rather, its associative (A(BC) =(AB)C)
me too, I wish there were more videos that guide you through the details. and you're right, that's a mistake in the video. luckily I just mixed up the two words so the math is still correct. I had put this in the pinned comment, but maybe it's too long already 💀
Nice! I'm trying to wrap my head around the XPBD paper and I newly discovered your videos, amazing work so far, can't wait for the upcoming videos! Next thing for me will be to get constraints working with rigid bodies, I'll most likely mess it up and then wait for you to explain it :D
Thank you! Happy to hear that :D Unfortunately it'll still take quite some time until I get there. If I could, I would pump out these videos weekly, but that's just not doable for me
@@blackedoutk That's totally understandable, with these kind of topics I value quality over quantity, watching a bad tutorial that makes you more confused than before is not a good experience. That's definitely not the case with your tutorials, so keep up the good work!
Please make a video (if you haven’t already) implementing the quaternion approach. That would be really fun to watch. Also great video, really enjoyed it.
Thanks! I understand more less how L is conserved at minute: 38:30, but how do you apply an external force to the L. I mean the combination of the L conservation and also some forces producing torques. Thanks!
Similar to the linear motion where force is the derivatve of the linear momentum p, torque is the derivative of the angular momentum L. So in both cases, applying forces or torques for a certain time at the center of mass can be accounted for by integrating both of these and adding them to the respective momentum variables. If you have an external force that is not applied to the center of mass, you have to apply it to the center of mass and separately compute its resulting torque by using Torque = Cross(point where the force is applied, Force) and apply it to the angular momentum too. Does this help? I would touch on this in future episodes, but idk when I will do those
As some of you have pointed out, I made a few minor mistakes while talking about the math. I want to summarize them in this comment.
First, at 26:06 I inserted the rewritten vector triple product into the integral without putting parenthesis around the expression. So in every following expression, it looks like rho(r) is only multiplied with the right addend, when it actually must be multiplied with both of them.
However, if you imagine that there are brackets around the sum expression or think about rho(r)dV as being the differential mass element of r, which is what I did and how this mistake even occurred, then everything is still correct.
26:06 TL;DR: brackets missing visually, maths still handled correctly (as if they were there)
Secondly, at 26:15 I moved some parenthesis and said that this was possible because matrix multiplication is commutative. I meant to say associative of course. Matrix multiplication is not commutative in general.
26:15 TL;DR: is used a wrong word
Thanks to @bartoszstyperek6306 and @jaborl mentioning these and sorry for any possible confusion.
If you find further errors, I would appreciate them being pointed out as a reply to this comment, so they are easier to find.
UPDATE 2024-06-30
As @notu483 pointed out, the explanation prior to the conversion step done at 7:41 is a bit vague. If you want to do this more formally and correctly, I suggest to use a function w(x, t) to have a better distinction between the resulting time dependent world position w and the local position x that is being integrated. Then you can use Leibniz integral rule (specifically the one for higher dimensions aka Reynolds transport theorem) to do this conversion. Thanks for mentioning.
7:41 TL;DR: only important if you're interested in the specific mathematic details
@@matthiasmax2849 Hey, I feel what you're saying. Unfortunately, I'm not really sure what to recommend. I didn't read one specific thing that taught me all of this, rather I picked up some things here and there.
Are you studying computer science? That would definitely be a good starting point. I feel like what helped me was working through exercises and writing down derivations step by step, even if it felt kind of pointless.
And I would still recommend to attend the available simulation lectures, regardless of whether you have all the necessary prior knowledge. If that is possible. I picked up most of the math I present in these videos because of the animation and simulation lectures. I felt damn hopeless in the beginning, but because I was so interested in this topic I learned much by googling the little things or watching a few niche RUclips videos. Also, don't be afraid to ask your professors stuff.
By the way, I also have a discord server now if you're interested, the link is in the comments of my second livestream. We could discuss this further over there.
Man, do I sound that german 🙈I hope my english is still okay to listen to haha
probably best to fix the error in the video and then to reupload the video.
@@PerriPaprikash in some way true but unfortunately that kills the momentum of the video. and I would lie if I said that I don't care how many people I reach with these videos. after all I make them so people watch them. so that's a bit of a dilemma. additionally the comments would be lost
@@blackedoutkyou could have an unlisted fixed video, though hard to tell how would that affect the algorithm
I want to understand this video, yet my calculus knowledge is limited to a highschool-level course. Please remind me in 2-3 years to come back and rewatch this video so I can actually understand all the math
I created an entry in my calendar in 2 years:D see you on the other side 😤
you don't need calculus yet,you must be good at linear algebra and geometry.Programming is not easy as mathematical imagination,one logic goes wrong and the rest of the system will be ruined.
@@lanchanoinguyen2914 Imo it's easier, you can be a bit less strict unlike math that's unforgiving.
@@lanchanoinguyen2914 Math is harder, bro. Programming deals more with Raw Logic, though.
math is 100% harder yeah@@friedrichmyers
I can almost understand the math, like an itch you cannot scratch. Love it. Great video, thank you so very much.
:D thank you. maybe I can help out? which part is not exactly clear?
FINALLLY!!! a new physics engine video 😀
yayyyyy
It's always interesting seeing these types of videos, which are always rare to come across without obnoxious over-the-top narrating, I'm glad I subscribed :)
That's nice to hear :)
I’ve been working on my own physics simulation engine as an opportunity to brush up on my understanding of physics as well as practice coding some more interesting projects.
This video is phenomenal! The intuition presented here is so much easier to make sense of than everything else I’ve seen for handling 3D angular momentum.
Part of the simulation that I’m interested in is handling a dynamic model that does not stay as a rigid body, but if I’ve internalized this intuition correctly, I should be able to use conservation of angular momentum combined with time dependent inertial tensor calculations to accurately model rotations in my simulation.
That's great, thank you so much. I am not exactly sure if this is applicable in your case, I mean the total angular momentum of the dynamic model must stay constant, but that is not true for any part of it, since they might exchange energy.
I’m a mechanical engineering student and I didn’t really understand the whole inverting/ shifting axis of rotation thing until I watched this, excellent work!
that's so great, thank you!
Mate, your videos are amazing; a great balance between math and implementation! Thank you and keep posting :)
Thank you, that's great to hear :) I feared there was too much math in this video
I feel like ive been waiting for this video to exist my whole life. I think I can die happy now.
haha:D
I really love the quality of the video. The explanation is also really good. These types of tutorials give me motivation to challenge myself with programming projects I've never tried before. I hope you continue making videos!
Thank you, that‘s nice! My goal is to make these things both easier to understand and implement. I hope I will continue too 😁
i have never understood how integrals work until now, but this made my brain finally grasp the continuous function pat
great to hear:D I really dislike it when there is a mathematical concept that I can't get an intuition of
this vid is also a nice introduction to the actual physics of rigid bodies, well done
thank you :)
legendary fyp pull
aint getting no "we can go gyatt for gyatt" reels
damn I feel old, but thanks I guess haha
@@kafial7776 😂😭
legend! finally an in-depth dive into rigid body simulations (not that I can understand the math but still)!
ty! 😅 if you have questions regarding some parts feel free to ask. maybe I can help out
yessss my calculus course is worthy now !!!!
haha finally, right
At 26:15, you said matrix multiplication is commutative but it is actually associative.
Thanks for pointing that out. I meant to say associative. Matrix multiplication is not commutative in general.
This is over my head but I’m trying to learn it. Your videos are gold for helping me make that leap. Thank you! I am very much looking forward to the next one. Please don’t stop! Your efforts are greatly appreciated!
Thanks, glad to hear that :) I would recommend working through some exercises to get more comfortable with these concepts. Or even just writing down the derivations and trying to understand each step.
@@blackedoutk Will do! I"m brushing up on my calculus as well.
Try to check my comment up above, maybe it'll help?.. Maybe not
What an incredible presentation. Taught in such a way I alllllmost feel like I could've gotten there myself. Such is the mark of all excellent explanations as well as the excellent teachers behind them. Excellent job and thank you for this gem!
Thanks man, finally a video that not just scratches the topic of rigid bodies. After reading through a paper, watching this video makes me understand what I have read better. Thanks!
Glad it helped :) which paper did you read?
Very nice, i can see how statics, dynamics, and some coding/matrix knowledge is used.
And the first half of a transcendental calculus textbook should be sufficient for anybody looking to learn.
thanks. that's useful to know, I always struggle a bit telling people what prerequisites they need
Amazing video! I was looking for something like this for a long time
Same :D Thanks!
This is golden! thanks for making this video
Thank you :)
Very nice video on such an interesting topic.
You've actually explained the spin instead of the angular momentum since you were using r and not x. In your notation it would be the angular momentum L = x x p and the spin N = r x p (with integrals).
The problem you've faced with the referential density also holds for the integration limits. They would be also dependant on the actual rotation when you are using the inertial basis as coordinate representation.
I made the observation, that many people get problems with rotations and transfomration matrices. The vectors r, r-~ and r-v all refere to the same vector in space, namely the vector from CM to the particle, but only represented in other coordinate systems. There isn't something rotated, it's just an projection to other basis vectors. You could try to store the Omega and N in body fixed coordinates, how it is often done in mechanical simulations. I guess that could save some matrix multiplications.
Thanks for the video, I like to see you making progress. I liked the explanation to get the angular velocity with the rescaling, made it more intuitive what's inside the inertia tensor.
Thank you :) Definitely interesting, I didn't know there was a differentiation between the spin angular momentum and the orbital angular momentum. But I don't think it's necessarily wrong to still call it angular momentum, just a matter of which origin point is used.
How would the density be dependent on the rotation in an inertia basis? I am not sure I understand. Also, while r, r-~and r-v refer to the same vectors in local coordinates, I am not sure this is the case for global coordinates. Maybe you have another intuition than I have?
I thought about storing the angular momentum in local coordinates, this might be a good idea. Though I am not exactly sure because then you might have to rotate the torque vector. What would be the benefit of storing omega in local coordinates?
I really appreciate your remarks, thanks
@@blackedoutk Thanks for your reply. I wasn't conscious of these english expressions for spin angular momentum and orbital momentum. For kinematics, you have to use the same reference point for induced torques, which is anyway convinient to take the center of mass for that.
Something that really improved my unterstanding of physics and especially mechanics, was to think of vectors as arrows in the space instead of putting three number on top of each other. Mechanics works as well with these arrows, but we need number to describe these arrows. For that we can use a inertial fixed basis or any other, like body fixed. Then, r, r-tilde and r-v describe the same arrow in space, but with other numbers.
After rewatching your the sequence I think I got it better. Your density function (rho) takes the vector in global coordinates and rho-tilde takes it in body fixed coordinates, which would be the only possibility to give a proper definition of the function.
Lastly, I have never thought about integrating the angular momentum instead of the angular velocity. This could simplify many things and removes some exhausting derivatives and materix multiplications. I think expressing the torque vector in local coordinates could be already cheaper. Force elements are mostly mounted body fixed, so for rotaional springs/dampers, their force contributions are already in local coordinates. For induced torques by a globally given force, you either have to take force into local coordaintes or calculate r in global coordinates.
Would be interesting to see some benchmark experiments with both approaches and whether you face any other problems like in time integration.
Anyways, I am curious see the progress you're making :)
@@niklaswagner6191 Such benchmarks would definitely be interesting. Though later I will probably stick to storing and integrating the angular velocity anyway, because that's how the XPBD paper does it.
Your understanding of the density functions is how I imagined it, so the definition would then be rho(R, r) = rho-tilde(R^T*r).
I try to think of vectors as arrows in space too. And even matrices as multiple arrows if applicable. I believe understanding these concepts is much easier with a visual intuition and find it quite unsatisfying when people introduce some theory (for example the inertia tensor) without providing an intuition for it. In my opinion, there should be some amount of focus on teaching that as well
watched all the way through, very thorough video. amazing job
nice, thank you
The first minute perfectly describes my experience with this lol
Wow youtube compression is very good. Downloaded this video because it is great and found out it's only 110 megabytes!
Amazing video. Really well done and I loved how you approached the topic. It was also really funny at times! I was laughing when the tension over baiting an explanation on quaternions over matrices scene happened, and I was genuinely lol'ing when the terminal started showing random strings of characters as the guy in the clip smashed the keyboard.
If there's any criticism I can make is that you sound a bit monotone. Many of the jokes would have been 10x better with some small comedic performance. Dude, you are funny and great! I know you can do a version with slightly more energy even if just for the joke parts. Please keep this content up!
Subscribed.
love your comment, made me happy thank you :)) I agree with the monotone bit but it's hard for me to change that. sometimes I think I already bore people when I'm just telling them stories but it's the worst when I'm reading out loud 💀 plus this is english and I have to calm myself because somehow I get stressed when recording the script and then I sound like in the first or second epsiode. I'll see if I can do something, though doubt it. but definitely a fair point, appreciate it
Epic video. The most relatable and useful one so far
That‘s great, thanks a lot
did you delete your reply or was it some yt shenanigans?
@@blackedoutk I did. I wasn't in my best state of mind and thought i was being cringe so i deleted it lol. but my point still holds, epic channel bro
@@弘睿甫 no worries I am the same. part of why I am so slow to answer is because I overthink what to say. sometimes I respond faster and cringe a month later lol. I thought your comment was funny
I have no idea what is happening. I barely understand the math, but something inside me made me click the video and subscribe
I like that:D I mean, not the part that you don't understand the math. Is there something I can do to fix that?
7:13 "Dot notation" is actually called newton's notation.
Ah interesting. Sometimes I just use non technical terms to make the stuff I say more relatable or easier to understand. Though admittedly I didn't know it was called newton's notation
@@blackedoutk btw bro, why did you stopped uploading?😭
Your content was so fire 🔥🔥🔥
@@renuk8560 university :/ Right now if I could I would be programming all day haha
So far I've found Verlet to be better than Euler. It's more stable. I've been building a cloth simulation, and with Euler it explodes way too often.
Verlet doesn't use an explicit velocity, it calculates it from the previous position:
vel = pos - prev
prev = pos
pos += vel + acc * dt * dt
Yes there are definitely problems where it is more stable. I think it is closely related to the semi implicit Euler method
23:47 You forgot to tell us what tmn and tvn are
They are template structs for vectors (tvn) and matrices (tmn) where the parameter T is the scalar type and U is the number of elements per row or column. The data is stored in an array named E, hence why in code you always see .E[] instead of x, y and z for example. To make these easier to use I then typedefed them like this: typedef tvn v3; and with a prefix d for 64 bit floats.
@@blackedoutk Ah, okay -- thanks!
This is my new favorite video on RUclips
Woah, really cool. I'm happy you like the video so much :)
@@blackedoutk I wrote a game engine for a uni project and the physics transforms really tripped me up. But this video and the follow up one on inertia made everything so much clearer. Do you have another dev log planned soon for fixing the determinant bug and other juicy stuff?
@@MrBomberman11 Planned yes, but without date. So next video would be intertia tensor decomposition and then the next I wanted to fix the determinant using quaternions
I recommend you to search about "matrice d inertie " and "tenseur dynamique" this is everything you explain but in very simple form
I doubt this is everything I explained and also I don‘t understand french
is method we use for simplify the calculation
This video is great, thank you very much! I will certainly try it out myself in my code.
thanks:) yes definitely try it out. working on a game or just for fun?
@@blackedoutk I have a pet project in C from scratch, where I learn things. Based on handmade hero, but with my own twist.
I have an idea for a game that is reachable for my abilities, I think, but it's still a huge amount of work, and it's really hard to combine with a full time job.
@@slavicradko9846 oh cool, I also watched handmade hero, but only the first 200 episodes or so. it's really great. did you watch the whole thing?
I can imagine the difficulty when having a full time job. I don't have one but still struggle with time management :/
@@blackedoutk no, I did not, I watched around 100 and then selectively some of the later. It was enough to get me a well paid job though, so I greatly appreciate Casey for his efforts 🙏
Excellent video!
Thank you! :)
Nice, very nice.
Thanks :)
I have a problem at 09:44. As a theoretical physics graduate student I'm used to C and Python so I understand the idea behind your struct, but what kind of libraries are you using? I've never seen "dv3" as a datatype to define 3D vectors as well as the datatype "mesh''. Can you provide some info? Beautiful video by the way!
Thank you, glad you like the visuals! The data structures you're seeing are part of the game and not from a library. I talk a little bit about the general vector type in my first episode, but really they are just structs that hold the coordinate data in an array. Then I wrote all of the functions needed to work with them, like operators, dot products and so on.
The mesh struct I don't think I have mentioned in detail in any episode. It holds all of the data for a model, like vertex positions, normals, tex coords, colors, face indices and textures, and the handles that are needed for the OpenGL rendering, meaning vertex array object, vertex buffer object and texture handles.
It also contains some less relevant stuff like the models name or edge information which lets me draw a wireframe model without using wireframe mode.
Lastly it contains the original center of mass and decomposed intertia tensor of the model as it was exported from blender for example. Though this I plan on explaining in the next episode.
I updated the description with the libraries the game uses in its state of the video. Let me know in case you have further questions about this
I am loving all of the explanations! Can you share the source code of the animations in the video? How do you do the voiceovers? Will you share your right body simulator code as well?
that's great, thank you. sharing the 3d animations is difficult because they are part of the game, so for anyone to understand the code I would have to share parts of the game code aswell. the manim animations I could share but I'm not sure I want to, what would you want to do with them?
for the voice overs I just record me reading the script and then fiddle the stuff together in DaVinci Resolve. I will share the rigid body code eventually in the library I talk about in the episode 6, but the game code for now I don't want to share. my goal is to explain the important parts, so that viewers can implement it themselves or at least know where to look for
You are my god.
woah not so fast, where are my prayers?
Wait this is a very valuable resource. Damn.
Glad you think so :D
Transposes R equal to inverted R if R is orthogonal matrix
Did I forget to mention that?
tl;dw
Let me try to make it shorter. Body has linear and angular momentum. Divide linear momentum by mass to get linear velocity. Transform angular momentum into local frame of reference, divide each component by one of 3 angular masses, and transform it back into global reference frame to get angular velocity (which doesn't always ends up aligned with angular momentum, creating interesting dynamics). Or compose it all in it's entirety into a single momentum->velocity transformation, if you so desire, which ends up as a symmetric matrix - matrix that resizes space relatively to some orthonormal basis. Now move your position by vel*time and rotate your rotation by angVel*time.
The tricky part here is actually calculating next rotation, since it is represented *either* with geometric algebra rotors and bivectors, or using matrices. (And no, euler angles don't count, they are just funny useless parametrization, that can't do anything on it's own)
Anyway, long story short(er):
Angular velocity (or momentum) is a bivector - a quantity, where each component is associated with 2 coordinates. Kinda non-diagonal elements in a matrix. But here, instead of linear mapping, they represent oriented quantity from one axis to another one - for example "+5xy" shows rotation around "z" axis.
Easiest way to turn them into actual rotation is by viewing them through the lense of VGA. In it, vector is used to represent reflection around a plane, and so a composition of two of them gives us a rotative transformation twice that of angle between them. This is called a rotor (in 2d only it's a complex number, in 3d it's quaternion). Composition rules are pretty simple (read left to right): "x*x = 1", "x*y = xy". So "(1x + 0y) * (0x + 1y) = 1xy".
"1xy" in this case is just a bivector, since vectors were orthogonal to each other, and it represents a +180 degree rotation. But reflections generally don't commute, so composing them backwards will give us opposite rotation "y*x = -1xy", which is -180 degree rotation around z (in 3d).
Now, these bivectors can be composition-exponentiated, which gives us a rotor (in 2d and 3d you can implement exponentiation using very simple trig, and for other dimensions there is a more general formula). In other words, we just turned rotation direction into a rotation. Compose it with our original rotation, and you're good to go. In any amount of dimensions, at that. Have fun rotating hypercubes!
Now, in order to render vertices and whatnot, just transform your vector represented as a reflection-operation into a global frame. How? The same exact way we did with local angular mass (which is just an operation converting local momentum into local velocity) and rotation. "[madeupArgument]*reverse(rotation)*reflection*rotation" "[madeupArgument]*reflectionOutsideRotation".
Anyway, I'll go into more detail and fill in the gaps, if anyone ever reads this and wants to know more. Could as well touch on PGA rigidbody dynamics too, since they are quite elegant and interesting, although their math is a bit too big-brained and not as general purpose, as concepts I discussed.
tl;dr
I think covering this in depth needs a bit of time, hence the length of the video. And while I appreciate you trying to explain rotors and bivectors, I don't understand this purely in a short comment. Why don't you make a video about it?
@@blackedoutk Uhhh.. Yeah, making videos is not mine kind of thing. I'd probably just write an article series in couple years, after my current projects are over
@@blackedoutk Just check out materials created by bivector community, to fill in the gaps. My goal was just to give a rough intuition, which those materials on their own do not fully provide. They are more focused on algebraic aspect, and working with transformations as if they're objects (by talking about transformation's invarient subspaces).
C++ - "It works on my machine" the language
is that an insult 😤 what's your fav language
@@blackedoutk Referring to the build system that even you are having horrible issues with. And, Rust
@@Waffle4569 Ah I see. But I think that's more of a problem with the build tools rather than the language itself. Maybe it's because I have never worked on big enterprise software, but I really don't understand the need for all of the complexity in build tools. For small to medium sized projects, using shell scripts is definitely superior imo. Also because you say "even you", I don't think I am a good reference for comparison when it comes to building projects, I'm horrible at that.
I tried rust recently because I have to use it for a project and I get really angry about the borrow checker all the time lol, but I know that's probably a skill issue
@@blackedoutk I think it stems from the simplicity of the old days when compiling was just calling an exe with arguments, but its horrendously overgrown now. The build system was never intended for more than one person's personal computer, absurd amounts of build config are defined by command line variables and dependency directories that might not be present. Not to mention there is no real compiler standardization, so even the compiler becomes a dependency that might not be listed. Pretty much every language after C++ realized they need to define how the build system and dependencies should work.
Rust has a very steep learning curve, but ironically it has the easiest dependency/build system I have ever used.
CMake is cancer of the highest order. It is the PHP of build systems. And that is an insult to PHP.
14:30 Why not just use trapeziums to calculate the approx. area? You can calculate the next v 1 iteration before, store it, calculate the correct trapezium area, and then the next iteration you already have the current v.
Yes that would be better, however keep in mind that you need the right end value to do that, which means it's an implicit method and thus way harder than explicit. It's a bit difficult to see with the linear velocity example because the velocity does not depend on the position, so you can just compute it here. But try to write down the same thing for the angular velocity. This one depends on the current orientation. So to get the exact right end value you need the angular velocity there. However this velocity depends on the orientation at that point in time. It's a cyclic dependency. Does that make sense?
There are explicit methods that do kind of what you suggested for simple functions, like the midpoint method which is second order explicit. But of course the formula looks more complicated so I wanted to stick with something simple here.
Good video
Thanks:)
Facinating video. Are you interested in computational EM and opics? or just physics engine and rigid body motion?
thanks. currently more interested in rigid and soft body physics. but I'm not opposed to other simulation topics, just already so many things to learn. do you know more about these other topics? or do you wish to watch videos about them?:D
@@blackedoutk Yes I know more about these topics and I wish to watch videos about them too. There are channels that do something similar but I thought why not ask you about your interest to understand you area of expertise.
14:00 yooo I used a pretty basic numerical approximation like this in my double pendulum simulations so that's why it blew up really fast
haha yes, given enough time this will happen unfortunately
Awesome video. Very cool
Thank you, happy you like it :)
What a coincidence! I've also been working on implementing some rigidbody physics.
I am currently trying to implement angular motion with a constant angular velocity, just for simplicity.
I have a question: I have tried updating the rotation matrix as you did in the video: Cuboid->R += DeltaTime*Cross(Omega)*R (with a constant omega vector)
However, when I do that, my rotation matrix is no longer a rotation matrix after a few thousand simulation steps (The determinant explodes into values like 200). I'm using a DeltaTime of 0.01, but I have the same problem with a DeltaTime of 0.001.
Am I missing something? Do you normalize at some point?
Thanks for the video btw
Cool! The problem you are facing is completely normal, I talk very briefly about this at the end of the video. But to add to that, you can even make intuitive sense of it.
What you are trying to do by adding Cross(Omega)*R to R itself is move the axes of R along their respective circular paths. As explained in the video, Cross(Omega)*R contains the velocities of each axis vector of R, which are tangent to the circles. Regardless of how small your step is, if you move some epsilon > 0 along the tangent line of a circle, you will always leave the circle. Resulting in a larger radius than previously. The axes increase in length.
You can fix this by reorthogonalizing R after each simulation step if you wanted to continue to work with a rotation matrix. Another, probably better fix would be to use quaternions instead. I didn't do any of that in the video, for some of the footage I just used an even smaller time step 😅
@@blackedoutk Thanks for the answer. Yeah, I figured out that it was normal but I didn't think the drift would happen so fast especially because it seemed to work well in your video 😅. I implemented a solution using quaternion too but can't seem to figure out what to do with the derivative of the quaternion after computing it. Simply adding the derivative x DeltaTime doesn't seem to give any good results...
@@Shikinoe93 Probably because the captures weren't very long. I think I used 1ms for most of it and only 0.01 ms for the "phone" and the screw thing.
Adding the derivative x DeltaTime should work. Though similar to how only orthogonal matrices (with a determinant of 1) describe rotations, only quaternions of unit length describe rotations. So you might want to normalize your quaternion after adding its delta value.
@@blackedoutk I'm getting much more stable results now with quaternions. The previous implementation with rotation matrices would explode depending on the DeltaTime. Still not getting to the precision I need though, I don't know what more I could do to improve the accuracy of the simulation. Even increasing the deltatime doesn't seem to change much...
@@Shikinoe93 Hmm, I would need to know more about your implementation to see what might be wrong. Are you using double precision?
Yo this is just what ive been looking for! Could I ask what program you used to animate these slides?
Nice! So basically the video is a collection of images, screen recordings, manim animations for the equations and custom animations that I made in my game itself. All of these I then put into DaVinci Resolve with my voice and added some further texts, emojis and stuff.
The custom animations are also screen recordings because I didn't want to spent even more time trying to export the rendered images as a video. You can see this even at 32:49 where I struggled to remove the background from the object when its duplicate slides over 😅 But they are in game renders. Was a bit of a pain at first because I had to write the internal animation framework while creating the final animations for consistent playback, mouse handling and stuff.
I hope this answers your question. At first I was thinking about using blender for the custom animations but I wanted to use my physics code in them
Very good video. Nice job.
Thank you
Perhaps some parts weren’t too rigorous (such as the part where you exchange the derivative and integral operator, which is actually a specific case of the Leibniz integration rule where the region is constant), but it is very valuable nonetheless. Thank you! ❤
Interesting, I should do some more checking instead of relying on intuitions too much maybe. So the explanation for the factoring out isn't really correct, right?
I looked at the Leibnitz integration rule for higher dimensions on Wikipedia (it also says Reynolds transport theorem on there) and noticed that I probably should have been more specific what the x really is because it doesn't distinguish between the x of the domain of integration and the resulting x in world coordinates. But when I do that (e.g. use w(x, t) instead of x(t)) then I think the "factoring out" step still works because the velocity of the domain's boundary is zero (since it's static) and the partial derivative equals the total derivative again because x doesn't change over time.
Really appreciate your remark thank you, and I'm also happy you still think it's valuable. Now I'm curious, are you a mathematician?
What course do you recommend to learn that? whether it’s a book or an online course, with the required topics in math or physics?
hm it's hard for me to answer because there isn't one specific book I read or course I watched, rather it's small bits from everywhere. one commenter said the first half of a transcendental calculus book should be sufficient for anybody looking to learn. but I can't verify this. definitely a bit of calculus, linear algebra, numerics (ode and linear algebra) and a mix of calculus and linear algebra, so multidimensional calculus, where you learn about the jacobian matrix. maybe the "essence of" series by 3blue1brown is a good start?
what simulation platform did he used?
I know that he's using c/c++ for the lang, but i wanna know the simulation platform
I use some libraries like SDL for window and input, stb image for image loading, ImGui for debug user interface and glad for loading the OpenGL functions but other than that I wrote the code myself. Or what exactly do you mean with simulation platform?
Great video, I have a question though, didn't you mention in one of the soft body videos that you can use a constraint to essentially have the effect of rigid body?
Thanks :) I don't think this would work using a single constraint, but with multiple it might be somewhat possible, like for the "rigid" cube in episode 1. Are you referring to that?
There are a few problems when using multiple constraints to make an object rigid like in previous episodes.
First, the mass properties aren't exactly correct, because you are dealing with point masses instead of a contiuous body. If you didn't tetrahedralize your mesh, the mass would even only lie on the surface of the model.
Secondly, it is probably inaccurate and or very expensive, depending on the complexity of the model and how many iterations you perform. In comparison, simulating the dynamics of a rigid body like in this episode is almost free and independent of the model's complexity (assuming the initial inertia tensor is given). As an example, in the previous episode, if the solver was perfect, the tire wouldn't have been soft at all, because I set its inverse stiffness to zero. But since I only performed a limited number of iterations, which were already pretty expensive, the tire appeared to be soft.
@@blackedoutk I see, and yes, I was referring to the cube, great explanation. Thank you very much and keep up the videos I really enjoyed them.
I'm having some trouble implementing this into a blender simulation with simulation nodes. I've been trying for about a month, I keep coming back to this video as it is describes a simulation with assumptions very similar to mine such as using only point masses, constant density, etc. I was wondering if I could send an annotated photo of my simulation setup to you through email. I know you're using c++ but the node I'm using in blender are quite simple so I'm sure you'd be able to understand them. If not no worries though. Either way thanks for this video it explains it very concisely!
Unfortunately I don't have much time at the moment, but you can still send it to the email that is listed in the channel details/info. In a month or so I might be able to take a look at it. Apart from that you can also join my discord server and post it on there if it's not something that you wish to be kept private. Maybe somebody over there has an idea why it's not working
i'm working on a physics engine for my game engine using projective geometric algebra so that rotation and translation can be combined into one object and torques just magically happen
ohh I've seen some people talk about pga but for me it seems so hard to understand. you have a good resource that is not for math wizards?
I've been trying to learn some PGA, but I don't have a good intuition for it yet. I really like how it feels, but I always revert back to linear algebra when I'm doing work.
Another problem for me is the code. Should I just be working with multi-vectors, or should I have separate objects for each element?
@@blackedoutk I thought I replied but it seems youtube ate my reply. Freya Holmer's video on why we can't multiply vectors is a good intro, followed by sudgylacmoe's videos called a swift introduction to geometric algebra and one for projective geometric algebra
@@Hector-bj3ls You generally need for physics a few types: general multivectors, motors which are the even subalgebra, bivectors for momentum and velocity, and in pga trivectors for positions. more than that is useful but probably unnecessary
@@keldwikchaldain9545 Unfortunately I've seen comments disappear quite often with youtube, it's really annoying. I remember watching this one talk about pga on youtube (can't find it right now) and it seemed to make a lot of sense but just like Hector said, I find it hard to translate these ideas to code. What datastructures to create and what can I do with them. But maybe that's because I haven't watched enough of it, so thanks for these resources
I have done something like this with joints for objects in java do you want the code to see if it is ok?
I can take a look if you want, but I am actually learning these things roughly at the same time as I am making the videos about it. So I haven't implemented joints myself and I am not sure if I can validate your implementation
To ensure the determinant of the rotation matrix remains at 1.00000 can you not simply normalize the x y and z components before applying it to the mesh? Loving the videos, i am trying to create my own N-body gravity simulation in C++/OpenGL, and have been trying to wrap my head around rotation natrices and this video helped perfectly.
That's great to hear :) I haven't tried anything to fix the rotation matrix so far, but I think that while just normalizing the axes might help, it doesn't guarantee orthogonality. So you also need to ensure that all axes are perpendicular to each other. For that you could use cross products (normalized) or something like Gram-Schmidt. But I don't know which approach works best.
@@blackedoutk The book Game Programming Gems 1 for which you find a pdf online has a chapter 2.2 on "Integrating the Equations of Rigid Body motion" by Miguel Gomez on this subject. This chapter proposes a different integration variable "q" and also some references because it claims that the rotation-matrix method introduces error and requires regular reorthogonalization.
BTW a lot of this rigid body math is also present in university level courses on mechanics, robotics and aerospace engineering.
@@richardbloemenkamp8532 Nice, thanks for sharing the resource. They use a unit quaternion q instead of a rotation matrix to avoid having to do a reorthogonalization. The quaternion just needs to be normalized after the update, which is easier. In the future I want to use quaternions too, but here I wanted to start with the basics.
I noticed that too, that rigid body math is part of quite a few university lectures. Currently I am attending a robotics lecture and a lot of the stuff I researched for this video helped me to understand some of the topics faster. They also presented algorithms that build on top of these basics, like for chains of rigid bodies with joints (robots).
Best way is not to use rotation matrices. Just use rotors. Uhhh, most people aren't educated about them, though, right? Yeah, they call them quaternions/complex numbers :d
how do u make the animations for the video, they're so well made
Happy you think so it was quite a bit of work, thanks. The equation animations are made with manim in python and the renders are from my game actually. At first I thought about using blender but I wanted to use my simulation code, so I wrote a small internal animation framework alongside of programming the animations itself. In the end I opened up the timeline in the game and hit space while screen recording to start the automatic playback. You can even see where I struggled a bit at 32:49 because I couldn't figure out how to remove the background of the object in video:D I used DaVinci Resolve to put everything together
Where do we find the c++ code?
the code is just in the video so far. but it's not much so a summary of the physics is at 41:38
30:47 LMAO "sqaure" instead of "square". That was a very epic typo
nooooooo 😭 it's crazy I scrolled through this video so many times while editing and reviewing, yet stuff like this slips through
@@blackedoutk Haha, don't worry it's so minor I barely noticed 😃
The video is still top quality btw, found this video by accident, but I think I'll check out your other videos
Always remember the hardest part in physics is it's maths
probably yes
10:25 What is bold *x* exactly? Is it like position? Position of what?
So at the timestamp you've given bold x would be the column vector of x, y and z. And because we integrate over the domain Omega (the cube) bold x is the position of every point inside of Omega
@@blackedoutk ok thanks
Humble asking, I’m not an engineer degree student, what knowledge should I learn in order to understand this video content? Calculus and Linear Algebra? If so how deep should I go?
I am actually not even an engineering degree student myself, just computer science. I think it's enough to understand the basics of both calculus and linear algebra and a bit of physics maybe but I would say having an intuition is important. Like thinking about what does a matrix represent in space or what does it mean to take an integral. And then there's a mix of the two which is also important, deriving vector functions results in a jacobian matrix etc. The latter is a bit of a matter of practice, meaning writing down and rearranging equations.
I hope this helps, it's hard to say exactly what is needed imo. I just attended the basic math lecutures that mathematicians attend and even thought that some of it was overly theoretical. Maybe because of the proofs. A lot of the knowledge comes from working with matrices and vectors like when doing a lot of graphics programming. The calc and linear algebra mix I learned because I attended some animation and simulation lectures, where you have to derive vector functions because of 3d physics and stuff
What are you using for ui, you could've put this in the description too.
U mean the gui? Looks like he's using Imgui
yes, the in game ui I made with a library called ImGui. I have more details about this in episode two. I will consider to update the description, it's a good suggestion thanks
I've read "this is an initial value problem" in so many papers, I wonder who started it and why it keeps being repeated?
Do you think it shouldn't be repeated? I don't know who started it, but to me this seems like the correct term to use
@@blackedoutk The structure of the problem is so straightforward that calling out its fancy name seems unnecessary, especially when it tends to be only mentioned once and then never brought up again.
Just a curiosity though, the video is great and I can't wait for the Quaternions to show up!
@@LarsDonner The reason I mentioned it is so that viewers have something to look up if they want to learn more about it. The problem itself may be easy to understand, but there are a lot of other things associated with it and many different, not necessarily straightforward ways to solve it.
Though I know what you mean and would probably agree with you in some other cases. I remember seeing the Schur complement being mentioned in the XPBD paper for example and initially thought it was really complicated because it looked like that on Wikipedia. After writing the derivation down step by step though, it turned out to be just some simple equation rearrangements.
At 29:57 you had Matrix1 - Matrix2 * g(r) . Then you just subtracted these Mat1 - Mat2 , ignoring that second matrix is multiplied by g(r). Is this legal? If g(r) is constant then at least it should be M1 - M2*g
Ok, my bad - I can see it's more like [ M1 - M2] * g(r)
@@bartoszstyperek6306 Yes exactly. But you‘re right, I should‘ve included brackets there, thanks for pointing that out. I was thinking about the rho to be associated with the dV
Yes!
🎉
Hi, im currently learning phyiscs, math and i solve c++ problem solving and now i came across few physics simulations and i would love to learn it my self what framework do you use?😊
Hi, in my game I am using SDL for windowing and inputs, glad for loading the OpenGL functions, Dear ImGui for displying a debug gui and stb for loading images. I have a very basic version of the program on my GitHub in a repo called cg-papers if you want to try it out
@@blackedoutk Thank you so much, i appreciate the help. best regards :)))
What tool do you use for this simulation?
Basically the SDL library to create a window and handle inputs, OpenGL to render (with the glad library to load the OpenGL functions), the ImGui library to create a debug user interface and a bunch of C/C++ code that I wrote. The program started pretty simple in my first episode, if you'd like to see
Edit: Forgot to mention the stb image library for loading images
5:39 LOL 🤣🤣 Evil libraries
😬😬 boost is trauma inducing right 🥲
@@blackedoutk true!
Instead of using a rotation matrix could you define a set of pure quaternions x,y,z. Where the components of these pure quaternion encode an angular velocity vector for them. After which you multiply the vector component by delta time and then perform quaternion multiplication. Then you add the result of a new delta rotation to the current rotation of the ridged body?
Example of an arcade way.
void QuatApplyYaw(float DeltaTime) {
float NewYawSpeed = YawVelocity.Z;
float YawSpeedCoeficent = NewYawSpeed / MaxYawSpeed;
float YawAccelRad = FMath::DegreesToRadians(MaxYawAccel);
FVector AngularYawAccel = FVector(0.0f, 0.0f, YawAccelRad * GetLastYawInput());
FVector YawDrag = FVector(0.0f, 0.0f, YawSpeedCoeficent * MaxYawDrag);
YawVelocity += (AngularYawAccel - YawDrag) * DeltaTime;
FQuat AngularYawVelocity = FQuat(0.0f, 0.0f, YawVelocity.Z, 0.0f);
YawQuat = FQuat(AngularYawVelocity) * DeltaTime;
}
Then you take it this and stuff into another Quat
FinalQuat = FQuat(RollQuat.X, PitchQuat.Y, YawQuat.Z, 0.0);
WorldDeltaRotation += WorldDeltaRotation * FinalQuat ;
is this a correct approach?
Hm, so what exactly are you trying to achieve? You can definitely replace the rotation matrix by a unit quaternion, but why do you want to use x, y and z quaternions separately?
@@blackedoutk When I initially coded a plane game I had to obviously deal with Gimbal Lock issues. When I visualized it in my head I imagined Unit Quats for the yaw pitch and roll. Then the final rotation would be the composition of those quats. The reason I separated I guess was because I had different inputs for Yaw Pitch and Roll. So I wanted to control angular acceleration per axis using just a quat for each axis.
@@julianpopa-liesz3345 So I think for implementing the physics of a rigid body using multiple quaternions is not the right thing, just use a single quaternion and accelerate using torque. However in some cases like for camera control it might make sense to use x, y, z quaternions to describe delta movements. But I would still store the orientation of the camera as a single quaternion.
I hope you understand I don't have the time to understand and assess the correctness of your code. Just one thing I noticed, to apply a quaternion to another one you can imagine them to be like a series of matrix multiplications, so apply the newer ones to the left of the old one (using the quaternion multiplication operator of course) and then don't add, just assign, meaning TotalQ = QuatMult(DeltaQ, TotalQ)
@@blackedoutk I agree with you fully for rigged body its a bit different. One thing I might add if you do go down that route which I've been looking into and trying to understand the precision from taking derivatives and Integrals of Quats. More specifically the best way to apply a delta over time. It gets into the weeds with Lie Algebra (since you're taking about tangent space for Unit Quat of the hypersphere) but for computation, the question is what would the best way to apply the final rotation in a error free manner. Apparently taking the k=1 Taylor series is enough to approximate the orientation delta when doing the integral. So I found out two ways you take the integral, You can Multiply the quats to the final orientation or multiply then add. The issue with the addition path is you really need to normalize the quat every iteration because there is error that accumulates overtime. When I get the time I will be testing this to see what the best way to apply the discrete steps should be.
Assuming a spherical cow 🐄 we can see it's very easy to understand 😂
😂😅 so, not easy to understand?
@@blackedoutk it's for people who got into the mythical math school, and understand the arbitrary kabbalistic notation and symbol.
It took me a while to understand than 3d matrix were just 3 or 4 vector literally duck tape together. Most concept are simple but damn if math people got years of brainwashing about poorly thought notation. Proof there is equivalence between math and programming, technically they are the same thing, but it's way easier to learn programming than math, and programming can surely be improve more.
@@timmygilbert4102 Interesting, do you have other examples of math notation being poor? Not that I necessarily disagree, just curious. A matrix being a series of vectors in space is probably the best inution in many cases, but for example like the undecomposed inertia tensor it's hard to make sense of it when just reading it as its 3 column vectors
@@blackedoutk just an opinion but basically all if it, we can probably redesign number to more intuitive, like actually representing of the quantity, like actually many number system beside the Arab numeral we use. It's been proven these alternative are better cognitively. Redefining naming convention to not be the patronyms of mathematician would help, I know it's about showing appreciation for people who help discovering the math principles but I'm doing math, if I need to learn history I'll use the proper course. Also all symbol were basically randomly chosen on a whim and barely represent what they are doing, even if I'm comfortable with big pi, Big sigma, and integral schwa, doesn't mean they aren't arbitrary.
Proof is that programming is the little twin brother of math, and started with the same convention, but quickly diverge toward sanity, loop, function, variable, clearly spell what they do and avoid ambiguity and arbitrariness. And when mathism come biting back, like with adoption of functional programming, we clear the nerd and their monoid, morphism and functor, to replace it with clear explanation like 'do not have side effect in your damn function'. These functional programming term aren't even hard, category theory isn't even hard, the hardest part is to remember which terms map to which concept in an insane cascade of arbitrariness that prevent making connection across discipline sharing pattern.
Fir example, the AI hype is making everyone nervous to appear not smart enough to understand what's going on, so people cling to term as a replacement to understanding, oh it's a Markov process, congrats it mean nothing, a computer is a Markov process when observed from outside, that say nothing, it's s stack of matrix tensor, so is my Photoshop drawing what's the point? Arbitrariness if term came as a crunch to socially signal you recognize reference as a replacement for understanding, as people might not know the word despite being intelligent to process the concept behind the words. So when I try to point that, despite neural network being thought as black box, the fact they are oriented graph severely limit what can be done, especially if we realize single neuron can only perform 4 fundamental operation, we can infer general mechanism from these constraints on any observed performance or quirk. For example, chat like AI have to encode sequence, how does a DAG support this functionally, it shed light on how all of this works because there is a limited way in which you can do so, you can derive first principle to discover how neural network get their performance. But not you just have to bake hebbian and that's the end of the discussion. Which lead to people doing absurd thing like looking semantics in single network, like as if inspecting transistor in a microchip to find the one that do math, instead of figure out what an adder is, IE a network of transistor performing a function collectively. Imagine these optimisation of circuitry where a transistor reused and belong to two cluster of function, then inhibiting it people realize the chip no longer perform two operations and call that transistor 'polysemantic', that would be pure buffoonery 🤡
In what did you graduate?
Computer Science, but I only have a bachelor's degree so far, working on the rest 😅
@@blackedoutk i also have a bachelor degree, but in computer Engineering. I wanna try reading those papers too, hoping I could get through
@@claudiopisa2043 nice, computer engineering is also a bit of physics, is it? if you read the papers just don't stress to understand it all the first time, it definitely takes time and sometimes going through the equations by hand
@@blackedoutk yeah we have two physics exams, the former focuses on the basics of kinematics to mechanics, the latter is about electromagnetism. The hard part of this paper is to understand all the linear algebra notations, you need to get used to them
@@claudiopisa2043 really cool, wish I had more mechanics lectures
manim?
yes
You sound like Mr.Terminator Man
haha wait is that good or bad 😅
@@blackedoutk I like it :)
Garcia Angela Robinson Jennifer Thomas Amy
bro enough teasing. code please
@@johnhammer8668 what? the physics code is in the video
@@blackedoutk you cant copy the text in the video . duh..
@@johnhammer8668 right, but it's not that much code and if you write it yourself I believe you will better understand what you are doing
Good video, but I don't know why you spent so much time talking about density. It is not the job of rigid body simulations to compute mass given an arbitrary density function. Everyone just assumes density is uniform and mass is given as an independent variable, just like the geometry of the object.
mister Gauss making gaumes
imagine having Gauss level of maths understanding, that‘d be crazy
@@blackedoutk he would stuck at watching 3d girls)
@@bbrother92 ayo 🤨😶
wtf, i’ll never understand all of the even when i’ll end computer sience.(jk i just have to study like you did lol)
that's the spirit, also don't skip the math and simulation lectures. if you struggle to study at home try out the uni library, I like the vibe
omg
😳
Mmm math
spicy
This video still make the same mistakes that the other do, it assumes a lot from the viewer.
Sorry :/ Unfortunately I have to start somewhere, else the video would be wayy too long. What exactly would you like to have explained in more depth or which prerequisite knowledge should I not assume to be given?
OMG! THIS MAN UNDERSTANDS ME! He legit just described my whole life in the first 3 min😂.
Instant like and instant sub
hahaha very nice. the pain is real. thank you
0:20 I am glad to learn that i am not the only one who makes up all those excuses.
haha, I mean it's not even wrong is it?
Here is code for calculating mass of any triangular mesh with uniform density.
def get_volume(indices:list, vertices:list) -> float:
volume = 0.0
for i,j,k in indices:
a = vertices[i]
b = vertices[j]
c = vertices[k]
e0y = b[1] - a[1]
e0z = b[2] - a[2]
e1y = c[1] - a[1]
e1z = c[2] - a[2]
volume += (e0y * e1z - e0z * e1y) * (a[0] + b[0] + c[0])
volume /= 6.0
return volume
def get_mass(indices:list, vertices:list, density:float) -> float:
return density * get_volume(indices, vertices)
If you need Inertia tensor as well, it could be calculated at the same time with some changes.
Note: triangle winding must be CCW.
How did you come up with this? I tried to make sense of it but couldn't.
@@blackedoutk it's basically a volume integral reduced to a surface integral using divergence theorem.
@@rizohashimi Ah nice! That reminds me of the paper "Fast and Accurate Computation of Polyhedral Mass Properties" by Brian Mirtich where he uses the divergence theorem to compute the inertia tensor. It was actually the first method I tried to use, but found it to be a bit too complicated 😅
Although the volume computation you posted looks quite cheap. I wonder how it performs in contrast to the scalar triple product version
@@blackedoutk By the scalar triple product version you mean the one where you calculate volume of each tetrahedron?
What's cool about this version is with some changes it could calculate the intertia tensor at the same time.
IIRC it's from a paper "Polyhedral Mass Properties (Revisited)" by David Eberly.
@@rizohashimi Yeah the volume for each tetrahedron one. Yours has 2 subtractions more but only 3 multiplies instead of 9. But it's probably more about how simd compatible they are.
You can actually combine the inertia combinutation with the volume for each tetrahedron version as well. In fact, that's what I did. Hopefully I can talk about that in the next episode.
What maths do i need to learn for this?
I would say a bit of calculus, linear algebra, numerics of odes (maybe also numerics of linear algebra), and a mix of calculus and linear algebra, so multidimensional calculus, where you learn about the jacobian matrix. one commenter said the first half of a transcendental calculus book should be sufficient for anybody looking to learn. but I can't verify this. numerics is probably the least important of these. the most important is getting intuitive understandings of vectors, matrices, derivatives and integrals
26:20
Why is the vector on the left and matrix on the right I'm scared
Excellent! Especially because the video requires the exact amount of math I'm familiar with :)
i laughed out loud at 17:20
:D
This is not only for computer science students. works also for engineering.
That's nice. you cover it in even more detail or roughly like this?
Hey! This video just now popped up in my recommended videos. It was really good and I watched it all, understanding most I'd say. It has really helped me. Thanks a lot! I will be watching the next one(s) too.
Hey, thanks for your kind feedback. Feel free to ask about parts you didn‘t exactly understand, maybe I can help out
Thank you for this video! I've always enjoyed math and physics applied in programming.
Btw at 26:14 , matrix multiplication is NOT commutative, (AB≠BA (usually)), rather, its associative (A(BC) =(AB)C)
me too, I wish there were more videos that guide you through the details. and you're right, that's a mistake in the video. luckily I just mixed up the two words so the math is still correct. I had put this in the pinned comment, but maybe it's too long already 💀
@@blackedoutk oh sorry my bad I didn't see that comment
@@luckyizzac no worries
Nice! I'm trying to wrap my head around the XPBD paper and I newly discovered your videos, amazing work so far, can't wait for the upcoming videos! Next thing for me will be to get constraints working with rigid bodies, I'll most likely mess it up and then wait for you to explain it :D
Thank you! Happy to hear that :D Unfortunately it'll still take quite some time until I get there. If I could, I would pump out these videos weekly, but that's just not doable for me
@@blackedoutk That's totally understandable, with these kind of topics I value quality over quantity, watching a bad tutorial that makes you more confused than before is not a good experience. That's definitely not the case with your tutorials, so keep up the good work!
now do 4d
maybe in another universe:D
Please make a video (if you haven’t already) implementing the quaternion approach. That would be really fun to watch. Also great video, really enjoyed it.
Thank you :) my plan was to cover the quaternion implementation in episode 8
Thanks! I understand more less how L is conserved at minute: 38:30, but how do you apply an external force to the L. I mean the combination of the L conservation and also some forces producing torques. Thanks!
Similar to the linear motion where force is the derivatve of the linear momentum p, torque is the derivative of the angular momentum L. So in both cases, applying forces or torques for a certain time at the center of mass can be accounted for by integrating both of these and adding them to the respective momentum variables.
If you have an external force that is not applied to the center of mass, you have to apply it to the center of mass and separately compute its resulting torque by using Torque = Cross(point where the force is applied, Force) and apply it to the angular momentum too.
Does this help? I would touch on this in future episodes, but idk when I will do those