Hi there,
Apparently setLocalScale only affects visual mesh, what about collision? Any ways to scale/update it without reloading model? Thanks
Hi there,
Apparently setLocalScale only affects visual mesh, what about collision? Any ways to scale/update it without reloading model? Thanks
I’ve not tried this myself but you could try:
That should remove and re-add the physics body to the world
No effect unfortunately
scale = otherEntity.getLocalScale();
otherEntity.collision.enabled = false;
otherEntity.rigidbody.enabled = false;
otherEntity.setLocalScale(scale.x + 0.05, scale.y + 0.05, scale.z + 0.05);
otherEntity.collision.enabled = true;
otherEntity.rigidbody.enabled = true;
You probably need to remove the cashed mesh in order for the engine to generate a new one with a new scale. So, after you disabled the components, and before you enable them, something like:
// when using render
for (const mesh of entity.collision.render.meshes) {
delete this.app.systems.collision._triMeshCache[mesh.id];
}
// when using model
for (const instance of entity.collision.model.meshInstances) {
delete this.app.systems.collision._triMeshCache[instance.mesh.id];
}
Hi, no effect either
scale = otherEntity.getLocalScale();
otherEntity.collision.enabled = false;
otherEntity.rigidbody.enabled = false;
otherEntity.setLocalScale(scale.x + 0.05, scale.y + 0.05, scale.z + 0.05);
for (const instance of otherEntity.collision.model.meshInstances) {
delete this.app.systems.collision._triMeshCache[instance.mesh.id];
}
otherEntity.collision.enabled = true;
otherEntity.rigidbody.enabled = true;
Using debug draw
It should work. You need to debug and see why it doesn’t, if it doesn’t.
First, I’d check if it really doesn’t work by changing the scale to something much larger, e.g. multiply the current by 10 scale.x * 10
. Perhaps 0.05 is not a noticeable change. I would also try to reset the cache completely, instead of only the affected mesh.
Couldn’t get it to work, tried deleting this.app.systems.collision._triMeshCache - no luck either
Here’s repro PlayCanvas 3D HTML5 Game Engine
KEY_PAGE_UP
to increase scale/clear cache
You may need in addition to destroy the shape in Ammo:
for (const mesh of entity.collision.render.meshes) {
const shape = this.app.systems.collision._triMeshCache[mesh.id];
Ammo.destroy(shape);
delete this.app.systems.collision._triMeshCache[mesh.id];
}
Have you tried this on render? Model throws errors
Isn’t it that Ammo.destroy(this._triMeshCache[key]);
requires meshInstance key? As these are actually stored
Nevertheless, using ammo destroy with valid keys throwing ‘Error: Cannot destroy object. (Did you create it yourself?)’
No it’s being actually used in the PlayCanvas engine, I’ve shared the link above.
The logic is it’s not enough to remove the JS reference, Ammo.js occupies a different memory chunk than the one used by regular JS data. So that Ammo.destroy() call is required to clean up that memory.
Now if that solves your problem or not I’m not quite sure. But definitely it shouldn’t give any error if the object is valid. Try using the JS debugger or the console to check that you are using it as expected.
for (const instance of otherEntity.collision.model.meshInstances) {
const shape = this.app.systems.collision._triMeshCache[instance.mesh.id];
Ammo.destroy(shape);
delete this.app.systems.collision._triMeshCache[instance.mesh.id];
}
RuntimeError: indirect call to null
for (const instance of otherEntity.collision.model.meshInstances) {
const shape = this.app.systems.collision._triMeshCache[instance.key];
Ammo.destroy(shape);
delete this.app.systems.collision._triMeshCache[instance.mesh.id];
}
TypeError: a is undefined
It looks like it is not easy to change a scale of a collision mesh at runtime at the moment.
Before clearing the cache, you also want to destroy the reference stored in the collision component:
Ammo.destroy(otherEntity.collision.shape);
otherEntity.collision.shape = null;
Related issue:
I can confirm it works as expected
scale = otherEntity.getLocalScale();
otherEntity.enabled = false;
Ammo.destroy(otherEntity.collision.shape);
otherEntity.collision.shape = null;
otherEntity.setLocalScale(scale.x + 0.05, scale.y + 0.05, scale.z + 0.05);
for (const instance of otherEntity.collision.model.meshInstances) {
delete this.app.systems.collision._triMeshCache[instance.mesh.id];
}
console.log(this.app.systems.collision._triMeshCache);
otherEntity.enabled = true;
}
Thank you folks