Three-mesh-bvh DynamicGeometryGenerator?

Hey @gkjohnson, I’m currently trying to slightly modify your Sphere physics collision Demo but running into some issues that I can’t seem to find documentation on.

Essentially, I’m trying to add some rotation to the gltf collider mesh on pointermove and have any balls in the scene respond to that rotation physically, here’s a short clip of what i’m referring to…

what I have tried:

I have added the visualizer, collider, environment objects to a container object3D so this can be rotated, made staticGenerator a global variable so it can be accessed from within the pointermove event and then trying to refit the bounds tree of the collider geometry when rotation happens eg…

renderer.domElement.addEventListener("pointermove", (e) => {

	mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
	mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;
	
	container.rotation.x = mouse.x
	container.rotation.z = mouse.y

	container.updateMatrix()
	container.updateMatrixWorld();

	if(staticGenerator){
		staticGenerator.generate( collider.geometry );
		collider.geometry.boundsTree.refit();
	}
});

this looks like it’s making the balls slightly react to the rotation of the gltf collider but it’s not stable at all, very jumpy and balls end up going through the gltf collider geometry where there are freezes in the regen process…

I’ve tried to find reference to some sort of DynamicGeometryGenerator in the three-mesh-bvh lib with no luck so far so decided to come to the source and see if you’d possibly have some idea how this physics functionality would be best handled or implemented with the smoothest response times?

EDIT: omitting the following lines vvv from the above code ^^^… everything runs smooth as butter…

	//container.updateMatrix()
	//container.updateMatrixWorld();

:ok_hand:

EDIT EDIT: there’s definitely still something off vvv but i think this is likely the way I’m making rotations on the parent of the visualizer, collider and environment object rather than “absolutely” on these objects individually…

3 Likes

Hey! I haven’t touched that example in awhile but here’s what I recall and would recommend.

From what I’m understanding you want to be able to animate the “scene” and have impact the physics of the balls, is that right?

Currently the physics is all happening in the world frame which is where the triangles in the collider are position so there is not need to transform to balls into the local frame to calculate collisions - but if you’re going to be rotating the scene then you’ll want to make sure you’re calculating all the collisions in the rotated frame. In other words, for each ball you’ll want to transform the ball position into the local frame of the scene, calculate the collision points & imparted force vectors, transform them back into the world frame, and perform the physics step.

That said things likely won’t just work the way you want out of the box. If you want the balls to fly around when you swing the world around you’ll need to calculate the angular momentum at the hit points to impart forces, perform multiple iteration steps similar to what is happening with the spheres, and maybe more. Unfortunately I’m not enough of a physics engine expert to cite everything you’d need to make this work.

then trying to refit the bounds tree of the collider geometry when rotation happens eg…

I wouldn’t recommend doing this. Refit is faster than rebuild but can still be slow. It would be better to transform there spheres into the rotated local frame of the scene, instead. Refit is good when the triangles have changed relative to each other and you need a quick result but it does result in a less optimal bvh, as well. If a collsider is moving as a whole it’s best to just recalculate in the moved frame.

very jumpy and balls end up going through the gltf collider geometry where there are freezes in the regen process…

Yeah this issue of pieces of the model moving too much and causing the balls to miss collisions is the reason you need to perform collision iterations in multiple steps.

Depending on how deep you want to get into this stuff you might take a look at Greg Hodge’s Game Physics in One Weekend series which is very affordable. I haven’t read the whole thing myself but from what I did look at it seemed to be pretty good.

3 Likes

thanks @gkjohnson! Mathematically, this is going to take a moment to digest and scope the code for where and how to apply this logic… I’ll try to filter out where in the update loop / s I should make these amendments! I really appreciate the guidance in direction here!

so far, I’ve put together a fun little testing pen to try to solve this, I’ve given the setup a slightly different context to give a better feel of the overall thing I’m trying to do…

Video:

Codepen:

1 Like

If you’re making one of those tilting marble maze things, I can almost guarantee you’d be better off using a regular off the shelf physics engine, be it Ammo, Rapier, Cannon, Havok, PhysX, et al…
Actually rotating the physical table/static geometry is a nightmare scenario for physics engines. They reeeally prefer their static geometry to stay static and only the bare minimum number of objects be moving and dynamic, like the ball. The way I would approach this is to fake tilting the table but what you’re really doing is just changing the gravity vector on the sim, or just applying a single constant directional force to the ball. It will be sooo much faster, stable, and robust than trying to do an actual dynamic environment. Just my 2c. having made some of these kinds of things before. :smiley:
I know it’s not exactly what you’re aiming for but here’s a thing I made a long time ago… the code is shite but might give u some ideas:
https://136.24.178.125/thrux/app/index.html

