xeokit / xeokit-sdk

Open source JavaScript SDK for viewing high-detail, full-precision 3D BIM and AEC models in the Web browser.
https://xeokit.io
Other
728 stars 287 forks source link

Fix inability to set certain objects unpickable #879

Closed Kurtil closed 1 year ago

Kurtil commented 2 years ago

Some objects may be still picked even if there are not pickable.

Steps to reproduce the behavior: 1 - Serve the following code as index.html 2 - try to pick the red door 3 - the door is colorized on green on hover and clicking on it log it on the console as it is picked.

Expected behaviour: It may not be picked as the object is not pickable (see the logged object on the console : pickable: false)

code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>xeokit Example</title>
    <style>
      #myCanvas {
        width: 500px;
        height: 500px;
      }
    </style>
  </head>
  <body>
    <canvas id="myCanvas"></canvas>
  </body>
  <script type="module">
    //------------------------------------------------------------------------------------------------------------------
    // Import the modules we need for this example
    //------------------------------------------------------------------------------------------------------------------

    import { Viewer, XKTLoaderPlugin } from "../dist/xeokit-sdk.es.js";

    //------------------------------------------------------------------------------------------------------------------
    // Create a Viewer, arrange the camera
    //------------------------------------------------------------------------------------------------------------------

    const viewer = new Viewer({
      canvasId: "myCanvas",
      transparent: true,
    });
    window.viewer = viewer;

    viewer.camera.eye = [-3.933, 2.855, 27.018];
    viewer.camera.look = [4.4, 3.724, 8.899];
    viewer.camera.up = [-0.018, 0.999, 0.039];

    //----------------------------------------------------------------------------------------------------------------------
    // Create a xeokit loader plugin, load a model, fit to view
    //----------------------------------------------------------------------------------------------------------------------

    const xktLoader = new XKTLoaderPlugin(viewer);

    const sceneModel = xktLoader.load({
      id: "myModel",
      src: "../assets/models/xkt/v8/ifc/Duplex.ifc.xkt",
      edges: true,
    });

    //------------------------------------------------------------------------------------------------------------------
    // Set all objects un-pickable and grey, except for the slab in front of the door, which we'll set pickable and blue
    //------------------------------------------------------------------------------------------------------------------

    sceneModel.on("loaded", () => {
      viewer.scene.setObjectsPickable(["1s1jVhK8z0pgKYcr9jt7AB"], false);
      viewer.scene.setObjectsColorized(["1s1jVhK8z0pgKYcr9jt7AB"], [1, 0, 0]);
    });

    //------------------------------------------------------------------------------------------------------------------
    // Click Entities to colorize them
    //------------------------------------------------------------------------------------------------------------------

    var lastEntity = null;
    var lastColorize = null;

    viewer.cameraControl.on("picked", pickResult => {
      console.log("picked", pickResult.entity);
    });

    viewer.cameraControl.on("hover", pickResult => {
      if (!lastEntity || pickResult.entity.id !== lastEntity.id) {
        if (lastEntity) {
          lastEntity.colorize = lastColorize;
        }

        lastEntity = pickResult.entity;
        lastColorize = pickResult.entity.colorize.slice();

        pickResult.entity.highlighted = false;
        pickResult.entity.colorize = [0.0, 1.0, 0.0];
      }
    });

    viewer.cameraControl.on("hoverOut", () => {
      if (lastEntity) {
        lastEntity.colorize = lastColorize;
        lastEntity = null;
      }
    });
  </script>
</html>

764fd7ae26fe81cf1b90826f6e7dd837

Xeokit Version 2.2.2

Kurtil commented 2 years ago

In the same example, setting all objects but one (the door) as unpickable does not work properly. Some objects are still pickable.

sceneModel.on("loaded", () => {
  const allIdsExceptTheFrontDoor = Object.values(viewer.scene.objects)
    .map(o => o.id)
    .filter(id => id !== "1s1jVhK8z0pgKYcr9jt7AB");
  viewer.scene.setObjectsPickable(allIdsExceptTheFrontDoor, false);
});

3381281fa2e5827c1f2420448e11016a