如何在React-Three-Fiber中为从Rhino3dm文件加载的每个网格部分添加鼠标事件?

huangapple go评论111阅读模式
英文:

How to add mouse events to each mesh part loaded from Rhino3dm file in React-Three-Fiber?

问题

以下是代码部分的翻译:

  1. import "./styles.css";
  2. import * as THREE from "three";
  3. import { useEffect, useMemo, useRef, useState } from "react";
  4. import { Canvas } from "@react-three/fiber";
  5. import { useLoader } from "@react-three/fiber";
  6. import { Rhino3dmLoader } from "three/examples/jsm/loaders/3DMLoader";
  7. import { Environment, OrbitControls} from "@react-three/drei";
  8. import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
  9. import { Suspense } from "react";
  10. const Part = (child) => {
  11. const objRef = useRef();
  12. const [hovered, setHover] = useState(false);
  13. const material = new THREE.MeshStandardMaterial({
  14. color: hovered ? "hotpink" : "orange"
  15. });
  16. return (
  17. <mesh
  18. key={child.id}
  19. ref={objRef}
  20. castShadow
  21. receiveShadow
  22. onPointerOver={(e) => {
  23. e.stopPropagation();
  24. setHover(true);
  25. }}
  26. onPointerOut={(e) => {
  27. e.stopPropagation();
  28. setHover(false);
  29. }}
  30. >
  31. <primitive object={child} material={material} />
  32. </mesh>
  33. );
  34. };
  35. const Model = () => {
  36. // For some reason mouse events don't work well in Rhino3dm.
  37. const object = useLoader(Rhino3dmLoader, "./rhino_logo.3dm", (loader) => {
  38. loader.setLibraryPath("https://cdn.jsdelivr.net/npm/rhino3dm@0.15.0-beta/");
  39. });
  40. const model = object.children.map((child) => Part(child));
  41. // For gltf the below code worked fine.
  42. /* 
  43. const gltf = useLoader(GLTFLoader, "./rhino_logo.glb");
  44. const model = Object.values(gltf.nodes).map((child) => {
  45. if(child.isMesh){
  46. return Part(child)
  47. }
  48. });
  49. */
  50. return model;
  51. };
  52. export default function App() {
  53. return (
  54. <div className="App">
  55. <Canvas>
  56. <Suspense fallback={null}>
  57. <Model />
  58. <OrbitControls />
  59. <Environment preset="sunset" background />
  60. </Suspense>
  61. </Canvas>
  62. </div>
  63. );
  64. }

注意:我只翻译了代码部分,没有包括其他文本内容。

英文:

I want to realize a function that changes color when the mouse is over each mesh part loaded from an Rhino3dm file with react-three-fiber.But in the code below mouse events are not working properly for some reason.

For GLTF, using Object.values(gltf.nodes).map worked fine.
enter image description here

For Rhino3dm, I use object.children.map and I think this is bad.

Do you know the cause and solution?

This is the sandbox URL.
https://codesandbox.io/s/test-rhino3dmloader-wnrty6?file=/src/App.js

  1. import &quot;./styles.css&quot;;
  2. import * as THREE from &quot;three&quot;;
  3. import { useEffect, useMemo, useRef, useState } from &quot;react&quot;;
  4. import { Canvas } from &quot;@react-three/fiber&quot;;
  5. import { useLoader } from &quot;@react-three/fiber&quot;;
  6. import { Rhino3dmLoader } from &quot;three/examples/jsm/loaders/3DMLoader&quot;;
  7. import { Environment, OrbitControls} from &quot;@react-three/drei&quot;;
  8. import { GLTFLoader } from &quot;three/examples/jsm/loaders/GLTFLoader&quot;;
  9. import { Suspense } from &quot;react&quot;;
  10. const Part = (child) =&gt; {
  11. const objRef = useRef();
  12. const [hovered, setHover] = useState(false);
  13. const material = new THREE.MeshStandardMaterial({
  14. color: hovered ? &quot;hotpink&quot; : &quot;orange&quot;
  15. });
  16. return (
  17. &lt;mesh
  18. key={child.id}
  19. ref={objRef}
  20. castShadow
  21. receiveShadow
  22. onPointerOver={(e) =&gt; {
  23. e.stopPropagation();
  24. setHover(true);
  25. }}
  26. onPointerOut={(e) =&gt; {
  27. e.stopPropagation();
  28. setHover(false);
  29. }}
  30. &gt;
  31. &lt;primitive object={child} material={material} /&gt;
  32. &lt;/mesh&gt;
  33. );
  34. };
  35. const Model = () =&gt; {
  36. // For some reason mouse events don&#39;t work well in Rhino3dm.
  37. const object = useLoader(Rhino3dmLoader, &quot;./rhino_logo.3dm&quot;, (loader) =&gt; {
  38. loader.setLibraryPath(&quot;https://cdn.jsdelivr.net/npm/rhino3dm@0.15.0-beta/&quot;);
  39. });
  40. const model = object.children.map((child) =&gt; Part(child));
  41. // For gltf the below code worked fine.
  42. /* 
  43. const gltf = useLoader(GLTFLoader, &quot;./rhino_logo.glb&quot;);
  44. const model = Object.values(gltf.nodes).map((child) =&gt; {
  45. if(child.isMesh){
  46. return Part(child)
  47. }
  48. });
  49. */
  50. return model;
  51. };
  52. export default function App() {
  53. return (
  54. &lt;div className=&quot;App&quot;&gt;
  55. &lt;Canvas&gt;
  56. &lt;Suspense fallback={null}&gt;
  57. &lt;Model /&gt;
  58. &lt;OrbitControls /&gt;
  59. &lt;Environment preset=&quot;sunset&quot; background /&gt;
  60. &lt;/Suspense&gt;
  61. &lt;/Canvas&gt;
  62. &lt;/div&gt;
  63. );
  64. }

答案1

得分: 0

我已经能够在下面解决它!谢谢!!

https://discourse.threejs.org/t/how-to-add-mouse-events-to-each-mesh-part-loaded-from-rhino3dm-file-in-react-three-fiber/48191/2

英文:

I was able to solve it below! Thank you!!

https://discourse.threejs.org/t/how-to-add-mouse-events-to-each-mesh-part-loaded-from-rhino3dm-file-in-react-three-fiber/48191/2

huangapple
  • 本文由 发表于 2023年2月18日 13:45:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75491455.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定