Prozi / detect-collisions

Detect collisions between different shapes such as Points, Lines, Boxes, Polygons (including concave), Ellipses, and Circles. Features include RayCasting and support for offsets, rotation, scaling, bounding box padding, with options for static and trigger bodies (non-colliding).
https://prozi.github.io/detect-collisions/
MIT License
202 stars 21 forks source link

getPotentials(new Box(...)) not work #39

Closed alderzhang closed 1 year ago

alderzhang commented 1 year ago

Create a body without physics.insert will not have the minX、minY、maxX、maxY properties. So getPotentials with body not inserted into physics will be not work.

Prozi commented 1 year ago

getPotentials with body not inserted into physics will be not work.

this part is actually intentional

alderzhang commented 1 year ago

getPotentials with body not inserted into physics will be not work.

this part is actually intentional

Thanks for replying so quickly! In some cases, such as finding objects within the viewport, it seems unnecessary to insert the viewport rectangle body to the physics, because the viewport body should not be collided with other bodies in the physics, it only used for physics.getPotentials. Is it possible to consider updating the minX/minY/maxX/maxY properties of the incoming body inside physics.getPotentials? @Prozi

Prozi commented 1 year ago

Thanks for replying so quickly! In some cases, such as finding objects within the viewport, it seems unnecessary to insert the viewport rectangle body to the physics, because the viewport body should not be collided with other bodies

there is a flag for exactly this - it's called isTrigger, use it like:

system.createBox({ x: 0, y: 0 }, 1024, 768, { isTrigger: true });

I will write something more in README about flags in upcoming version, sorry for this being poorly documented

in the physics, it only used for physics.getPotentials. Is it possible to consider updating the minX/minY/maxX/maxY properties of the incoming body inside physics.getPotentials?

the System.getPotentials(bodyWithBBox) is actually

RBush.search(bodyWithBBox).filter(
  notSelf => notSelf !== bodyWithBBox
)

(see https://github.com/Prozi/detect-collisions/blob/master/src/system.ts#L139-L142)

so to get the collisions with a body using RBush it has to be inserted into collision tree.

so I advise to use the code above with isTrigger and check the results

thanks for opening an issue :)

Prozi commented 1 year ago

you know what, after thinking for a bit maybe your use case is correct.

why insert the rectangle to collision tree, you don't need to do that, you should be able to do what you want

I will think about how to implement it @alderzhang

Prozi commented 1 year ago

actually I think what you need is Body.getAABBAsBox, try this:

import { System, Box } from 'detect-collisions';

const viewport = new Box({ x: 0, y: 0 }, window.innerWidth, window.innerHeight);
const physics = new System();

// insert some stuff then
physics.getPotentials(viewport.getAABBAsBox()).forEach...
Prozi commented 1 year ago

updated the readme as mentioned above

alderzhang commented 1 year ago

actually I think what you need is Body.getAABBAsBox, try this:

import { System, Box } from 'detect-collisions';

const viewport = new Box({ x: 0, y: 0 }, window.innerWidth, window.innerHeight);
const physics = new System();

// insert some stuff then
physics.getPotentials(viewport.getAABBAsBox()).forEach...

It works!

But I found that the changes didn't just affect the getPotentials function, it also caused the checkCollision function to not work when the body was not inserted into physics.

If use this library for games, maybe everything is ok, because all bodies should be in physics. but my use case is canvas, users can use pen to draw a lot of lines, and allow users to select and modify(move/rotate/scale) these lines, I use this library for line and mouse collision detection.

A line is composed of many polygons, when the user modifies the line, insert and delete a large number of polygons into physics, will cause performance problems, so I did an optimization, physics only insert the bounding box of the line, first find out the line that may collide through getPotentials, and then use checkCollision to check whether each polygon on the line collides with each polygon separately.

Can you consider retaining the collision detection function of the body without inserting physics? Or could you consider adding an option to control this behavior?

Prozi commented 1 year ago

It works!

But I found that the changes didn't just affect the getPotentials function, it also caused the checkCollision function to not work when the body was not inserted into physics.

please try something like

https://github.com/Prozi/detect-collisions/blob/master/src/bodies/box.spec.js#L106-L132

does this solve your issue? :)

alderzhang commented 1 year ago

When creating a body with physics.createCircle, it works fine, because this .insert is actually called internally. But if creating a body with new Circle, you can't. This requires all bodies to be added to physics first, and if I have a large number of bodies and need to be modified frequently, this will cause performance issues and dropped frames.

Prozi commented 1 year ago

bodies need to be added to physics for other bodies in physics to collide with them

Prozi commented 1 year ago
  1. if you need to check are the bodies within view port then do what I did here https://github.com/Prozi/detect-collisions/blob/master/src/bodies/box.spec.js#L106-L132

  2. if you need bodies detecting collision between each other then insert them into system

alderzhang commented 1 year ago

Well, maybe my usage is a little inconsistent with the original design of this library, in fact most of the time I don't need to detect collisions between objects, I just need to detect whether objects collide with the mouse or fingers. I'll figure it out for myself to deal with this, thank you for giving so much guidance!