-
-
Notifications
You must be signed in to change notification settings - Fork 131
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
feat: 503 conditional rendering of primitives #514
Changes from 1 commit
cf979fa
5a24eea
5ed02b6
8d52f32
2df1e65
3490c4a
37ab904
b0ba190
de730ef
8408351
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…erties
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -191,25 +191,28 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = { | |||
if (node) { | ||||
let root = node | ||||
let key = prop | ||||
if ( key === 'object' && prevValue !== null) { | ||||
const newInstance = nodeOps.createElement('primitive', false, null, { | ||||
if (key === 'object' && prevValue !== null) { | ||||
alvarosabu marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
// If the prop 'object' is changed, we need to re-instance the object and swap the old one with the new one | ||||
const newInstance = nodeOps.createElement('primitive', undefined, undefined, { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like this doesn't break references in
Whenever the primitive object becomes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @andretchen0 we will need to explicitly mention on the docs that the user needs to animate the Screen.Recording.2024-02-08.at.10.14.03.movThere are several reasons why we need to
This is what happens without the Screen.Recording.2024-02-08.at.10.24.31.movIt's either has this limitation of having to use the ref coming from the custom renderer to animate or
I balance through the first option. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the PR as it currently stands is an improvement. I don't want to stand in the way of improvements. I approved the PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sort of error is an itch I can't stop scratching, so if you want to keep scratching ...
Can you elaborate on unwanted side effects? Technical issues aside, there's a point that isn't clear for me conceptually. To illustrate: <script>
...
const userMesh = new Mesh(...)
userMesh.position.x = 100
const userMesh2 = new Mesh(...)
userMesh2.position.x = 200
</script>
<template>
...
<primitive ref="primitiveRef" :object="userMesh" :position-x="300" />
...
</template>
For R3F, the answer to both is "yes", it seems. Here's a StackBlitz. Notice that the rotation of the TorusRing increments with every frame, but resets whenever it's made the That seems like the right solution to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 197 in 8408351
I understand that this will make a clone, which is required at the moment, but is there a reason why it's necessary to go through There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
One side-effect is that is not possible to pass a ref or reactive as @JaimeTorrealba mentioned in the thread on Discord. With clone, we can ensure that swiping between models is possible.
Yes, the prop has priority because it will overwrite the mesh positions on the setup.
Users shouldn't overwrite vue template refs, wouldn't it be kind of an antipattern? I also see the users complaining about having to do this extra step of
That was to not having to duplicate the same code of the createElement inside of the |
||||
object: nextValue, | ||||
}) | ||||
const blacklistedKeys = ['uuid', 'position', 'rotation', 'scale', 'quaternion'] | ||||
newInstance.uuid = node.uuid | ||||
for (const key in newInstance) { | ||||
if (!blacklistedKeys.includes(key)) { | ||||
node[key] = newInstance[key] | ||||
} | ||||
for (const subkey in newInstance) { | ||||
const target = node[subkey] | ||||
const value = newInstance[subkey] | ||||
if (!target?.set && !isFunction(target)) node[subkey] = value | ||||
else if (target.constructor === value.constructor && target?.copy) target?.copy(value) | ||||
else if (Array.isArray(value)) target.set(...value) | ||||
else if (!target.isColor && target.setScalar) target.setScalar(value) | ||||
else target.set(value) | ||||
} | ||||
// This code is needed to handle the case where the prop 'object' type change from a group to a mesh or vice versa, otherwise the object will not be rendered correctly (models will be invisible) | ||||
if (newInstance.isGroup) { | ||||
node.geometry = undefined | ||||
node.material = undefined | ||||
} | ||||
else { | ||||
delete node.isGroup | ||||
} | ||||
|
||||
} | ||||
|
||||
if (node.isObject3D && key === 'blocks-pointer-events') { | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In
nodeOps.ts
, I mentioned that cloning means that setup references are lost. Below is some demonstration code that can be pasted here.Both
torus
andtorusKnot
continue to exist after theclone
, but they no longer point to the on-screen objects, so the on-screen objects don't update.If the objects aren't
clone()
d innodeOps
, the on-screen shapes will rotate – but other errors pop up.I don't know if there's a workaround here. Just pointing it out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andretchen0 This argument makes me think we should abandon the idea of trying to make
:object
prop reactive, swiping instances without losing the ref is getting too complicated.Users could still use primitives with conditional rendering, I wanted
primitive
to work similar tocomponent
but honestly at this point I don't know how to achieve it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alvarosabu
I don't understand the internals of Tres well enough to have an opinion on the feasibility here.
I'll start reading the source after I finish
<AnimatedSprite />
for Cientos.I agree that this is a worthwhile goal. It'd be great if it "just works".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andretchen0 let me know if you are up to a pair-programming call to discuss the internals when you get free let me know, we definitely can use your knowledge and your quality feedback inside of the custom renderer code. 💚
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alvarosabu
Sure thing. That could be fun!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @andretchen0 I created a thread on the core team discord channel discussing this but to give a summary:
I found a way of making it work (animations), the only constraint is that the object passed through
:object
needs to be of the same type (mesh -> mesh) (group -> group). If we do (mesh -> group), it doesn't work anymore.Screen_Recording_2024-02-02_at_12.43.44.mov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I'll go read the Discord.