ThatOpen / engine_components

MIT License
346 stars 135 forks source link

Highlighted outline is projected in wrong place #501

Closed mkarklins closed 1 month ago

mkarklins commented 1 month ago

Describe the bug 📝

So, I added a highlighter with an outline on click. I would expect that the outline closely matches the BIM element, but the outline in some cases is way off the actual element.

This seems to be apparent only when you are streaming 2+ IFC files one on top of another. For a single streamed IFC file it seems to be working fine.

https://github.com/user-attachments/assets/808d7e8e-1a36-44eb-b6b1-c1dbda4a23c7

Reproduction ▶️

No response

Steps to reproduce 🔢

Here's a react component I used to show the problem.

import { useEffect, useRef } from "react";
import Stats from "stats.js";
import * as OBC from "@thatopen/components";
import * as OBCF from "@thatopen/components-front";
import * as THREE from "three";

const BIMStreamingComponent = () => {
  const containerRef = useRef(null);

  useEffect(() => {
    const components = new OBC.Components();
    const worlds = components.get(OBC.Worlds);

    const world = worlds.create<
      OBC.SimpleScene,
      OBC.SimpleCamera,
      OBCF.PostproductionRenderer
    >();

    world.scene = new OBC.SimpleScene(components);
    if (containerRef.current)
      world.renderer = new OBCF.PostproductionRenderer(
        components,
        containerRef.current
      );

    world.camera = new OBC.SimpleCamera(components);

    components.init();

    if (world.renderer) world.renderer.postproduction.enabled = true;
    world.scene.setup();
    world.camera.controls.setLookAt(12, 6, 8, 0, 0, -10);

    const grids = components.get(OBC.Grids);
    grids.create(world);

    // Make the background of the scene transparent
    world.scene.three.background = null;

    const highlighter = new OBCF.Highlighter(components);
    highlighter.setup({ world });

    const outliner = components.get(OBCF.Outliner);
    outliner.world = world;
    outliner.enabled = true;

    outliner.create(
      "hightlightOutline",
      new THREE.MeshBasicMaterial({
        color: 0xbcf124,
        transparent: true,
        opacity: 0.5,
      })
    );

    highlighter.events.select.onHighlight.add((fragIdMap) => {
      outliner.clear("hightlightOutline");
      outliner.add("hightlightOutline", fragIdMap);
    });

    // Get the IFC streamer
    const loader = components.get(OBCF.IfcStreamer);
    loader.world = world;

    // Set the base URL for the streamer
    loader.url =
      "https://wbuploadsdev.blob.core.windows.net/wb-uploads-dev/38/";

    const uuids: string[] = [];

    // Function to stream the given model
    const loadModel = async (
      geometryURL: string,
      propertiesURL: string | undefined
    ) => {
      const rawGeometryData = await fetch(geometryURL);
      const geometryData = await rawGeometryData.json();
      let propertiesData;
      if (propertiesURL) {
        const rawPropertiesData = await fetch(propertiesURL);
        propertiesData = await rawPropertiesData.json();
      }
      const model = await loader.load(geometryData, true, propertiesData);
      console.log(model);

      model.items;

      uuids.push(model.uuid);
    };

    const models = [
      [
        "https://wbuploadsdev.blob.core.windows.net/wb-uploads-dev/38/fgpaj1-420pohistvoifc-geometries-streaming.json",
        "https://wbuploadsdev.blob.core.windows.net/wb-uploads-dev/38/fgpaj1-420pohistvoifc.ifc-processed-properties.json",
      ],
      [
        "https://wbuploadsdev.blob.core.windows.net/wb-uploads-dev/38/fgpaj1-420gradbena-delaifc-geometries-streaming.json",
        "https://wbuploadsdev.blob.core.windows.net/wb-uploads-dev/38/fgpaj1-420gradbena-delaifc.ifc-processed-properties.json",
      ],
    ];

    models.forEach((model) => {
      // Start streaming the model
      loadModel(model[0], model[1]);
    });

    // Update the scene each time the user stops the camera
    world.camera.controls.addEventListener("sleep", () => {
      loader.culler.needsUpdate = true;
    });

    // Enable caching for the loader
    loader.useCache = true;

    // Customize the loader
    loader.culler.threshold = 0.00000001;
    loader.culler.maxHiddenTime = 100000000;
    loader.culler.maxLostTime = 300000000;
  }, []);

  return (
    <div
      id="container"
      ref={containerRef}
      style={{ width: "100%", height: "100vh" }}
    ></div>
  );
};

export default BIMStreamingComponent;

System Info 💻

Using latest:

    "@thatopen/fragments": "^2.2.0",
    "@thatopen/components": "^2.2.11",
    "@thatopen/components-front": "^2.2.2",


### Used Package Manager 📦

npm

### Error Trace/Logs 📃

_No response_

### Validations ✅

- [X] Read the [docs](https://docs.thatopen.com/intro).
- [X] Check that there isn't [already an issue](https://github.com/ThatOpen/engine_components/issues) that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a repository issue and not a framework-specific issue. For example, if it's a THREE.js related bug, it should likely be reported to [mrdoob/threejs](https://github.com/mrdoob/three.js) instead.
- [X] Check that this is a concrete bug. For Q&A join our [Community](https://people.thatopen.com/).
- [X] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.
CabeDigicorp commented 1 month ago

I found the same issue, also only when multiple IFC files are loaded.

fethigurcan commented 1 month ago

This issue is same for me, it happens when we use multiple models and it happens for non-first models. Hightlight is ok but Outliner draws at wrong place.

agviegas commented 1 month ago

Should be solved from @thatopen/components-front@2.3.4!

CabeDigicorp commented 1 month ago

Looks fine now, thank you!