Issue with getting collisions to work with GLB

Hello there, I usually manage to solve most of my issues but this time I feel completely blocked for reasons I just can not understand, I have that piece of code :

addMeshToHeadEntity(meshInstance) {

    let model = new pc.Model();

    model.meshInstances = [meshInstance];
    this.rigidbody = this.head.addComponent("rigidbody", {type: "static"});
    this.collision = this.head.addComponent("collision", {type: "mesh"});
    this.head.collision.model = model;

    model.graph = meshInstance.node;

    this.head.addComponent('model');
    this.head.model.model = model;
    this.head.model.castShadows = true;
    this.head.model.receiveShadows = true;
    this.head.model.castShadowsLightmap = true;

}

that I created and tested and it always worked perfectly, however I’ve been working with OBJ files that whole time, and am now forced to also use GLB files, I created a piece of script that extract the meshInstance from the GLB renderEntity, and throw it into that code I showed you. The weird part is that it works in rendering the meshInstance in the viewer, but for some reason the collision is non-existent. It’s really weird since it’s the exact same mesh used for collision & rendering, I just can’t understand why my raycasts would return something when the mesh comes from the OBJ file and but not when it comes from the GLB.

Any idea of why ?

Thank you very much !

Hi @Paul_Courau,

It may be the case render assets are treated differently in the collision component, they require to be attached on a different property:

You need to reference a render asset in the renderAsset property.

Thanks Leonidas, however there’s something I don’t understand well, how do you create a render asset ?

From what I’ve seen, you can do :

let model = new pc.Model();

but can’t do :

let render = new pc.Render();

In the API reference I only see “RenderComponent” but I’m now willing to make a full component

I did try to do the following :

this.head.collision.render = model;

but with no results :S

This is related to this issue I think Implement simple API to allow Meshes / Renders to be used as a Collider · Issue #4181 · playcanvas/engine · GitHub

See some possible workarounds in the linked forum thread there

1 Like

But what I do not understand is that I retrieved the mesh from the render, so it is no more a render but just a raw mesh, and then I created a model from that mesh, so technically there should be no issue in that regard, I’m not sure if there’s something I’m misunderstanding here, maybe it’s not the same type of “mesh” objects in Renders and Models ?

Sometimes there’s a scale of 0.01 applied on entities with render component or something similar … so you might just be missing that and your mesh is too small or something like that.

The mesh itself is the same between model and render component though, so that should work. Check the scales. And other workarounds from that thread I linked.

1 Like

Try to debug draw your physics state. It should help debugging collision meshes.

https://playcanvas.com/project/744419/overview/ammo-debug-draw

1 Like

I did try that script but unfortunately it only makes my app ultra laggy without seeing any collision on the screen, even with working collisions :S

If your computer is struggling with the debug renderer, it means it has to draw too many lines. Temporarily disable all your other collision entities, and leave just the one you are debugging and maybe another one it is colliding with.

I actually only use one collision entity :S

in General I managed to narrow down the issue quite simply :
I created an Entity, to which I manually added :

  • A Render component (for displaying purpose)
  • A Collision component

Both the render component & collision component share the same render Asset that manually imported in my project.

When both are imported manually, everything works fine, the collision matches the visual, however whenever I load a GLB asset from online using :

  this.app.assets.loadFromUrlAndFilename(url, "headModel.glb", "container", (err, asset) => {
         let renderAsset = asset.resource.renders[0];

        this.head.render.asset = renderAsset;
        this.head.collision.renderAsset = renderAsset;
  });

the rendering works fine and shows the head but the collision doesn’t match the render.
I tried using simple tricks like disabling & enabling collision/entity but it doesn’t seem to be working,

I used a custom script full of raycast to find out if my collision was lost somewhere in space but raycasting in all directions didn’t find anything

If it is a single entity, you should have no problem with debug rendering it. Unless, it is a high poly model and it tries to render thousands of lines. What is your vertex or tri count on that model?

Generally, the physics models are simplified versions of visual ones. A head is usually just a simple sphere. Often, the whole character is just a single capsule.

It is quite a high poly, around 10k vertices, and sadly I’m not allowed to lower its resolution.

In short, I need that exact head topology for fitting products on it

EDIT : Also I believe that if the AmmoDebug script doesn’t work is because for some reason app.drawLines doesn’t work anymore in my project, I have to figure out why later but it’s not a feature I usually need

I suspect you just have it too large. I would try to set this.head scale to [0.01, 0.01, 0.01] before adding a collision component to it. Also note that Ammo is not great a dealing with high-poly trimeshes. It can start stuttering at some point. I would also still try to debug render it. Even if it slows down your pc, at least you would be able to see if the collision mesh is there, its orientation and scale.

You can try booklet from yaustar, just launch this bookmark in your launch window. You don’t need to add anything to your project. It includes the Ammo debug drawer.

make sure your camera uses Immediate layer, and that this layer is specified in your Sub-layers in the settings.

Actually my Head is already scaled down to 0.01, I had to even use a separate sub-entity with scale 0.0018 to do my 0.000018 scale since I couldn’t enter it in the editor, however normally there should be no issue at all since my Render asset for both collision and render are the same asset, the head entity is already scaled down so the render shows the proper size.

I also did a serie of Raycast at 100 Distance in a cylinder pattern to find any big object flying, all returned null so I don’t believe there is any floating head somewhere :S

I’ll try scaling it up/down see if raycasts show any results in general

Try casting from -veryfar to +veryfar, passing center where model is. If you are casting from the center, you might be hitting backfaces.

Too early deduction sorry

The sweet (ironically) part about the models I receive is that the mesh is not centered on 0

Turns out it was the mesh my client sent me that had issue, opening it and resaving it in blender fixed the issue…

1 Like