Decals and "Setting vertex data kind ‘position’ with an empty array"

Hi there, @Blake and @Evgeni_Popov:

First, I apologize for the missing of a PG here, but my scene is very large and intended to be used in a non-public project. Anyway, I’m only looking for any general guidance and tips here.

The case is that, I’m experimenting a strange issue related to Decals.

In order to identify the perfect place for my decals, I’m using a code like this over a running scene, intended to capture the decal’s data:

_scene.onPointerObservable.add(function (evt) {
    switch (evt.type) {
        case BABYLON.PointerEventTypes.POINTERPICK:
            var pickResult = _scene.pick(_scene.pointerX, _scene.pointerY);
            if (pickResult.hit) {
                //written data to be noted in order to be used later
                alert("Mesh: " + pickResult.pickedMesh + "\nPoint: " + pickResult.pickedPoint + "\nNormal: " + pickResult.getNormal(true));

                //I take this opportunity to show the decal and check is all OK
                var decalMat = new BABYLON.StandardMaterial("decalMat", _scene);
		        decalMat.diffuseTexture = new BABYLON.Texture("/assets/textures/dirt.png", _scene);
		        decalMat.diffuseTexture.hasAlpha = true;
		        decalMat.zOffset = -2;
		        //
		       var decalMesh= BABYLON.MeshBuilder.CreateDecal("decal", pickResult.pickedMesh, {
                   normal: pickResult.getNormal(true),
	               position: pickResult.pickedPoint,
		           size: new BABYLON.Vector3(0.1, 0.1, 0.1)
	            });
                decalMesh.material = decalMat;
             }
             break;
        ...

As I want to create all my decals by code, I only use the previous code in order to take note of the decal-related data from the “alert”. Those data will be written down later in the following decal creation code (see XXX_FROM_ALERT_OUTPUT in the following code)…

...
//1) material for the decal
var decalMat = new BABYLON.StandardMaterial("decalMat", _scene);
decalMat.diffuseTexture = new BABYLON.Texture("/assets/textures/dirt.png", _scene);
decalMat.diffuseTexture.hasAlpha = true;
decalMat.zOffset = -2;
//2) the decal itself
var decalMesh= BABYLON.MeshBuilder.CreateDecal("decal", scene.getNodeByName(MESH_FROM_ALERT_OUTPUT), {
    normal: NORMAL_FROM_ALERT_OUTPUT,
    position: POSITION_FROM_ALERT_OUTPUT,
    size: new BABYLON.Vector3(0.1,0.1,0.1)
});
decalMesh.material = decalMat;
...

Doing so, sometimes it works and other times I get the infamous “Setting vertex data kind ‘position’ with an empty array”.

How is that possible that the same decal-creation-data used in the interactive creation of them (first block of code shown) is not valid (sometimes) when using that same data in the same scene in order to re-create that same decals from that data (second block of code shown)?

In a more specific way, how it can be that BJS complains about “Setting vertex data kind ‘position’ with an empty array” being position a not empty array at all?

May it be that weird behavior related with the fact that decals are working only with not-animated geometry? I’m not done yet a comprehensive survey on that.

May it be related with optimization tweaks I’m conducting in the scene?

Any help on this?

Thanks for your time.

Hmm if the mesh passed to CreateDecal is eg a parent/root mesh without vertex data or if it’s a disposed mesh without vertex data it will trigger that warning IIRC… Maybe try logging mesh.getTotalVertices() for the mesh right before it’s passed to CreateDecal to make sure it has vertex/position data? But that’s all I can think of RN without playing with a repro… :thinking:

Try to see if it’s not the same problem as:

Hi there, @Blake

My problem with the PG is, of course, that I’ve tried but can’t reproduce the issue in a trivial scene.

I’m going to tweak here and there in my scene, in order to see if I can find out more on all this.

Thanks for your time.

Good afternoon, @Evgeni_Popov:

I saw the question thread you’re pointing out, but in my case I’m very certain I’m using the correct mesh, as I can see its name is the intended to be when I click/tap on it in order to create the decal.

I’m going to see if I can find out any more hints on all this.

Thanks for your time.

Hi there, @Blake:

Ok. this was something that I was paying attention meanwhile debugging this issue.

When I click/tap on the “offending” mesh (as said this is not always the case), in order to have access to the decal-related values I need to re-create it later in my production code, the “pickResult.pickedMesh” dump shows things like this:

Mesh: Name: AscensorCompleto1:ChasisCabinaPuerta:PuertaCabina:TapaOperador_geo, isInstance: YES, # of submeshes: 1, n vertices: 446, parent: AscensorCompleto1:ChasisCabinaPuerta:PuertaCabina:OperadorPiezas_grp
Point: {X: 0.9138821210292234 Y: 7.652108213358165 Z: 0.8205000162124634}
Normal: {X: 1.5670804414289845e-16 Y: 0.000006169962390482781 Z: 0.9999999999809659}

Of course, different picking points show different “Point” info, but I’m using it always on the same mesh, and you can see that it has 446 vertices indeed.

Taking all this mesh, point and normal, and trying to re-create with them the decal by code (without picking I mean) is what raise the "Setting vertex data kind ‘position’ with an empty array” warning.

Kind regards.

Hi,
You can try to use

getMeshByName

instead of

getNodeByName

and before to create the decal check if the mesh exist

if (scene.getMeshByName(MESH_FROM_ALERT_OUTPUT)) 
 // add decal

Hi there, @MarianG:

Of course, that has been checked with getNodeByName, and as expected using getMeshByName shows the same wrong behavior.

As stated, very weird that this code raises the empty array warning:

...
if(_scene.getNodeByName(params.node)){
    var decalMesh = BABYLON.MeshBuilder.CreateDecal("decal",_scene.getNodeByName(params.node),      {
        normal: new BABYLON.Vector3(params.normal[0], params.normal[1], params.normal[2]),
        position: new BABYLON.Vector3(params.position[0], params.position[1], params.position[2]),
        size: new BABYLON.Vector3(params.size[0], params.size[1], params.size[2])
	});
}
...
}

I mean, even with wrong normal, position and size values (that is not the case), the decal would be created once the mesh parameter in the CreateDecal call is correct, isn’t it?

Having some geometries “accepting” decals on them and others not, all that in the same scene, is what is driving me nuts.

Maybe is something about GLTF/GLB and the implementation of decals in BJS?

Thanks for your time.

Hey,
Is your mesh animated?
Can you create a playground to show the isuue?
I have no ideea what can be :frowning:

Good morning, @MarianG:

The “offending” geometry is part of a mechanism with several animated parts, and other that are completely static. But I’ve checked out that the “decal’s vertex problem” arises in both types.

That said, I have my scene arranged from several GLTF/GLB files and I can see now that decals are working flawless on the geometries coming from files that don’t have animation.

So this is a problem with decals on meshes from my animated GLTF/GLB models, and being such individual meshes (this is the even more weird part) the ones animated or not, I guess.

I apologize for not being able to reproduce this behavior in a simplistic-enough 3D model I could share via PG.

Understood,
it is ok, I think we are close
Did you check this? … there are few more parameters for rigged meshes

Hi there, @MarianG:

In advance of opening this question in the forum, I took a while looking all the entries about decals problems and so.

This one you’re pointing out here is of course very informative, but sadly, not very helpful here as my animations are not driven by skeletons but by keyframes and blendshapes (aka morphtargets).

Said this, I keep on investigating.

Thanks for your time.

Heya, another idea is maybe you’re somehow passing zeros for the decal size? EG the Vector3 constructor defaults to zero values or if you’re calculating the size maybe it’s getting miscalculated? EG here’s the cat example from the docs where I just added line 33 to scale the size vector by 0 to repro the warning. That’s the only other way I found to repro it anyway, just in case… :slight_smile:

Edit: never mind about the debugging part, I forget you’re missing the playground repro that I usually use for that. :thinking: