Provide a way to access three.js objects from child components #1782
Replies: 6 comments 6 replies
-
Are you trying to create something similar to https://github.com/pmndrs/gltfjsx or does this have to do with the attach API? |
Beta Was this translation helpful? Give feedback.
-
Yes, I basically want to be able to apply the "attach" command to the meshes I've received from the loader in order to assign the materials. That's a cool tool, but my use case is to grab geometry from web-based geometry streams. I guess I could do something declarative using the data in the stream, but I'm trying to get it working with a three.js loader class. I'd prefer to use the react-three-fiber |
Beta Was this translation helpful? Give feedback.
-
for more context, this is what I'm trying to avoid doing (replicating all the options for materials etc as props):
|
Beta Was this translation helpful? Give feedback.
-
you can do that, you can attach stuff to components ootb. real world example: https://github.com/pmndrs/drei#instances <Instances
limit={1000} // Optional: max amount of items (for calculating buffer size)
range={1000} // Optional: draw-range
>
<boxGeometry />
<meshStandardMaterial /> this works because the Instances component spreads props over its view: function Instances(props) {
return <mesh {...props} ... as for the 2nd part const speckleGroup = useLoader(SpeckleLoader, JSON.stringify(options));
//TODO access materials etc here and apply to all the loaded geometries.
console.log(props.children);
return (
<Suspense fallback={<Loader />}>
<primitive object={speckleGroup} />
</Suspense> the suspense is not correct. useLoader is causing the component to suspend, which then triggers the outmost suspense boundary. |
Beta Was this translation helpful? Give feedback.
-
it seems to me your problem is primitive. you shouldn't try to give a primitive declarative children because it's an external, imperative object. you could still just spread props though and it would basically work (materials, etc) but .... that would be anti react and anti three. first of all, most loaders give you a scene or a group, these dont have materials, their nested innards do, and that's where all bets are off. mutating primitives will open a gaping hell hole, i would recommend not doing it. you can only declare something because you know it, that's why gltfjsx works. if the data is unknown, you can't declare it. unless you know where it needs to be applied to. |
Beta Was this translation helpful? Give feedback.
-
ps heres an example of a component that loads and that takes children: https://codesandbox.io/s/gltf-simple-example-forked-xuljn?file=/src/App.js but again, the only reason this works is because i know the structure. if i didn't then there would be no other way than to traverse imperatively and mutate the materials, that's what separates these two worlds: imperative and declarative. |
Beta Was this translation helpful? Give feedback.
-
If this feature already exists, I couldn't find the solution.
I'm looking to add my own components that get treated like native meshes etc in terms of being able to apply materials etc.
The pattern I'm looking to use is as follows:
If I used a 'mesh' react node within this component, I could pass the children on. But in this case I can't do that because I'm using a loader within SpeckleStreamGeom to grab geometry from a Speckle stream. The mesh objects have all been created by the loader. I basically want to 'forward' all the child nodes (e.g. meshBasicMaterial) onto those code-created mesh objects.
I don't think there is a way to do that with the reconciler as its currently set up. I'd appreciate any input if there is a more elegant way to handle this.
Beta Was this translation helpful? Give feedback.
All reactions