Rendering loop and physics collide questions

Hi,
In my scene, I have a mesh that changes of shape (this is an extruded a long path tube ) , when I animate my scene. I have some optimlisation problems

To achieve this, at each rendering loop, if the shape has changed, I dispose() the existing mesh, and create the new one (beforeRender) and create the associated physics impostor

Is there a quickest way doing this (updating only the mesh without disposing and creating the impostor)
I register a collide function for this mesh.

When there is a collide event this function is called , I am changing the emissive color of collide meshes. But unfortunately this is called at every render loop and this is very unuseful if the shape has not changed, since I already know there has been collide and it has been visually processed.How can I avoid this ?

Is it possible to have the repro of your problem in Playground? It would be much easier for everybody to help you.
As far as I see it there are some logical problems in your approach which could be easily solved.

Hi @Stephane_Ancelot , I think disposing and recreating meshes and physics impostors is the preferred way to do this. It may be possible to not destroy anything if you find a way to tap directly into Bullet/Ammo’s low-level API: How to refresh collisions after changing a body's shape? - Real-Time Physics Simulation Forum

In your last paragraph, did you mean that you are checking for collisions once per render loop? If you use PhysicsImpostor methods like registerOnPhysicsCollide, onCollide, and onCollideEvent, you wouldn’t need to check for collisions each frame. They would just call a callback where you could update the emissive colors

Here’s a Playground that console.logs when there is a collision: https://playground.babylonjs.com/#GE0ASK#15

1 Like

I tried to make a playground that looks similar to my real application, unfortunately, I could not finish it since ExtrudeMesh replies with Uncaught TypeError: e[r].clone is not a function

@gbz , I agree but in my case, this is a kind of animation, you can move the time step using a slider , each time step is a representation of a situation at time t. (In reality this a rigid body).
I have to compute a new mesh for one shape each time the step changes (and register again collide func). once the collide has been detected and slider time step has not changed, there is no need to collide compute again, since nothing has changed in the scene

here is the playground I began to implement to emulate my application, but I am stuck at ExtrudeShape error:
https://playground.babylonjs.com/#8KLHPQ#16

@gbz in your playground, we can sea what happens in my application too.

When the part has falled, you registered it collided with ground.
and the registered function is called at every render()… altough nothing more is moving in the scene onCollide() is always called .

It is not very clear for me at the moment, but I noticed if OnCollide is defined, registerOnCollide and onCollideEvent are not called

@Stephane_Ancelot, maybe we’d want to update how we register collisions in the Babylon.js source code. However, for now, onCollide is only called if a callback function is provided to registerOnCollide (for AmmoJSPlugin). This behavior is actually different between AmmoJSPlugin, CannonJSPlugin, and OimoJSPlugin

After diving into the source code, I found:

Source: Babylon.js/ammoJSPlugin.ts at master · BabylonJS/Babylon.js · GitHub
Notice how onCollide is only called if _onPhysicsCollideCallbacks.length > 0.

_onPhysicsCollideCallbacks is only incremented beyond 0 if registerOnCollide is called and given a callback function
Source: Babylon.js/physicsImpostor.ts at master · BabylonJS/Babylon.js · GitHub

here is my working bullet code in c++ , when using the bullet api.
I don’t need iterate steps since I don’t use gravity.

if I could do the same thing in babylonjs after renderering this may be fine.

int performCollideDetection()
{
	int ret = 0;
	collide_pairs.clear();

	physicalWorld->performDiscreteCollisionDetection();

	int numManifolds = physicalWorld->getDispatcher()->getNumManifolds();
	int done = 0;
	for (int i=0;i<numManifolds;i++)
	{
		btPersistentManifold* contactManifold = physicalWorld->getDispatcher()->getManifoldByIndexInternal(i);

		const btCollisionObject* obA = contactManifold->getBody0();
	    const btCollisionObject* obB = contactManifold->getBody1();
		//btCollisionObject* obA = contactManifold->getBody0(); // static_cast<btCollisionObject*>(contactManifold->getBody0());
		//btCollisionObject* obB = contactManifold->getBody1(); // static_cast<btCollisionObject*>(contactManifold->getBody1());

		int numContacts = contactManifold->getNumContacts();

		if (numContacts > 0)
		{
			pairname paire;
			if (done == 0)
			{
						done = 1;
			}

			string *name0, *name1;
			// printf("collision !\n");
			name0 = (string *)obA->getUserPointer();
			name1 = (string *)obB->getUserPointer();
			paire.nom0 = *name0;
			paire.nom1 = *name1;
			collide_pairs.push_back(paire);
			//printf("%d %s %s\n",numManifolds,name0->c_str(),name1->c_str());
			ret = 1;
		}


	}
	return ret;
}

@Stephane_Ancelot, ah I see you’re using the Contact Manifold Check

According to Collision Detection In Javascript 3D Physics using Ammo.js and Three.js | by Blue Magnificent | Medium, there seems to be a few ways to do collision detection:

  • Contact Manifold Check (iterating over all manifolds and contacts and checking for collisions)
  • contactTest (single check if an object is contacting any other)
  • contactPairTest (single check if 2 objects are contacting)
  • and more…

By default, Babylon’s AmmoJSPlugin seems to use contactTest and contactPairTest. I think if we wanted to use the Contact Manifold Check as you are, we would need to implement our own custom physics engine. Unfortunately, we lose access to Babylon’s intuitive physics API, which automatically handles the pairing of rendered meshes and physics bodies for us. Now, we have to manage the pairing of these ourselves

Following the tutorial linked above, I was able to use the Contact Manifold Check in a custom lightweight physics engine: physics/PhysicsTest.ts at main · regnaio/physics · GitHub

In this case, I decided going with a Web Worker, so I managed the pairing using SharedArrayBuffer. However, you could choose to not use a Web Worker and pair rendered meshes to physics bodies by simply adding an attribute to both referencing each other. Intro to JavaScript 3D Physics using Ammo.js and Three.js | by Blue Magnificent | Medium explains this by introducing userData

You could clone the above repo and uncomment

// this.detectCollisions();

which is the Contact Manifold Check. However, beware that this might generate a lot of console logs if you generate many physics boxes

With your knowledge of Bullet, you could definitely implement your own custom physics engine if you require the Contact Manifold Check. I’d highly recommend the entire 4-part series: Intro to JavaScript 3D Physics using Ammo.js and Three.js | by Blue Magnificent | Medium

@gbz Thanks for your reply.

Ok, I understand you used a webworker => mainly to avoid computation impact on the main page.

Since my collide detection is really different . I made a class to manage my ammojs collide object with my own collide implement.

using bullet debugdraw, I can watch my collide objects.

but at the moment I duplicated objects vertices in ammojs. I have not understood if there was an easy way to share the same vertices between ammojs and babylon without impacting memory ?

now I have a small problem, how want to set the position of the ammojs objects , so I retrieve the mesh matrix using babylonjs getWorldMatrix() , this does not seem being the same format as ammojs setworldmatrix() . how can I do , to be efficient and right to copy it? (This should be the matrix related to root)