erincatto / box2c Goto Github PK
View Code? Open in Web Editor NEWLibrary for 2D Game Physics
License: MIT License
Library for 2D Game Physics
License: MIT License
I'd like to recover as many of these as reasonably possible. In my engine, I've specifically wrapped all joint getters and setters from v2.4 in the scripting engine, in order to easily monitor and variably configure joints, based on a variety of different gameplay conditions. Additionally, I have some joint configurations that are designated as renderable in relation to their connected bodies; in these cases I recover even the generic joint data like the local anchor points and transform them using an array of body transforms, which are adjusted for visual interpolation.
I probably can't make a proper use case for getting and setting every single joint parameter at this time, since I've focused more on engine development than the creative process, however I think joints are where Box2D really shines and I wanted to express a desire to see that level of control make its way back. I figured it would also be easier to ask for another pass and then fill in any remaining blanks from there, if that makes sense.
A few examples that have popped up thusfar would be like b2DistanceJoint_SetLength, which takes all 3 length parameters, but if say only minLength needs to be changed, there is no way to recover what the other two were. b2DistanceJoint_SetTuning is in the same boat. There are also no functions to check or adjust a weld joint after creation.
EDIT: I'd also like for joint user data to return if that's reasonable to do.
doubly linked list?
update mass properties incrementally as shapes are added/removed.
Avoid callbacks if possible.
Doesn't exist in 2.4.
Seems to be broken and causing performance issues.
Starting with my needs for godot-box2d which integrates box2d into godot. Godot has its own physics system that has an API that needs implementing. With box2d this was possible, but in box2c some functions are missing.
- b2Body_SetFixedRotation() // be able to set fixed rotation of body after it's created.
- b2Body_ForceSleep() // force a body to sleep. I used to call this after making a body static. Not 100% sure if it was needed, but nice to have since there is a wake function as well.
- b2Body_GetBullet() // get if a body has ccd enabled
- b2Body_SetBullet() // set if a body has ccd enabled
- b2Body_IsSleepingAllowed() // get if a body is allowed to sleep
- b2World_GetBodies() // some function to get bodies in the world. I use this to go through all bodies and check which of them moved so I can call a callback on them and mark them as active bodies. There might be a better way to do it, not sure.
Haven't went yet into setting callbacks and other things, still wip, but these are just a few. I will add more as I advance.
Apparently drawing 15k circles can get slow on a mac.
This is my fork which I build on Arch linux x64. Core library does not require changes in CMakeLists.txt
but samples are trick.
Prerequiments:
➜ box2c git:(main) ✗ lsb_release -a
LSB Version: n/a
Distributor ID: Arch
Description: Arch Linux
Release: rolling
Codename: n/a /0.0s
➜ box2c git:(main) ✗ gcc --version
gcc (GCC) 13.2.1 20230801
...
➜ box2c git:(main) ✗ cmake --version
cmake version 3.27.8
...
Build command is cmake . && make -j
that gives the next:
In file included from /home/nagolove/tmp/box2c/extern/simde/x86/sse.h:34,
from /home/nagolove/tmp/box2c/extern/simde/x86/avx.h:28,
from /home/nagolove/tmp/box2c/src/contact_solver.h:9,
from /home/nagolove/tmp/box2c/src/island.c:10:
/home/nagolove/tmp/box2c/extern/simde/x86/../simde-f16.h:96:11: error: ISO C does not support the ‘_Float16’ type [-Werror=pedantic]
96 | typedef _Float16 simde_float16;
| ^~~~~~~~
In file included from /home/nagolove/tmp/box2c/extern/simde/x86/sse.h:34,
from /home/nagolove/tmp/box2c/extern/simde/x86/avx.h:28,
from /home/nagolove/tmp/box2c/src/contact_solver.h:9,
from /home/nagolove/tmp/box2c/src/contact_solver.c:4:
/home/nagolove/tmp/box2c/extern/simde/x86/../simde-f16.h:96:11: error: ISO C does not support the ‘_Float16’ type [-Werror=pedantic]
96 | typedef _Float16 simde_float16;
| ^~~~~~~~
cc1: all warnings being treated as errors
make[2]: *** [src/CMakeFiles/box2d.dir/build.make:317: src/CMakeFiles/box2d.dir/island.c.o] Error 1
make[2]: *** Waiting for unfinished jobs....
In file included from /home/nagolove/tmp/box2c/extern/simde/x86/sse.h:34,
from /home/nagolove/tmp/box2c/extern/simde/x86/avx.h:28,
from /home/nagolove/tmp/box2c/src/contact_solver.h:9,
from /home/nagolove/tmp/box2c/src/graph.c:11:
/home/nagolove/tmp/box2c/extern/simde/x86/../simde-f16.h:96:11: error: ISO C does not support the ‘_Float16’ type [-Werror=pedantic]
96 | typedef _Float16 simde_float16;
| ^~~~~~~~
cc1: all warnings being treated as errors
After removing -Wpedantic
from CMakeLists.txt
building gone to work.
Taken from include/box2d/id.h various null ids are defined as {-1, -1, 0}. This has different binary representation than nullptr. Some bits are 1 while with nullptr all bits are 0. While there is no big difference in C/C++, because every field/variable must be initialized (unless you want to memset
0 the entire structure), other languages might use their own policies. For example in C# struct
cannot have custom default (no parameters) constructor, the compiler automatically provides a default constructor that initializes all fields to their default values and these are 0 for int
/uint
. So with C# binding, the current approach would be much more cumbersome to use and error-prone because you couldn't rely on the default compiler behavior.
Pass back the whole shape for custom rendering.
The stack allocator should be grown each time step when capacity has been exceeded. I can still report the needed capacity for optimal startup.
In v2.4 I was able to iterate over the fixtures of a body, getting AABBs from the shape, agnostic of the shape type, since ComputeAABB was part of the base class. Now it looks like the only path to replicate this behavior is to use the shapeID to get the type, then switch case that to use the shape specific compute functions in geometry.h after also getting the geometry pointers.
It looks like b2ComputeShapeAABB already exists, but isn't exposed for the user. I think it would be nice to be able to get an AABB from a shapeID and transform in a similar way.
Additionally, it would be nice to have some of the AABB helper functions back. In this same case, I would use Combine with each of these AABBs to create one large "body AABB" which I would then make sure was usable with IsValid. I'm also missing GetCenter, Contains, and b2TestOverlap.
Hi Erin,
the FinishTask function is not checking if the task pointer is null and returning if it is, which can occur if the task array is full.
https://github.com/erincatto/box2c/blob/main/samples/sample.cpp#L52
Also, I think a good idea is to add a ParallelFor function to Box2C. This is a common practice I think. With enkiTS, ParallelFor can be implemented by a enqueue function followed by a wait for task function. This is good because it doesn't add to the task array and since (I think) enkiTS scheduler is thread-safe, the parallel for function can be called from multiple threads.
Callbacks block this. Implement some samples to show best practices and get community feedback.
Use cases:
As I've been developing a game around the previous version of Box2D, I've found myself wishing for "one way joints."
The best use-case I can provide is between two dynamic bodies in a platformer-type setting. You would have a primary player-controlled "body" and an auxiliary "head," connected together with two joints: distance and revolute. The revolute joint is configured to limit how much movement the head can perform, while the distance joint acts as a spring to center it.
As the player lands on a platform, the head has room to bounce down a little bit. This looks awesome. But, since it is now pulling down on the player body, if the player were to immediately jump again, the force of the joint pulling on it would reduce the next jump's height.
Since this particular set up of joints is entirely based around the effects on only one of the bodies, if it was possible to turn off the joint effects on the other, that would be excellent. I have experimented with several practical ways to try to get around this, but each seems to have its own caveats or produces a different result.
I figured I would request this early, since I would imagine that it would require adding some bools to the joint defs and that would be less API changes later.
Currently it looks like there's no getters or setters for existing bodies for linear damping, angular damping, or gravity scale.
EDIT: I'm also noticing that there are no functions for getting/setting the filter on existing shapes.
https://github.com/erincatto/box2c/blob/main/src/distance.c#L1045
Not sure if this is a temporary, but B2_MAX is not necessary in this line. Assuming totalRadius >= 0 then target >= b2_linearSlop always.
Circles move with linear speed towards a point. According to the formula below.
Similar code works fine with Box2D C++ and its ports.
There the circles never pass through each other.
auto dist_x = player_p.x/PPM - enemy_p.x;
auto dist_y = player_p.y/PPM - enemy_p.y;
auto distance = sqrt(dist_x*dist_x+dist_y*dist_y);
auto velocity_x = dist_x/distance*speed;
auto velocity_y = dist_y/distance*speed;
b2Body_SetLinearVelocity(enemy[i], b2Vec2{velocity_x , velocity_y});
map a buffer and have multiple threads write to different sections
have one large draw call from that buffer
https://docs.gl/gl3/glMapBufferRange
what you need is glMapBufferRange to map a buffer with circle transforms
https://docs.gl/gl3/glDrawElementsInstanced
glDrawElementsInstanced, draw 1 instance per circle
have 3 buffers
1 index buffer with circle indices
1 vertex buffer with circle vertices
1 vertex buffer with one transform matrix per circle
map the transform buffer and write to different sections from threads, then unmap it
for that transform buffer use this https://docs.gl/gl3/glVertexAttribDivisor
set the attribute divisor to 1, this will map one element from the buffer to each circle instance
and then in a shader you will get this transform matrix as a regular vertex attribute
This should vastly improve joint perf by making it cache friendly.
check for finite/nan/etc
What would you think about providing a file for public apis so that other languages can write generators that can generate code which is easier to read on that language.
For example Steam provides a json file for Steamworks-SDK.
Only having a header file either requires using generic ffi-binding-generator where the yielding code is unreadable or manually parsing header file which is not great to write or writing every binding manually which is hard to maintain.
With this file it is very easy to generate ffi-bindings and create a readable code.
Example: https://github.com/aeb-dev/steamworks_gen which generates https://github.com/aeb-dev/steamworks
Be able to access the segments for bespoke distance, TOI, etc. For character mover.
Test performance before/after
I don't have a use case for this yet, but I did notice it was missing since I had it wrapped.
I would use b2World_QueryAABB
for get visible objects in work for drawing. But now I have not pointers to internal structures with polygon data, circle data etc. How it would be implemented? Or may be I did not see such in example.
In v2.4 I was able to collect a list of fixtures, and then raycast their shapes directly, without needing to know the shape type. It looks like there isn't a way to do this currently.
My use case was some basic line of sight checking for targeting. I would use QueryAABB to get everything in range of an object, filtering everything into two lists: fixtures marked as "hurtboxes," and fixtures marked as capable of blocking line of sight. Then to find the closest valid target, I would use body positions to determine a ray, and cast against anything in the "block line of sight" list; continually adjusting the maxFraction from any hits, before finally using that possibly-shorter ray to cast against the "hurtbox" fixtures to see if they still hit.
Probably not the most accurate approach, but it worked well enough for my use. With v3 adding b2World_OverlapPolygon, I am wondering if a visibility polygon approach might be more accurate and efficient. But I still think it would be beneficial to have something like a b2Shape_RayCast function. This could possibly also apply to shapecasting.
more efficient and standard practice
Right now the plugin for Godot Box2d uses a custom version of box2d that updates the categoryBits and maskBits flags to be uint32. https://github.com/appsinacup/box2d/pull/1/files
Would be nice if box2c could support uint32 for these flags.
Often users desire to change a shape at runtime. Make a sample that shows how to do this.
I am currently working on creating automated C# bindings for box2c at this repo Box2D.NET. Most C# bindings generators do not support generating constant structs like this one below.
static const b2Filter b2_defaultFilter = {0x00000001, 0xFFFFFFFF, 0};
It is left up to the user to initialize the default values manually because of these limitations. Right now I have handwritten extensions that provide the default values but these are error prone and will become outdated if box2c adds/modifies/removes any members from these structs.
It would be great if box2c also came functions that could provide default values as an alternative to using the const structs. Maybe something like b2_MakeDefaultWorldDef
would be a good option? Ideally the user should be able use these functions and run the binding generator without having to worry about possible changes to the default values.
Sample repo with box2d v3/raylib/enkiTS
Make it a template?
Currently working on migrating an AABB query callback that collects all shapes in an area, and I'd like to ignore any shapes that are sensors, but currently do not have a replacement for IsSensor. It would definitely be nice to have that function back.
I was also thinking that this might also be a possibly good use case for adding another field to b2QueryFilter for ignoring sensors, since that might be useful for others as well.
After creating a joint, there's no way to get what kind of joint type it is from the ID. Before it was possible to store the base b2Joint class and use GetType; I use this in switch cases to check/modify joint parameters after creation.
EDIT: I've also noticed that b2JointType is internal, which would also have to be changed.
I've noticed that there's no functions for getting or setting the density of a shape after creation. After making changes, in v2.4 I would also use ResetMassData to make sure that the body's mass is properly updated as well. It would be nice to have these back using the new systems.
EDIT: I also noticed that there's no getter for MassData either.
It is not handling the unit test of ray vs box. The shape cast code should handle zero radius (I think).
Try combining with NGS for stress test
I know at least line 37 is incorrect, not sure if there are any others yet.
EDIT: Line 22 as well.
Keep nodes ordered by height?
I use a negative gravity scale at body definition all the time in v2.4 to make light things like bubbles float upwards, and adjust it per frame for any body in water, allowing certain objects to float. Unfortunately several assertions prevent this from being treated as a valid input, requiring that gravityScale >= 0.0f. I'm hoping this is not intentional.
It seems that a chain never gets unlinked from its parent body singly linked list on destruction:
https://github.com/erincatto/box2c/blob/main/src/body.c#L675
BTW, I really like this way of dealing with chains (just a bunch of smooth segment shapes). Do you plan to change this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.