-
-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for generating slots from blender custom properties #265
base: master
Are you sure you want to change the base?
Conversation
@marwie i think it should be export function Model({ foo, bar, ...props }) {
const { nodes, materials } = useGLTF('/untitled-transformed.glb')
return (
<group {...props} dispose={null}>
<mesh geometry={nodes.Tower_Brick_MT_0.geometry} material={materials.Brick_MT} position={[0, 7.561, 0]} rotation={[-Math.PI / 2, 0, 0]} />
<mesh geometry={nodes.Tower_Details_MT_0.geometry} material={materials.Details_MT} position={[0, 7.561, 0]} rotation={[-Math.PI / 2, 0, 0]} />
<mesh geometry={nodes.Tower_Glass_MT_0.geometry} material={materials.Glass_MT} position={[0, 7.561, 0]} rotation={[-Math.PI / 2, 0, 0]} />
<mesh geometry={nodes.Tower_Plaster_MT_0.geometry} material={materials.Plaster_MT} position={[0, 7.561, 0]} rotation={[-Math.PI / 2, 0, 0]}>
{foo}
</mesh>
<mesh geometry={nodes.Tower_Roof_MT_0.geometry} material={materials.Roof_MT} position={[0, 7.561, 0]} rotation={[-Math.PI / 2, 0, 0]}>
{bar}
</mesh>
</group>
)
} otherwise it would spread props all over the root mesh (and could also introduce some real problems, like naming a slot "position". it would require though that slots for all nodes are known beforehand, just some javascript mapping and reducing. |
Ah that's a good point. I missed that. I think currently all objects are collected at the start of codegen anyways so collecting that info could be added there. What do you think about the callbacks idea (or slots becoming functions) what I mentioned at the end of the post? |
wouldn't be necessary imo. defining functions inline is considered bad because this isn't a true component, it would un-mount/re-mount every render. if it contained useEffect(() => ..., []) it would fire every render as well. as for accessing parents, you can do this <Tower roof={<Foo />} />
function Foo(props) {
const ref = useRef()
useLayoutEffect(() => {
console.log(ref.current.parent)
}, [])
useFrame((state, delta) => {
console.log(ref.current.parent)
})
return <group ref={ref} />
} |
f19727c
to
1d64753
Compare
Example output: export function Model({ cat, screen, ...props }) {
const { nodes, materials } = useGLTF('/untitled.glb')
return (
<group {...props} dispose={null}>
<group rotation={[-Math.PI / 2, 0, 0]} scale={0.002}>
<group rotation={[Math.PI / 2, 0, 0]}>
<group>
<mesh geometry={nodes.defaultMaterial001.geometry} material={materials.wire_134006006} />
{cat}
</group>
<group>
<mesh geometry={nodes.defaultMaterial.geometry} material={materials.Screen} />
{screen}
</group>
</group>
</group>
</group>
)
} Objects that have a slot property would also not be pruned with this change. |
Wondering, could it make sense to have a differentiation between something like Other than that, very much looking forward to this, being able to decouple the generated code and lift dependencies to the parent component, not having to re-edit the jsx every time you update your meshes/scene will help a lot with more demanding usecases where you are iterating a lot (like gamedev). |
Let me know if there's anything else you'd like to change |
I was wondering how this works with multiple slots. I was testing the process on my end and you can only add one |
@krispya You mean adding multiple slots to the same object in blender? When would you want to do that for example? |
I guess you are right, I was considering something more like a registry. If there is a name collision what happens? |
Multiple objects can have the same slot name (e.g. you can add the same custom property slot name in blender to multiple objects). The slotted objects will then appear in multiple places. export function Model({ my_slot, ...props }) {
const { nodes, materials } = useGLTF('/untitled.glb')
return (
<group {...props} dispose={null}>
<group rotation={[-Math.PI / 2, 0, 0]} scale={0.002}>
<group rotation={[Math.PI / 2, 0, 0]}>
<group>
<mesh geometry={nodes.defaultMaterial001.geometry} material={materials.wire_134006006} />
{my_slot}
</group>
<group>
<mesh geometry={nodes.defaultMaterial.geometry} material={materials.Screen} />
{my_slot}
</group>
</group>
</group>
</group>
)
} Is that what you meant? |
What about multiple different props, i.e. my_slot1, my_slot2? |
Like here? #265 (comment) Or do you mean something else? |
Looks good to me. |
Ah yeah that's what I meant! |
5088bf9
to
9b996a9
Compare
@drcmda just squashed and rebased on the latest release and updated the example here: https://codesandbox.io/p/sandbox/xenodochial-dawn-77st43 |
@drcmda let me know if you'd like to have anything else changed or checked |
@marwie could you solve the conflicts? |
f3fc5a6
to
6d727db
Compare
@drcmda done |
6d727db
to
9c12d06
Compare
@drcmda hi do you have any further concerns regarding the feature? :) |
9c12d06
to
22b1b02
Compare
This PR allows to use custom properties defined in Blender to be used as custom react slots.
Example
https://codesandbox.io/p/sandbox/xenodochial-dawn-77st43
Usage:
slot
and enter a value e.g."mySlot"
gltfjsx myModel.glb
as usual{ props.mySlot }
which can now be access from outsideExample
Codegen
Screenshots
20240621-153139_index.js_-_nodebox_-_CodeSandbox_-_Google_Chrome-logo.mp4
Further Ideas (not implemented)
Props could possibly also / instead be functions that take a ref argument - perhaps with a different property name in blender like
callback: "myCallback"
. I'm not sure about drawbacks of potentially creating a lot of refs vs just injecting properties and/or if this is already possible with the code in this PR through some other hook.E.g. codegen would then create refs for all objects that need them and invoke the callback methods
This PR is funded by needle