Colliding a Sphere geometry with a TerrainPatch at the mesh level? (triangles)

Hi, how would one go about colliding a Sphere geometry with a TerrainPatch at the mesh level to obtain the terrain’s mesh triangles intersecting with that Sphere? inb4 try with a RAY instead of a mesh… I know, I’ve been using rays for other collideWith situations, but for this one I need to collide with something larger than a ray and I figured instead of puncturing the terrain with 10000 rays a second, I’d simply intersect and read the CollisionResults array to get the triangles. I tried various ways including this:

dat_terrain_patch.collideWith(dat_geometry.getMesh().getBound(), results);
dat_terrain_patch.collideWith(dat_geometry_parent_node.getWorldBound(), results);

…all of which don’t collide. Any ideas? :-/

Also, am I wrong to assume it’s impossible to get what I explained using a GhostControl? (Overlapping Objects which will only tell me what objects it intersects with but not which triangles of their mesh, right?)

Thx for all inputs.

I don’t know anything about JME’s terrain classes really but if it’s doing something ‘special’ with collision then you might have to grab the mesh directly. Just make sure your sphere is appropriately transformed for ‘mesh space’ (ie: if the sphere is in world space then inverse transform it to local space).

Would you be so kind as to provide a code example of what you described? Do you mean like to use this collideWith function that is tied to the Mesh class?

collideWith(Collidable other, Matrix4f worldMatrix, BoundingVolume worldBound, CollisionResults results)
// Handles collision detection, internal use only.

If so, I guess I’m stuck with the worldMatrix and worldBound variables, not sure what to pass there exactly.

dat_terrain_patch.getMesh().collideWith(dat_geometry.getMesh().getBound(), ???, ???, results);

… or should/can I use the HeightfieldCollisionShape to simply the collision? How does that work? I know you said you don’t know anything about the TerrainQuad system in JME3, but I guess if one can make use of the CollisionShape class, then it doesn’t matter if it’s a CapsuleCollisionShape or any other kind of CollisionShape. I just don’t know how to make use of it in my scenario:

Or maybe I’m looking in the wrong place, please let me know what you think.

EDIT: damnit… I just realized while reading that it might not work as I intended because of the LOD, but yet again, it should at least collide with some triangles IMHO, so maybe it could still work, I don’t know scratch that, because it works with a ray, so why not with a Sphere mesh? Anyhow, I just read this:

EDIT #2: I’m now thinking that since the collideWith() function from node to node.getWorldBound() works perfectly, I may end up puncturing like this every frame or something. I mean, it shouldn’t be THAT much of a big deal CPU-wise I think, maybe 4 or 8 punctures every frame or maybe I could do every 10 frames for all that matters, if the sphere does not move fast, it won’t be needed to bombard the terrain with rays.

What do you think?

Sorry, I forgot that mesh already takes transforms. If you want to collide against the mesh directly then you just have to pass the appropriate transforms and you can use your regular world-based sphere if you like. Just look at Geometry to see what it passes to the mesh if you want to know what to pass.

Matrix4f is not something I have ever had to deal with before, so I’ll have to do some trial and error in order to accomplish this. But seriously, do you think a 4000 triangle strip TerrainQuad will be slow to collide with a 30-ish sphere using mesh to mesh collision? Also, will the mesh collision “bug” reproduce with this technique too? By “bug” I mean the behaviour that forces us in some situations to clone the mesh before colliding with a world bound? I have 2 places in my project where not cloning the mesh before colliding makes the collideWith() function return nothing or return results all with empty triangles.

I’m saying this because taking the suggested route takes some time compared to as it sits now I have a functionning solution, which is what I posted before your last comment, the one with the sphere drawing. I think puncturing the mesh with 4 rays is MUCH more performant than mesh to mesh collision no? Especially with a TerrainQuad that has 4000 triangles.

You only have to clone if you are dealing with multiple threads. The JME scene graph is not thread safe and therefore the scene graph cannot be accessed (read write whatever) by multiple threads without external synchronization to make sure that multiple threads are not accessing the same data structure.

If it has nothing to do with multiple threads then you’d have to provide a test case.

I have no idea re: performance. Prior to recent commits by me, sphere->triangle collision didn’t work at all, really… though it pretended to.

re: “trial and error” I already told you that you could have looked at Geometry to see how it does it. No trial and error required just cut and paste.

1 Like

Yes it is caused by multiple threads, but just speculating out of the blue, I think JME should really take care of this business now and provide a method to get the mesh for reading and colliding purposes and then simply throw an exception if the user tries to edit it. That’s it. I think it would make more sense than cloning it every time.

I’ll take a look at the Geometry and “see how it does it” sometime, but I’m really convinced by now that colliding 5 rays is faster than 4000 triangles mesh cloning and comparing this clone to a sphere. But I’ll study it when I have more time, it’s important to understand how it works internally I guess. I’ll give you +1 for the effort, altough I think I’ll stick with the ray collision for now, I don’t think there is an even more optimal way of doing this at the moment, at least not one I can think of.

What are you casting the 5 rays against that wouldn’t also need to be cloned?

But 5 rays will be faster than sphere collisions.

Well yes for the terrain I guess, but wouldn’t I need to clone the sphere mesh too? Without implying the sphere in the equation and using a ray instead, I skip a mesh clone, that’s what I meant.