2 Likes

Your codepen looks pretty good so far!

I can almost guarantee you’d be better off using a regular off the shelf physics engine, be it Ammo, Rapier, Cannon, Havok, PhysX, et al

I’d agree. Unless you’re trying to learn how to write a physics engine, of course :grin: It’s a great way to learn, though!

2 Likes

I didn’t mean to imply that mesh-bvh is anything less than fantastic! Just probably not the ideal use case, dynamically recreating/refitting it each frame.

I looove me some mesh-bvh! It has put much food in my childrens mouths.

2 Likes

Oh Ignore everything I said @Lawrence3DPK … I just actually ran you’re codepen and it looks like it’s working really well so I think you’re on the right track! It was just my physics trauma surfacing…

1 Like

Would it be possible instead of rotating the model and the associated collider shape, just to tilt the camera? In this way it will look as if the scene is tilting, but in fact it will stay horizontal all the time. And no dynamic recalculation of bvh is needed.

Apart from the camera, the only other change is the direction of the gravity, it should not be straight down, but also tilt as the camera tilts.

1 Like

Yes indeed, I completely get why this has been conventional application across the board of physics sims from gta to embergen / marvellous, but may be failing to see why the division between “static” and “dynamic” was ever made, if we were to flip the scenario, from a static terrain to a dynamic ball, what this essentially equates to would be “until the ball knows an iteration of its directional velocity definitely contains, or has contained a collision, why move at all?” and hence my thinking around an implementation of a kind of “DynamicGeometryGenerator”, whereby dynamic objects determine thier directional velocity only after establishing the global normal vector of the face that a collision may have happened.

To elaborate… The idea “static”, I’m pretty sure, in actual physics, is similar to “nothing”, just our perception of “local space” enables a stable foundation to base a digital replication of the idea of physics upon the convenient theoretical grounds of something being “static”, however, a “cosmic space entity” irl, no matter how “globalised” (static), would still be “physically subject” to the same forces as it’s parent entity, and any localised children of that entity subject to both parent and grandparent forces, the mass and velocity of which, having a “parental magnitude influence” over children down the hierarchy… I think there’s a part of three js docs that describes this concept quite well… three.js manual
Eg… If the “earth” in the above docs is subject to a physical force, it’s child [“moon”], would be subject to the equal force of earth + any derivative forces evoked by collisions with earth, which in turn can both be escalated in their physical state up to their parent “sun” object…

The thinking behind where this is going…
Theoretically, a static parent only needs to be static if it didn’t move, relative to a fractional mass of child entities that interacted with it (for instance, would spacex’ rocket launches affect the directional velocity of earth at some point?) … To graphically represent this, imagine shrapnel of a bullet breaking away from the main hull as an impact occurs, the mass of the fractional entities would underweigh the parent shell in directional velocity but all the child pieces only know thier absolute directional velocity when a parent surface normal has been encountered, thus exerting that force on its parent. The idea is a type of fractal based physical simulation whereby all deeper level physical entities behaviours would be derived from it’s parental physical interaction + any local “child space” interactions.

Thanks @PavelBoytchev, as always that approach would hold together and probably be solid / rapid… Until you begin to AR… Afaia there’s quite strict global matrices in terms of how AR environments would handle this overall situation…

@gkjohnson I’m sure there’s a lot of valid reasons why not to delve into this particular branch of Web based physics as an independent dev but I feel there’s a little exploration here I could get away with and report back if any findings are helpful…

2 Likes

static/dynamic division exists because static objects don’t need to be touched every sim step.

The way you get physics simulations with > 100 objects is by having them be either static or “asleep”… so they can be removed from the per frame update checks.
They achieve this by using different acceleration structures internally…
A broadphase strategy:
https://pybullet.org/Bullet/BulletFull/classbtBroadphaseInterface.html

And then once an overlap between a static and a dynamic object is detected… a narrow phase collision strategy is chosen based on a table of about 6 different techniques:
https://pybullet.org/Bullet/BulletFull/classbtCollisionDispatcher.html#a9a088008ee265797fae447c455bc4142

There is a good visual representation of the table somewhere but I can’t find it right now, but it shows the different input types on the x and y axis, and shows which algo is used for that case:

This is a good general overview: Bullet’s Collision Algorithm — Mechanica 0.0.1 documentation

2 Likes