That’s interesting, I can’t reproduce this. If it’s the same asset being used it wouldn’t normally matter if you reimport it or not. The mesh collider is being generated on runtime, not on import time.
Are you able to reproduce this on a sample project? It would be good to know if there is an issue to log on the engine repo.
‘Unfortunately’ I’m not able to reproduce this now, but it has happened to me once before, hence why I was compelled to make this post.
If it happens to me again, I’ll be sure to make efforts to isolate the problem.
When using differently scaled mesh colliders of the same mesh, only 1 instance of the collider will be used.
When I originally stated that reimporting the mesh fixes the issue, I had only added the mesh back to my stairs but had forgotten they were used on some decoration as well. After reapplying it, the issue came back and with some experimentation I found this to be the issue.
For us personally I don’t think it will be such a big deal, but I’d still like to make an issue for this. Should I do that on the PlayCanvas or the Ammo github?
Placing a mesh into the physics world is a computationally expensive operation - the engine generates an Ammo compound shape from a number of bvh triangle meshes, one for each mesh instance. Once generated the trimeshes then get cached for future re-use. As a result, when you use the same mesh for another collider, the trimeshes are taken from the cache, instead of generating new ones. Please, add an issue to the engine repo:
For the moment you could patch the following engine method to avoid grabbing a mesh from the cache (or implement your own logic for when to do that):
// do this before any of your level entities are initialized
this.app.systems.collision.implementations.mesh.createPhysicalShape = function (entity, data) {
// patched method
}
Seems like I’m facing the same issue, if I use the same model asset as a mesh on different scale entities same thing happens, also getting some weird jumping/bouncing issues, any way to patch it app wise/globally?
// do this before any of your level entities are initialized
this.app.systems.collision.implementations.mesh.createPhysicalShape = function (entity, data) {
// patched method
}
its now createAmmoMesh
createAmmoMesh(mesh, node, shape) {
let triMesh;
if (this.system._triMeshCache[mesh.id]) {
triMesh = this.system._triMeshCache[mesh.id];
} else {
const vb = mesh.vertexBuffer;
const format = vb.getFormat();
let stride;
let positions;
for (let i = 0; i < format.elements.length; i++) {
const element = format.elements[i];
if (element.name === SEMANTIC_POSITION) {
positions = new Float32Array(vb.lock(), element.offset);
stride = element.stride / 4;
break;
}
}
const indices = [];
mesh.getIndices(indices);
const numTriangles = mesh.primitive[0].count / 3;
const v1 = new Ammo.btVector3();
const v2 = new Ammo.btVector3();
const v3 = new Ammo.btVector3();
let i1, i2, i3;
const base = mesh.primitive[0].base;
triMesh = new Ammo.btTriangleMesh();
this.system._triMeshCache[mesh.id] = triMesh;
for (let i = 0; i < numTriangles; i++) {
i1 = indices[base + i * 3] * stride;
i2 = indices[base + i * 3 + 1] * stride;
i3 = indices[base + i * 3 + 2] * stride;
v1.setValue(positions[i1], positions[i1 + 1], positions[i1 + 2]);
v2.setValue(positions[i2], positions[i2 + 1], positions[i2 + 2]);
v3.setValue(positions[i3], positions[i3 + 1], positions[i3 + 2]);
triMesh.addTriangle(v1, v2, v3, true);
}
Ammo.destroy(v1);
Ammo.destroy(v2);
Ammo.destroy(v3);
}
const useQuantizedAabbCompression = true;
const triMeshShape = new Ammo.btBvhTriangleMeshShape(triMesh, useQuantizedAabbCompression);
const scaling = this.system._getNodeScaling(node);
triMeshShape.setLocalScaling(scaling);
Ammo.destroy(scaling);
const transform = this.system._getNodeTransform(node);
shape.addChildShape(transform, triMeshShape);
Ammo.destroy(transform);
}
I’ve thought this would return undefined if there were no models with mesh/asset as a collision, added few from editor, loaded few via code, still undefined
1.64.4
Okay did further tests, if there is at least 1 entity with mesh as collision + rigidbody (editor based), implementations.mesh is not undefined, but if there are no assets from inside editor and rather loaded using app.assets.loadFromUrlAndFilename, it’s always undefined
Update: Okay, type: ‘mesh’, was missing
But now the real question is, how would you patch using
this.app.systems.collision.implementations.mesh.createPhysicalShape = function (entity, data) {
// patched method
}