How to use dyn4j for collisions without physics

Posts that don't fit into other categories.
Pesegato
Posts: 17
Joined: Fri Oct 21, 2016 5:29 am

How to use dyn4j for collisions without physics

Postby Pesegato » Mon Oct 24, 2016 5:32 am

Hi there,
I want to use dyn4j collision with jmonkeyengine for a 2d game. I've added the boxes to the world and with physics enabled I can check the collisions.

However, I'd like to move around the boxes (in Bullet jargon, put them in kinematic mode so that they are not affected by physics law) but I don't know how to do... tried with body.move() and bodyfixture.shift(). Something goes wrong either way.

Thanks for your help!

William
Site Admin
Posts: 378
Joined: Sat Feb 06, 2010 10:23 pm

Re: How to use dyn4j for collisions without physics

Postby William » Mon Oct 24, 2016 9:10 am

I'm not up to date on the integration with jMonkeyEngine but the following should apply.

I'm guessing you are looking for:

Code: Select all

body.translate(Vector2);
body.translate(double, double);
body.rotateAboutCenter(double); // NOTE: radians


That said, to what degree do you want to limit the default physical simulation?
  • Do you want dyn4j to continue to advance the body's velocity (based on its acceleration) and its position (based on its velocity)?
  • Do you want dyn4j to continue to handle gravity?
  • Will all bodies be kinematic or just some?
  • Is "manually" moving/rotating a body the only reason?

I'm not sure what the goal is, so I'll just brain dump some possible solutions, which may need to combine:
  • Setting a body's mass to infinite turns off gravity and forces it to proceed at its current linear and angular velocity regardless of what it runs into. You can directly modify it's position and velocity. NOTE: infinite mass bodies will not collide with other infinite mass bodies and are not affected by forces, torques, etc.
  • Creating a MotorJoint which attaches a "manually moved" body to an infinite mass body will allow you to tell that body that you want it at a specified location and rotation and it will use motors to achieve that position. The nice thing about this is that the body that is being told what to do will still interact with the simulation normally (i.e. won't pass through walls and will continue to collide with stuff).
  • You can disable the collision resolution on a global or collision pair scale by extending the CollisionAdapter class and returning false from the collision(s) methods.
  • You can disable the collision resolution on a per BodyFixture scale by setting the sensor flag.

William

Pesegato
Posts: 17
Joined: Fri Oct 21, 2016 5:29 am

Re: How to use dyn4j for collisions without physics

Postby Pesegato » Mon Oct 24, 2016 11:35 am

Ok, I got the moving... but as you said, the collision between two infinite mass bodies are not detected :(

No, I don't want velocity or acceleration. I'll take care of the movement by myself.
No, I don't need gravity. Besides, my game is on space.
Currently I plan to have everything kinematic as I want to use dyn4j only as collision detect.
As I said, moving now works but collision detect don't... and I guess this is by design so I'll need some workaround :(

Thanks

William
Site Admin
Posts: 378
Joined: Sat Feb 06, 2010 10:23 pm

Re: How to use dyn4j for collisions without physics

Postby William » Mon Oct 24, 2016 1:12 pm

You can turn that default off by implementing a custom BroadphaseFilter and assigning it via the World.setDetectBroadphaseFilter method. The DetectBroadphaseFilter class is what is doing the infinite vs. infinite filtering.

There may be more stuff like this that you would need to do, though I can't say what it all may be.

As an alternative you could try using the collision detection classes directly:
Code: [Select all] [Expand/Collapse] [Download] (Untitled.java)
  1. // collision detection process:
  2. // Broadphase -> Narrowphase -> Manifold generation
  3. // create detection chain
  4. BroadphaseDetector<Body, BodyFixture> bp = new DynamicAABBTree<Body, BodyFixture>();
  5. NarrowphaseDetector np = new Gjk();
  6. NarrowphasePostProcessor npp = LinkPostProcessor();  // Only required if you use the Link shape
  7. ManifoldSolver ms = new ClippingManifoldSolver();
  8.  
  9. // setup "world"
  10. // add bodies to the broadphase
  11. bp.add(Body);
  12. bp.add(Body);
  13.  
  14. // whenever you modify the "world"
  15. // when you modify a body or body fixture's position/rotation
  16. bp.update(Body);
  17. // if you remove a fixture from a body
  18. bp.remove(Body, BodyFixture);
  19.  
  20. // when ready to detect
  21. List<BroadphasePair<Body, BodyFixture>> pairs = bp.detect();
  22. for (BroadphasePair<Body, BodyFixture> pair : pairs) {
  23.   Body body1 = pair.getCollidable1();
  24.   Body body2 = pair.getCollidable2();
  25.   BodyFixture fixture1 = pair.getFixture1();
  26.   BodyFixture fixture2 = pair.getFixture2();
  27.   Transform transform1 = body1.getTransform();
  28.   Transform transform2 = body2.getTransform();
  29.   Convex convex2 = fixture2.getShape();
  30.   Convex convex1 = fixture1.getShape();
  31.   Penetration p = new Penetration();
  32.   if (np.detect(convex1, transform1, convex2, transform2, p)) {
  33.     npp.process(convex1, transform1, convex2, transform2, p);
  34.     Manifold m= new Manifold();
  35.     if (ms.getManifold(p, convex1, transform1, convex2, transform2, m)) {
  36.         // you have a collision and a manifold to work with
  37.     }
  38.   }
  39. }

Naturally, you lose some nice features going this route, but at least you know exactly what's happening and you also have direct access to the pipeline.

William

zoom
Posts: 145
Joined: Sun Mar 17, 2013 3:57 pm
Location: Stockholm, Sweden
Contact:

Re: How to use dyn4j for collisions without physics

Postby zoom » Mon Oct 24, 2016 1:16 pm

You should seriously consider the second option. That is: take your spaceship, attach it via a motor joint to a 'kinematic'-object (I'll call it a control-object). Move and rotate the control-object. Collisions should work for the space ship but you have control over where it goes and rotates. I've used that setup and for my use cases it has worked perfectly. Even if the control object is placed in an "impossible" place the resolver will handle it so you won't clip through walls et c.

Pesegato
Posts: 17
Joined: Fri Oct 21, 2016 5:29 am

Re: How to use dyn4j for collisions without physics

Postby Pesegato » Tue Oct 25, 2016 4:02 am

Thanks! :)
Now that we are getting into the details, I'd like to draw the hitbox area with inkscape because I want the collidable area to match as closely as possible the actual sprite. This opens a new can of worms, because:

1) I need to somehow convert the svg shape into data that dyn4j can process
2) I need to also split concave areas into convex ones
3) What detector/processor is best suited for this case (by the way, I only need to check if shape A overlaps shape B... actual collision point or other info don't matter)

Pesegato
Posts: 17
Joined: Fri Oct 21, 2016 5:29 am

Re: How to use dyn4j for collisions without physics

Postby Pesegato » Tue Oct 25, 2016 6:32 am

Another question:

4) I want to add some information (POJO?) to a body, so that when happens a collision and I get the collided body, from it I can retrieve the POJO attached to it. Yes, I could add an hashtable... but maybe there's a smarter way that's already built in.

