xml3d / xml3d.js

The WebGL/JS implementation of XML3D
Other
74 stars 25 forks source link

Mouseover seems a bit inaccurate #90

Closed judithhartmann closed 9 years ago

judithhartmann commented 9 years ago

I wanted to implement a function that highlights a mesh when hovering over it.

I used the onmouseover event of the mesh for that and then used a shader uniform in a custom shader that colors the hovered mesh.

When I tested it, is is a bit inaccurate, especially when using camera transformation.

Here is the testfile in a gist: https://gist.github.com/judithhartmann/ae7746e5867fc64dd419

or when you want to download it directly https://www.dropbox.com/s/2t6p06r1llaun46/bundleview%20%2820%29.xhtml?dl=0

Why is this so inaccurate?

jasu0x58 commented 9 years ago

The mouseover implementation works as expected. The reason it seems to be inaccurate is that you're changing the mesh position (pos.z *= height) in your custom vertex shader. For picking, and thus for the mouseover implementation, the original unchanged mesh is used. If you remove the mentioned line from the vertex shader you will notice that mouseover works correctly.

The solution to the problem would be to use an Xflow operator (see below) on the mesh data to change the z-coordinate of the mesh's original position according to the height. This ensures that picking and mouseover work on the correct data.

Xflow.registerOperator("xflow.displace", {
    outputs: [{type: "float3", name: "position"}],
    params:  [
        {type: "float3", source: "position"},
        {type: "float", source: "height"},
    ],
    evaluate: function(displacedPosition, originalPosition, height, info) {
        var count = originalPosition.length / 3;
        for (var i = 0; i < count; ++i) {
            var idx = i * 3;
            displacedPosition[idx] = originalPosition[idx];
            displacedPosition[idx + 1] = originalPosition[idx + 1];
            displacedPosition[idx + 2] = originalPosition[idx + 2] * height[0];
        }
    }
});

The operator has to be used in the markup like this:

<mesh onmouseover="onIcicleHover(this)" id="2">
<data compute="position = xflow.displace(oposition, height)">
<!-- mesh data like position, normal, height and color goes here -->
</data>
</mesh>