Dirk Gregorius

  • Content count

  • Joined

  • Last visited

Community Reputation

2774 Excellent


About Dirk Gregorius

  • Rank

Personal Information

  • Interests

Recent Profile Visitors

11950 profile views
  1. Physics behind briddge constructor

    Interesting! I was sure when I read about introductions for FEM that Bridge Constructor was mentioned as an example using DSM. It is such a great use case for this method. I did structural analysis with simple physically inspired approaches, and I always got bad results. Simple geometric approaches worked good for me (e.g. to detect unstable overhangs).
  2. Physics behind briddge constructor

    I think they use the 'Direct Stiffness Method'. You can read about here: https://en.wikipedia.org/wiki/Direct_stiffness_method Really good free university course is here: https://www.colorado.edu/engineering/cas/courses.d/IFEM.d/
  3. Hey Dirk, a couple years ago I wrote an article about particle systems using second-order constrained dynamics method and you made the following comment:


    In games we usually don't solve on the accelerarion level though, but use simple first order world steppers. For particle constraints and springs we even use very simple position based dynamics. Maybe you want to talk about how to derive these steppers in future articles? :)

    My interests have taken me back in this direction, and I was curious to know what your favorite first-order method is. Is there one you consider more worthwhile than the others? I would love to take your suggestion and write an article about it.


  4. rigid body fixed constraint

    Looks nice! Let me know how it goes. From my experience convergence will be an issue here as well. Even for reasonable structures with only a few bodies. You can try warm-starting and only run a couple of iterations per step. This will amortize your costs over several frames. Be aware that the iterative solver can create large impulses in early phases (after only a few iterations). So you need to run for some time before making a break decision. I applied a low-pass filter, but that made things soft. In the end I stopped and used a connectivity graph since it felt like going circles.
  5. rigid body fixed constraint

    Looks like totally different Jacobians to me. In the first one J = ( 0 -E3 0 E ) which is constant while Randy uses the t vectors which would be cross products e.g. xa and yb. I think his equation (1) is a bit unlucky and makes it look the same though. I spend quite some time to use weld joints for structural analysis. To put in famous words of a current movie: "This is not going the way you think". Reasons are plentiful and complicated. For simple structural analysis to detect unstable overhangs (e.g. games) simple geometric approaches work best from my experience. If you need real structural analysis I suggest looking into the "Direct Stiffness Method" This is also a nice and non-mathematical entry into the world of finite elements. https://en.wikipedia.org/wiki/Direct_stiffness_method There are some really good resources I can share if you are interested. HTH, -Dirk
  6. rigid body fixed constraint

    Your expectation is wrong. You are currently using an iterative Jacobi block solver on a 6x6 linear system. Using the new angular velocities after you applied the linear impulse would get you a Gauss-Seidel iterative solver which has better convergence. Note that there is no guarantee for convergence. You would need to solve a 6x6 system for the correct analytical solution. When checking the error I would return two 3d vectors: the relative linear velocity at the pivot and the relative angular velocity. I would also print this each iteration. The error (length of each vector) should become smaller each iteration. The error would not be zero after ONE iteration. With Gauss-Seidel solving I would expect the error to be reasonably small after 5-10 iterations depending on the configuration (e.g. convergence will most depend on the inertia tensor and relative pivot location to the mass centers). One other thing. From a quick look I think the rotation constraint derivation in the referenced paper is not correct. The time derivative of the angle triplet is not the angular velocity. This is only true in 2D. Using angles for orientation is always problematic. If you use any triple of three angles small changes in orientation can result in large changes in any of the angles which gives you inconsistent behavior. You are not using a stabilization term yet, but later you need this. One solution is to use orthogonality constraints to fix the relative orientation. HTH, -Dirk
  7. How to make the bullet physics update faster?

    This looks to me as if you are taking 100 sub-steps per tick which would indeed be very slow. Usually you pick a fixed time-step like 30, 60, 120, or even 240 Hz and a fixed number of sub-steps. For games 30 or 60 Hz is a typical choice. const int MaxSubSteps = 4 const float FixedTimeStep = 1.0f / 60.0f; // Or similar pDynamicsWorld->stepSimulation( dt, MaxSubSteps ,FixedTimeStep ); I recommend checking out Glenn's post here: https://gafferongames.com/post/fix_your_timestep/ And the Bullet Wiki: http://bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World You also posted a bunch of other questions regarding dynamic mesh shape (GImpact) collision. This is usually slow since this is just a very difficult problem. I would not use GImpact shapes in real-time simulations. Use simple hulls or compounds instead.
  8. C++ 2D Math Problem

    This results from the dot product. Say you have a vector u and you are looking for a vector v orthogonal to u. You know that the dot product between two orthogonal vectors must be zero. Hence u.x * v.x + u.y * v.y = 0 Common sense shows that the simplest solution here is to choose: v.x = u.y and v.y = u.x and negate either v.x or v.y E.g choose: v.x = u.y and v.y = -u.x And you get u.x * u.y - u.y * u.x = 0 The same is true for v.x = -u.y and v.y = u.x Geometrically choosing v.x to be negative is equivalent to a 90 degree CCW rotation around the origin while choosing v.y to be negative represents a 90 degree CW rotation around the origin. This is easy to verify. You will find the same idea applied in 3D as well. Two coordinates are flipped like in 2D and the third coordinate is chosen to zero. Erin posted an elegant solution in 3D on his blog some years ago: http://box2d.org/2014/02/computing-a-basis/ HTH, -Dirk
  9. Character Solver

    I have a couple of ideas, but didn't get anything done for GDC next year. Maybe 2019 or during the Valve Steam Devdays 2018. Out of curiosity, what would be the topics you would be mostly interested?
  10. Character Solver

    I implemented Erin's code and it worked really well. IIRC I only projected a single point and the solver for the capsule is really just point to plane since the capsule is invariant under rotation around the up axis. The trick is to adjust the planes you get from the sweeps accordingly. E.g. you can choose any point any point on the capsule as reference point and simply shift the plane there. I chose the red point here, but the choice is really up to you.
  11. How to get RPY and plugin to Quaternion

    Your code looks like it takes a current absolute orientation (q_curr) and a delta rotation (q_rot) which you then combine to find the new absolute orientation (q_new). So you are missing one orientation somewhere that you have available. I can imagine that this will work something like this: // Once Quaternion m_Current = kQuatIdentiy; // Or any other reasonable initialization // Every frame Quaternion q_curr = m_Current; Quaternion q_rot = CreateQuaternion( Y, P, R ); Quaternion q_new = Normalize( q_curr * q_rot ); m_current = q_new;
  12. Extracting face/hit data after a GJK step

    After GJK returns it is challenging to extract feature information. It will provide you a separating axis which realizes the closest points. You can then use this axis to find the support faces on each shape. That means you scan for the most parallel face normal on A and anti-parallel face normal on B. You can then clip these faces to build a manifold. You would need to be careful with the manifold normal direction though. Using the witness features will be very tricky. E.g. you can get edge/edge witness features but these edges are actual diagonal across a face. So you need to make sure that you don't create an incomplete manifold accidentally. The code will become very ugly to handle all cases. In practice you would also need to run another algorithm if GJK detects overlap and you have no separating axis or witness features. As Randy pointed out you can try EPA, SAT or brute force sampling. The implementations for manifold generation that I am aware of use either incremental manifolds (e.g. find one point at a time and collect/reject in a persistent data structure) using a GJK/EPA/Brute Force method (you need the brute force fallback since EPA will fail in practice as well). Or SAT based full manifolds as I described in my two talks here. http://media.steampowered.com/apps/valve/2013/DGregorius_GDC2013.zip http://media.steampowered.com/apps/valve/2015/DirkGregorius_Contacts.pdf Both will work. I go over limitations a bit in my presentation. Personally I chose the SAT based approach because it can be implemented in one straight forward code path as compared to a GJK/EPA/BF pipeline with all kind of hoops to jump through. Also EPA is a numerical nightmare and none of the publically available implementations I am aware deal with numerical problems and would be useful in real production in my opinion. People are often concerned about the SAT performance (which is still O(n^2) with my suggested optimizations). In practice I found it really doesn't matter whether you call GJK or SAT as your primary collision routine, but what matters is that you don't call them at all utilizing temporal coherence.
  13. Circle-Circle impulse resolution not working properly

    One thing you can do is to setup similar situations both in Randy's and your simulators and step through them side by side. Or write down an analytical solution and confirm your results in debugger. The problem is that you need to debug your code and nobody else is going to do this for you.
  14. Circle-Circle impulse resolution not working properly

    That is Randy's stuff. He is on the forum here and should be able to help. I will ping him...
  15. Circle-Circle impulse resolution not working properly

    One thing I learned over the past years is that with software development in general and physics development in particular is that you want to come to a working solution as fast and easy as possible. From there you want to add one feature at a time always iterating on a working solution. You are currently seeing yourself what a pain it can be to search for a bug without having an idea where to look. If you use a smart incremental approach this helps to keep problems manageable. That is why I suggest getting the simplest problem working first and then add one feature at a time (e.g. penetration recovery and restitution). I don't know which tutorial you are referring to so I cannot comment on this. With game physics you have the problem that there are a couple of good references by industry experts and then a bunch of students essentially rewrite these tutorial for studying purposes and quite often introduce errors reflecting their lack of understanding. So when looking at in-depth tutorial make sure they are from people who know what they are talking about.