Scirra / Construct-bugs

Public bug report submissions for Construct 3 and Construct Animate. Please read the guidelines then click the 'Issues' tab to get started.
https://www.construct.net
108 stars 83 forks source link

Physics not working on certain meshes #5899

Closed BigBuckBunny12 closed 2 years ago

BigBuckBunny12 commented 2 years ago

Problem description

Collision detection not working properly on certain meshes with physics behaviour, causing other physics objects to fall through without colliding.

Attach a .c3p

MeshBug.zip

Steps to reproduce

  1. Object on the left is the one bugged. As you can see by starting the project, the ball goes through it without colliding.
  2. Object on the right is the exactly same object as the one on the left, but I moved one mesh point. You can see that in this case the collision is detected and the ball does not pass through.

Observed result

The left ball ignores the object and goes through it

Expected result

The left ball should behave like the one on the right, by colliding with the object.

More details

I tested the same mesh on r302 and r241, nothing changes.

The mesh has been created using a custom made editor which uses cubic splines in order to change the position of the mesh points according to a set path. I'm sure that the issue doesn't come from this method, as the mesh seems perfectly fine (see the object in edit mode inside the editor). Also, i previously used perlin noise to determine the position of the points, and the issue was still there.

I suspect it has to do with the number of columns of the mesh, since lower values do not produce bugged meshes.

System details

View details Platform information Product: Construct 3 r302 (stable) Browser: Chrome 103.0.5060.114 Browser engine: Chromium Context: browser Operating system: Windows 10 Device type: desktop Device pixel ratio: 1 Logical CPU cores: 4 Approx. device memory: 8 GB User agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36 Language setting: en-US Local storage Storage quota (approx): 133 gb Storage usage (approx): 114 mb (0.1%) Persistant storage: Yes Browser support notes This list contains missing features that are not required, but could improve performance or user experience if supported. Nothing is missing. Everything is OK! WebGL information Version string: WebGL 2.0 (OpenGL ES 3.0 Chromium) Numeric version: 2 Supports NPOT textures: yes Supports GPU profiling: yes Supports highp precision: yes Vendor: Google Inc. (NVIDIA) Renderer: ANGLE (NVIDIA, NVIDIA GeForce GTX 1050 Ti Direct3D11 vs_5_0 ps_5_0, D3D11) Major performance caveat: no Maximum texture size: 16384 Point size range: 1 to 1024 Extensions: EXT_color_buffer_float EXT_color_buffer_half_float EXT_disjoint_timer_query_webgl2 EXT_float_blend EXT_texture_compression_bptc EXT_texture_compression_rgtc EXT_texture_filter_anisotropic EXT_texture_norm16 KHR_parallel_shader_compile OES_draw_buffers_indexed OES_texture_float_linear WEBGL_compressed_texture_s3tc WEBGL_compressed_texture_s3tc_srgb WEBGL_debug_renderer_info WEBGL_debug_shaders WEBGL_lose_context WEBGL_multi_draw OVR_multiview2 Audio information System sample rate: 48000 Hz Output channels: 2 Output interpretation: speakers Supported decode formats: WebM Opus (audio/webm; codecs=opus) Ogg Opus (audio/ogg; codecs=opus) WebM Vorbis (audio/webm; codecs=vorbis) Ogg Vorbis (audio/ogg; codecs=vorbis) MPEG-4 AAC (audio/mp4; codecs=mp4a.40.5) MP3 (audio/mpeg) FLAC (audio/flac) PCM WAV (audio/wav; codecs=1) Supported encode formats: WebM Opus (audio/webm; codecs=opus) Video information Supported decode formats: WebM AV1 (video/webm; codecs=av01.0.00M.08) MP4 AV1 (video/mp4; codecs=av01.0.00M.08) WebM VP9 (video/webm; codecs=vp9) WebM VP8 (video/webm; codecs=vp8) Ogg Theora (video/ogg; codecs=theora) H.264 (video/mp4; codecs=avc1.42E01E) Supported encode formats: WebM VP9 (video/webm; codecs=vp9) WebM VP8 (video/webm; codecs=vp8)
AshleyScirra commented 2 years ago

For some reason the shape on the left fails to create a convex polygon shape, which is required for the Physics behavior. It happens deep in some complex geometric code. It's not clear why and I expect it will be difficult to do anything about it. Often these issues come down to floating point precision errors, which can be very tough to deal with.

BigBuckBunny12 commented 2 years ago

I understand, but why does it need to create a convex polygon shape? shouldn't it work with concave shapes too? And, by any chance, could this issue be related to #4269?

The fact that this bug may occasionally happen worries me, as most of the time mesh and physics are used to create procedural terrain, and a bug like this one can literally break the game.

I tried many things but with no success: I used a mesh with more columns (50, to be sure that the problem was more frequent), rounding each mesh point to the second decimal digit; this made the issue much rarer, but it didn't solve it completely, as you can imagine. I also noticed that the bug appears more frequently on almost flat surfaces (such as the one in the project I attached previously).

Until the bug isn't fixed, I think that the only reliable way to get the collision to work would be to dynamically create invisible sprites (with physics behavior attached) that match the mesh points, something like this:

ReferenceImage :

AshleyScirra commented 2 years ago

Physics internally requires convex shapes, which is a requirement of box2d. If you give it a concave shape, it runs a complicated algorithm to split it up in to multiple convex shapes. That is where the problem lies. Things like floating point precision can cause rounding errors that cause the algorithm to fail, and it can be very difficult to make it robust against that kind of thing, as computers fundamentally have limited precision in fractional calculations.

SnipG commented 2 years ago

Took a quick look at this. Because problems always repeat themself, problem seems come down to old issue: where polygon points on straight line cause bug. This was fixed in Construct3, by removing excess points that are between 2 point. From this, it could be reasonable conclusion why is this issue happening: Points removing does not work in mesh mode Points removing or applying and fractional calculation results some sort of bug: points exists in sprite mesh, but are not read into physics etc. Which results physic mesh to default into bounding box or mesh without any modification. So possible test to see if this is the case: apply or revert polygon points removing in mesh editing.

Quick example i hammered together. Oiiiiii.zip

Points that bug mesh n physic. Even small change in those points will remove bug. oiiiii

AshleyScirra commented 2 years ago

problem seems come down to old issue: where polygon points on straight line cause bug. This was fixed in Construct3, by removing excess points that are between 2 point.

I don't remember any such issue and I can't find any code that does what you describe for normal collision polygons. Do you have another bug number for reference on that?

SnipG commented 2 years ago

Took some time, but it should be this: #2822 From looks of it, it was improved and not 100% fixed. So it's most likely same case.

AshleyScirra commented 2 years ago

Ah, thanks for digging that up, it's really helpful. That issue applied to Drawing Canvas, not physics, which is why I couldn't find it, but it is indeed a similar problem involving colinear points.

The mesh code actually already had code to identify colinear points and remove them, but it was too sensitive and didn't remove any points in the repro project, which then failed convex poly separation. Decreasing the sensitivity of the colinear point detection removes a few colinear points and then allows convex poly separation to succeed so it works with Physics. So it should be fixed in the next beta.

BigBuckBunny12 commented 2 years ago

Amazing! Thank you guys!