model with silhouette and wireframe


I'd like to use kind of a wireframe mode in my application, where gltf models can be selected with a click. "Selection" is applied with a silhouette.

Mixing up these two results in some strange behavior. Apparently it is not possible to have a silhouette with enabled .debugWireframe option.

I know, the debugWireframe option is only meant for debugging purposes, but I looked into that function and it only sets a new primitiveType in _nodeCommands of the model. But it seems this is not being updated accordingly, when having silhouette enabled.

I made a Sandcastle example, which shows the effect:

So my questions are:

Why should it be impossible to set a new primitiveType, when silhouetteSize != 0? What do they have to do which each other?

What would be a alternative and "stable" method to implement a working wireframe, without using the debugWireframe flag? It does not have to be efficient, setting the primitiveType seems to be straightforward, but I somehow need to force the update.

Another mark on a first question: Apparently the options are not mutually exclusive, when experimenting with a transparent model (alpha = 0.9), there is a silhouette in wireframe mode.

The combination of debug wireframe and silhouettes is just something we overlooked. It can be fixed by changing Model.updateWireframe to the code below. Since it is a debug feature and not super high priority I’ll just leave the code here rather than open a PR right away.

We haven’t implemented a stable wireframe mode because it’s more complicated than setting the primitive type. One thing that’s wrong with the debug wireframe is lines segments from separate areas of the mesh tend to connect. You can see that with the stray lines on the plane (which unfortunately affects the silhouette too). A full solution would be to edit the model indices array but that requires too much architecture work. And unfortunately WebGL doesn’t have glPolygonMode, the standard way of drawing wireframes in OpenGL.

But the code is here if it comes in handy:

function updateWireframe(model) {
    if (model._debugWireframe !== model.debugWireframe) {
        model._debugWireframe = model.debugWireframe;

        // This assumes the original primitive was TRIANGLES and that the triangles
        // are connected for the wireframe to look perfect.
        var primitiveType = model.debugWireframe ? PrimitiveType.LINES : PrimitiveType.TRIANGLES;
        var nodeCommands = model._nodeCommands;
        var length = nodeCommands.length;

        for (var i = 0; i < length; ++i) {
            var nodeCommand = nodeCommands[i];
            nodeCommand.command.primitiveType = primitiveType;
            if (defined(nodeCommand.command2D)) {
                nodeCommand.command2D.primitiveType = primitiveType;
            if (defined(nodeCommand.silhouetteModelCommand)) {
                nodeCommand.silhouetteModelCommand.primitiveType = primitiveType;
            if (defined(nodeCommand.silhouetteModelCommand2D)) {
                nodeCommand.silhouetteModelCommand2D.primitiveType = primitiveType;
            if (defined(nodeCommand.translucentCommand)) {
                nodeCommand.translucentCommand.primitiveType = primitiveType;
            if (defined(nodeCommand.translucentCommand2D)) {
                nodeCommand.translucentCommand2D.primitiveType = primitiveType;