zoom
Posts: 145
Joined: Sun Mar 17, 2013 3:57 pm
Location: Stockholm, Sweden
Contact:

Re: How to use dyn4j for collisions without physics

Postby zoom » Tue Oct 25, 2016 1:23 pm

2) Dyn4J has a SweepLine and an EarClipping decomposer. I use it to take an arbitrary polygon (not always convex) and decompose into triangles which I then render. Like so:

Code: Select all

Triangulator decomposer = new SweepLine();
Vector2[] points = ...
final List<Triangle> triangles = decomposer.triangulate(points);


4) I use the set/get User data on the fixtures.
http://docs.dyn4j.org/v3.2.0/org/dyn4j/ ... UserData--

When there is a collision I can get the fixtures from the ContactPoint class, get the user data and find my game objects that way.

William
Site Admin
Posts: 378
Joined: Sat Feb 06, 2010 10:23 pm

Re: How to use dyn4j for collisions without physics

Postby William » Tue Oct 25, 2016 6:07 pm

Pesegato wrote:1) I need to somehow convert the svg shape into data that dyn4j can process

Whatever you do to get the points that represent the objects, be sure to try to simplify it. Either before decomposing them or after. Small or thin shapes will always be an issue. I wouldn't try to get it pixel perfect either since dyn4j as a whole isn't.

Pesegato wrote:2) I need to also split concave areas into convex ones

Just to add to what zoom said, the SweepLine, Bayazit and EarClipping classes will also decompose into convex shapes if you didn't want to use triangles.

Pesegato wrote:3) What detector/processor is best suited for this case (by the way, I only need to check if shape A overlaps shape B... actual collision point or other info don't matter)

It doesn't matter, both Sat or Gjk will work just fine. If you don't need collision info, then just skip the Manifold Solving step. The LinkPostProcessor is the only NarrowphasePostProcessor in the library. You don't need to use it at all unless you are using the Link shape.

Pesegato wrote:4) I want to add some information (POJO?) to a body, so that when happens a collision and I get the collided body, from it I can retrieve the POJO attached to it. Yes, I could add an hashtable... but maybe there's a smarter way that's already built in.

As zoom has already stated use the setUserData(Object) methods. You can set any info you want.

Thanks,
William

Pesegato
Posts: 17
Joined: Fri Oct 21, 2016 5:29 am

Re: How to use dyn4j for collisions without physics

Postby Pesegato » Wed Oct 26, 2016 5:40 am

Thanks!

I've posted my code on github, feel free to have a look :)

https://github.com/Pesegato/MonkeySheet ... /collision


Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 1 guest