-
Notifications
You must be signed in to change notification settings - Fork 24
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvements and ideas #12
Comments
@Genbox Thank you for contacting me and expressing your interest in my fork of Box2D! I've been using the top-level REAME.md file to provide an overview of the changes that I've made in my fork. I believe it should be the file that GitHub presents at the top-level of the fork. Sounds like this information isn't as easy to find however as I'd like it to be. Here's the "run-down" that I've mentioned in that file:
I've been considering putting this information into a CHANGES file in the hopes of making it easier to find. Please let me know if you have any suggestions to this effect. Another place on GitHub where I've been documenting this kind of info is in the Projects tab. Hmm... maybe the Wiki would be even better for this. |
From @Genbox on April 6, 2017 20:38 @louis-langholtz I should have clarified. I read the list of changes you made in the readme, but I just expect there to be more hidden in the ~1400 commits you have made. There always are :) Your list is a place to start. Velcro Physics is written in C# where many of the changes you have made (namespaces, solution, global variables, non-member function etc.) is best practices, so I already did them way back in 2007 when I first ported Box2D. However, I'm very interested in rounded corner collisions, stable stacking and the physics stuff, as I think it can really improve the physics experience. I'd also be very interested in the unit tests you wrote (wow - 400 seems like a lot). I am a big fan of formal verification, and I always planned to have code contacts implemented, but since Microsoft pretty much killed it along with XNA (the framework I used for drawing in Farseer Physics Engine), I have to fall back to comprehensive unit tests instead. |
Thank you for the clarification. Eric Cato wrote about the mathematics he used in publications that I've read which have impressed me. I'd like to do the caliber of formal mathematical analysis that he's done but I'm afraid my math skills right now aren't up to his level (particularly in regards to differential equations - ODEs and PDEs). If they were, I'd love to relate what I did regarding rounded corner collisions and other physics stuff that way. I have made some posts in which I discussed the physics changes in what I suppose could be called more like "layman's terms". My posts haven't been comprehensive either as really I've been having a blast working on evolving the C++ library into my own vision for it and haven't paid much attention to documenting about it; perhaps at least not as much as I should. What do you see a conversation about the physics changes looking like or what would you like that to look like? |
From @Genbox on April 7, 2017 22:43 I guess I will have a better idea once I dive into the code and dig up some of the changes. For now, I have to go though ALL of Box2D and synchronize my port with changes made the past 4 years. After I'm done with that, I'll come back here and take a deeper look into what changes you made. As for the formal verification, I'm much like you. Eric is on a level I can only dream of, so most of the formal verification will be against a specification based on behavior rather than the math. It is more setting up some constraints on what input/output a method works with, and then have a static analysis tool sit in the background and analyse if you break those rules at any point in time, while developing. |
Just an FYI update to this thread: I just added compile-time support for strongly-typed physical units. So no more needing to guess what the units are supposed to be for any given functions (unless they required unit-less, a.k.a. dimensionless, value like ratios). So for example, if the function or method took a length, it now takes that parameter as a |
From @Genbox on April 13, 2017 11:0 Are those some sort of type constraints in newer versions of C++? I mean, like functional languages where you can define an integer to have only the numbers from 5 to 10? |
This new units interface places no restrictions on the range of the values; only on the types of the values. That said, I've also been working on ideas and code for doing range restrictions. Some of which is already in place. Like for iteration count types such as |
From @Genbox on April 13, 2017 22:17 I've just stumbled upon one of the things I made this issue for. Since the engine itself would never give an AABB in the wrong order, I think it would be for the better to implement it only for user supplied data for performance reasons. |
From @Genbox on April 13, 2017 22:32 I only now notices that Box2D never uses the constructor itself, only user supplied data goes in the constructor. |
Is there an improvement you have in mind for the AABB class then? I'm not sure that I understand your last two comments about the AABB implementation/design but would like to be sure. :) |
Just looked at the use of the AABB class more. Yes, there are places in the code where the AABB gets initialized with already minimized and maximized points only to have the constructor recheck that to ensure it's invariant about that. I am updating the AABB interface to avoid this recheck while still being able to enforce the invariant. |
Update: with commit d361c51, I've just introduced what I consider a major change to the By design, this change does away with need of "ghost-vertices" at least for level surfaces. For a tutorial on what "ghost-vertices" are and why they were necessary see iforce2d's Box2D C++ tutorials - Ghost vertices. A shortcoming with the "ghost-vertices" solution was that it only solves the polygon getting stuck while being dragged across chained edge-shapes problem. It doesn't apply to dragging a polygon across a level floor made of rectangles for instance. The new manifold calculation mechanism though solves this problem for any shapes forming a level surface. |
Commit a952a62 introduces vertex-radius respecting |
From @Genbox on April 30, 2017 9:28 Wow Louis. I have a couple of questions:
|
From @Genbox on April 30, 2017 9:44 I tested the performance of different line intersection algorithms, I found that it is sometimes faster to do a quick AABB check before the intersection code. The AABB check is just a couple of range comparisons compared to at least 2 div instructions and sometimes sqrt. It might be different with C/C++ compilers though which are usually more aggressive in their optimizations compared to C#. |
I'd love it if he was/is interested in this! I don't know how to contact him about my solution. Should I just post something about this on his Box2D Forum pages? I'd started a thread a while ago related to this but it was an open question and got no responses.
Glad you asked! Yes, radius had been used mainly for the "CCD". Inconsistently. Some shape-shape collision handling (like in I'd changed how radius was handled so that it's always treated as a circular concept for CCD and collision manifold calculations in terms of separation distances. The "vertex-radius respecting I think this is easier to understand when the radius is in the visible size range. Imagine an Here's an image of a triangle ( The commit that introduces vertex radius respecting More generally speaking... An admitted potential downside of this, is more calculations getting done per world step. I've also changed the internal algorithms however and intend to make more optimizations that should in the end be faster at least in some ways. The upside, though, for me, is really exciting! One of these upsides, is like you've recognized, the handling of bodies getting dragged across composite surfaces without getting stuck and without the use of "ghost-vertices".
That's really cool to me that you're looking at my changes in terms of the refactorings they're doing!! Regarding
So instead of calling something like:
The code now calls:
Or potentially:
Where this The advantage to me, is greater re-use of code and looser coupling. I was able to toss away the shape specific This looser coupling, extends also to the manifold calculating code. Instead of dealing with contacts as contacts between a chain and circle or edge and polygon, my code more simply just deals with contacts between the two children as With contacts all being handled as between children (instead of being between shape types), down fell the need for the shape types enum. So that's gone now too with a Visitor interface to replace it for stuff like serialization (the dump code), and the |
From @Genbox on April 30, 2017 21:17
As I see it, what you have going here is a nice testbed for experimentation and you can make the code to your taste. I've done the same thing with Velcro Physics, but mostly outside the engine (utilities, micro-optimizations, etc.), It is not interesting to backport into Box2D. However, what you have here are improvements to the engine itself and could solve some of the issues people are having out there. As you know, with engines like this, performance is everything. As long as the algorithms (SAT, dynamic tree, newton integration etc.) are the same speed or better, then people don't really care. All they see is a black box with some knobs and switches they can play with. I love that you have made an alternative solution to the ghost vertices problem - it might be slower and have problems on its own, but it is worth doing in a testbed like your to see what potential it has, and once you have tested and benchmarked it, it would be a really nice thing to backport into Box2D. You literally have hundreds of changeset, and users don't care about most of them, so I think the best course of action here, is to do some test/benchmarks, and then fork a clean Box2D, to which you port the changes. That way, people can easily checkout your version, compile it like they are used to and just copy&paste the new DLL into their game. |
From @Genbox on April 30, 2017 21:29 As for the refactorings and cleaner code, I'm all for it. I love good separation with clean boundaries that can still be fast and flexible. The stuff you have done with simplifying shapes, manifolds, and raycast is the same thing I'm currently doing, I'm just waaaay behind you since I barely just started again. That being said, I don't pretend to understand many of the changes you have made, which is exactly why I created this issue. I like your explanations and level of detail - it really helps. |
Another new improvement: commit 04f9188 adds "early out" processing to velocity constraints resolution. |
Commit 2fe4135 brings support for any/all shapes:
I.e. I've added support for selectable and dynamic, chain and edge shapes. |
From @Genbox on May 29, 2017 20:42 Selectable and dynamic? What kind of sorcery is this? |
@Genbox Not sure what you mean but hope the new changes are exciting! ;) In case, what I meant by selectable isn't clear for everyone... it's whether the As for "collide with any/all other shapes"... I had also added |
With commit 1988b9e I've added full deep copy construction and copy assignment support for |
Guys, I didn't read the whole discussion, but there is some awesome stuff here! What are your opinions on multi-threading, and hardware acceleration (both on CPU and GPU)? I'm personally using Chipmunk not only because spatial hash proved to be a better optimization, but also because of the multi-threaded solver which along with the overall optimization of the engine is capable of outputting manyfold faster results compared to Box2D. These days the 3D engines are going GPU for acceleration, neither solution is robust though, Bullet has that in the works since forever and it's still far from mature, however, Bullet got that planar 2D stuff which allows you to simulate 2D physics I assume without some terribly inefficiency or other caveats (sim quality of 3D constrained to 2D used to be terrible), so I wonder if this will still be relevant once they roll out Bullet 3 which I guess will certainly suppress Box2D a lot in the indie scene. On a related note, it's too bad that it's not easy to point all the Box2D users here... Box2D isn't collaboration friendly and honestly is quite dead at this point. This should be much more popular :(. Even LiquidFun which is unmaintained and buggy to unusable levels is popular as heck, while PlayRho has only 7 stars so far :(. |
Also, what about allowing access to some advanced configuration like the Baumgarte scale (and provide good defaults and examples) as you have in Unity. I don't like Unity but they got some stuff right imho... and their "2D Physics" is for some reason much better than Box2D with the same timing and iteration settings, probably because those vars are fine-tuned. Massive stacks for example are way more solid and much less 'springy'... there's way less penetration, and overall the simulation runs much faster too because since there's less penetration there's less overlapping thus less contacts. |
Also, fluid simulation like LiquidFun maybe :P... just dropping random thoughts here :). LiquidFun is SIMD'd but has some pretty serious showstopping flaws |
@Genbox SPH makes the most sense to me. I did a project on CFD in video games a few years back comparing the different discretizations and SPH seemed to be the most stable, and produced the most visually appealing results. As part of the project I got Intel's TBB up and running and ran the samples (I think they're included here). There's also an in-depth 19-part blog series on the physics and code which starts here. I only went through the SPH discretization for that project, so I'd need to take some time to review it. That being said, that was 2013, and I things may have changed since then, and I'm more knowledgeable as well. As a university student, I have access to much of the literature. I can't share most papers with you (legally) but I'd be happy to do some rooting around in the literature and online (probably ~2 weeks or so) to see what the most promising methods might be. I gotta get myself familiar with the PlayRho code as well. I'll make a new thread to summarize my findings, but if you want to start one sooner with your thoughts and ideas please do. |
@NauticalMile64 You just ruined my evening movie in favor of some reading 👍 good stuff! I'm not associated with PlayRho. I'm just curious about all the awesome stuff @louis-langholtz is doing, I have a Box2D port written in C# over at Velcro Physics where I play around when I'm bored. However, I will be monitoring this thread closely as always. |
The
|
The manifold solver is indeed made to support 1 & 2 points to support stacking. I remember a presentation Erin did 10 years back where he discussed how solving 2 points was basically the same as 1 point due to the algorithm used, but provided a lot more stability for stacking. I don't remember the nitty gritty about how manifolds are created, and don't have the code in front of me - are you sure they are created when there are no contacts? Seems like a waste. |
I found the presentation. The part about determining contacts and manifolds is not in the slides though. |
@Genbox Looking at the Box2D sources, specifically collide functions like I don't know if single points of contact can be made to be as stable as two points but I want to eliminate as much branching as possible that goes on with manifold usage and I want to shrink its memory usage too. Secondarily, I want the manifold class (a I'd love discussion about this. For examples... There's really no need to have the contact point count for instance be its own 4-byte We could also just use zero values in a 2nd manifold point in cases where there's only 1 actual point of contact. That would save on needing to branch based on the point count. Not sure if this would foul up the block-solver though but it's something I've been thinking about. |
In terms of improvements and ideas, while perhaps ancillary to physics engine/library ideas/improvements, but still important in terms of giving users increased understanding of what's possible, I've just yesterday added a new Entity Editor to the Testbed (via pull request #188). Here's a screen shot of it in action on the Joints Overview Test: |
Hello. I've been following the discussion here but I honestly feel they're a bit beyond my understanding, I don't fully understand that manifold talk, but regarding stability, I use the Nvidia PhysX library for 3D physics and there are some flags to enable some tricks for stability and sim quality, most notably "adaptive force", "stabilization" and "average point" may substantially improve the results depending on the use case. Not sure whether that means anything to you but just wanted to point that out in case you're wondering if any of these methods yield usable results for real-life applications. |
Latest improvement: blowing away the between 0.1 to 10 meter rule... now supporting literally 1 to 1 Solar System scales for movement and collision handling. I feel very excited about that! Build with |
So is it possible to have scenes the size of our solar system while still having precision for human-sized characters just by using doubles? I could be wrong but last I checked it wasn't possible to do that naively not even with double precision. |
Yep, the fanciness ends when the relative scaling applies. The problem of meter rule is that ratio of smallest 1 to biggest 100 works okay, but objects exceeding this range disrupt stability of the simulation (performance problems, staggering, etc). So scaling linear slop and stuff to match the size of planet is okay, but that is not the solution to the root of the problem. Yet double precision seems to help a bit. I think some code could be integrated to solver so that big objects ignore small ones (act as kinematic) while small objects are blown away by big objects, this could help with artifacts during such interactions. And together with that you could try resolving small object collisions with lower slopping and stuff, so that double configuration is applied. But that probably leads to a size-relative configuration model of slopping (k*S + c). Probably need to experiment with this. __ Also wanted to note that an option (#define or smth) to disable vertex radius collision would be priceless in scenarios where performance is extremely important as it is the only extra functionality of playrho that you pay for with your very blood. |
I love this question! Please correct me if/where I'm wrong... I believe the answer ultimately comes from what's possible in terms of numerical fidelity of whatever type is being used for the In the scenario you're asking about we have some 2 meters at one end of the size spectrum and 696342000 meters on the other. Roughly 8-orders of magnitude difference in decimal digits. IEEE 754 single precision binary floating point format has as little as 6 significant decimal digits precision. Meanwhile IEEE 754 double precision format has at least 15 significant decimal digits precision. So looking at these types, I believe the answer — at least theoretically — is a solid no for In practice however, I suspect many interactions between human sizes and Sun sizes even with As I believe Hexlord is pointing out, using alternate notions of collisions or alternative solutions for collisions is another avenue to pursue for handling such situations. Right now, I see collisions as being dealt with from a third party perspective; that of the viewer. Depth of penetration for TOI calculations or the linear slop value for instance are absolute values that make the most sense to me when a viewer is viewing a scene at a scale relevant to those values. I can imagine using relative values instead like a percentage value for depth of penetration (vs. the total radius) that would have more robust handling characteristics in perhaps more dynamic collision scenarios however. |
😄 and I loved your answer! I agree with you and @Hexlord. Although it would be nice to be able to simulate such huge spaces and high scale/mass ratios, perhaps there are few use cases for that, especially considering that you'll probably need a high number of the smaller objects to populate such large areas in an interesting way, so having all of that running simultaneously probably is a going to be a problem bigger than precision, it's probably going to take some time until we can have those scenes naively without tricks/hacks. Perhaps at that time 128bit floats will be commonplace, I guess even these days one could achieve decent performance using SIMD 128bit registers (could be 100% wrong here), but then again, it doesn't sound something very practical, although it could surely be interesting and useful for some edge cases. |
dynamic/relative penetration/slop sounds nice. maximum usable scale differences are of importance to me at least - and proper interaction between something human-sized and possibly moon-sized (or at least multiple magnitudes larger) sounds awesome. i'd gladly trade performance for possibility in that case. |
I've seen some interesting idea in gpu-physics.js by schteppe: gif maybe interpreting small objects as radius-vertex geometry instead of volume geometry when interacting with big objects can ease resolving the conflict, maybe even consider a group of small objects as an area-rectangle interacting with big object, but that for sure will require lots of nancy stuff, just the extra thoughts. Relative slop & penetration may help, but the performance hit is still tremendous for TOI when huge asteroid of 500 fixture-triangle geometry flies upon 100 tiny triangles. I know very few how this stuff works, but the TOI not being optimized for multiple contacts incoming is an experimental observation as it lags all the way since small stuff is radius-close to the big object, that's when TOI starts to predict solving equation or something. That is not a very common scenario yet it happens. |
@Hexlord performance hit: huge astroid could be represented by single/few chain shapes or chained boxed just representing it's surface. worked way faster for me when doing some tests with box2d a while ago. and the 100 tiny triangles, should they all be of equal size, could be done using particlesystem like in liquidfun. if it's 100 unique objects, i guess that'll be slow(er) even without any astroids around. |
@ninnghazad yep, but chain shapes do not support holes. triangles are just the result of triangulation of geometry with holes, so liquidfun solution sadly won't work. 100 small objects work just fine if they meet small objects like eachother... Well that seems to be quite another problem as one mentioned before, yet still. |
Incidentally, I've been considering what it'd take to implement a "negative" of a shape for implementing holes. I'd like that very much as we could for example have an inner disk (circle) shape be the negative of an outer one and have fully round rolling without jagged approximations. I believe that the plausibility of negative shapes has some corroboration in the implementation of the false condition of the joint collide connected property. It may be a while to implement negative shapes though since I first want to refactor contacts and joints into being subclasses of a constraint base class and then develop a better understanding of how ordering effects simulations. Ordering I can see then begetting constraint hierarchy which seems necessary for negative shapes. |
@Hexlord Help me understand what you're describing in:
Do you mean simulating only velocity and acceleration and not simulating collisions? If you could reference specific code perhaps, that'd help me a bunch! Also, it's absolutely critical to make sure that we're using a release build of the library — i.e. with compiler optimization enabled to the fullest ( |
@louis-langholtz Sorry for my puzzling description of what I mean. I did not inspect the new code very precisely, but it seems like some checks are unavoidable even if all vertices of all the bodies have 0 radius, slowing the performance. They seem relatively cheap for 0-radius case, but still that is the only misstep from max-performance way, so that probably should be optional (#ifdef PLAYRHO_VERTEX_RADIUS or smth). I support run-time configuration, but this functionality is high-load and four if-s can really mess the cpu performance... |
@Hexlord I agree that four if's looks concerning but how concerning is it on a given hardware architecture in terms of reliably measurable performance loss? I ask because I don't know. My hope is that the Benchmark application will be increasingly used to measure these places (by calling the existing routines) and also to measure alternative coding strategies. Alternative functions can be added directly within the Benchmark itself to start with and possibly get migrated into the library as they prove useful. In terms of preprocessing out some of the Incidentally, what I'm more sure of is that I really dislike the length and complexity of the As another related side note, the alternative method for detecting almost equal that you'd provided for instance showed itself to be faster (which I saw after I increased the sensitivity of many of the tests in the benchmark application). It or the almost equal related unit tests however need some tweaks worked on since they don't match up exactly and can only be used on platforms where float and double are is_iec559 compliant I believe (in case you're interested in that 😄 ). |
@louis-langholtz Actually if you always use zero radius that would be just one tick thanks to prediction, so not a problem at all... Cool stuff! Could be an experimental feature, but probably its win is not considerable in the whole simulation. |
Just for reference, I'll note that Algodoo gives the ability to use shapes to clip one another, kind of like Snipperclips. Closed source code though :( |
@NauticalMile64 yes but it converts those clipped shapes into polygon shapes, so basically it's just a way to edit polygon shapes; internally it doesn't support a colliders described by booleans I think (I'm pretty sure). |
Hi, it seems flipping (vertically) bodies in Box2D is an obstacle for many users, since its quite common for 2D games with a side perspective. I did recently came into this problem, which feels like a dead end for my project. Imagine I have an excavator with multiple joints (wheels and a boom, which has a bucket jointed to it). If its facing a direction and then wants to move the other way, it has to flip/mirror/reflect vertically. Currently, the only solutions are quite complex. Recreating all the bodies, shapes, fixtures and joints, plus all the joints' bodies. Or having pre-created bodies of both directions and "hide" one of the direction from the Box2D and switch when a flip needs to happen. I was wondering what do you think about this and if a feature to simplify this would have a chance to be implemented. It would really help us less experienced users and may be migrate more Box2D users over to PlayRho. |
@iderik Hello and thanks for your suggestion! Here's some thoughts that come to me at the moment regarding your proposal. The flipping that you're asking about sounds in part like a reflection transformation matrix applied to the coordinates of the shapes in order to derive reflected shapes. A free function operating over an iterable range of shapes that mutated those shapes per the transformation sounds doable and appealing to provide. This could probably benefit from extending the Reflecting joints sounds like another part to what you're asking for. I think it'd be a more involved than the former part of this and probably has to be done on a joint type by joint type basis. I've been considering a redesign of joints to replace the use of public inheritance with the same kind of on-use polymorphic design that I suspect the overall functionality would still need to effectively do the complex solution. I like the idea of providing free function code that takes care of those details however so to the user this at least looks simpler. |
I've just merged in pull request #346. This introduces some new changes that I'm very excited about and greatly improve this library in my opinion. Here's a partial list of these improvements:
|
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
From @Genbox on April 2, 2017 11:46
Hi Louis,
I've seen you active around the Box2D project, and it seems like you are keen to improve it and add features. I'm working on Velcro Physics, which is a Box2D port in C#, but extended with many new features such as path generators, better performance, concave polygons etc.
I'm interested in your port as it seems like you made some improvements and new features, but I have a hard time going through hundreds of files and look for them, so could we have a discussion here on what improvements you have made?
Copied from original issue: louis-langholtz/Box2D#12
The text was updated successfully, but these errors were encountered: