Giter VIP home page Giter VIP logo

Comments (15)

drcmda avatar drcmda commented on May 18, 2024 1

useImperativeUpdate is a nice idea btw, it could still be useful.

I don't see how yours would work, you don't pass a ref. It could return one maybe?

const ref = useUpdate( 
  geometry => {
    geometry.addAttribute('position', getCubeVertices(cube.x, cube.y, cube.z))
    geometry.attributes.position.needsUpdate = true
    geometry.computeBoundingSphere()
  }, 
  [cube.x, cube.y, cube.z] // execute only if these change
)
return <bufferGeometry ref={ref} />

Or, accept one as the 3rd param optionally, so that you can re-use refs for multiple purposes

const ref = useRef()
useUpdate(() => {}, [...], ref)
return <bufferGeometry ref={ref} />

from react-three-fiber.

drcmda avatar drcmda commented on May 18, 2024

I think the problem is always the same, we have data, and if we don't manage it, we end up with a salad of three js objects. So a possible solution would be to put as much into the graph as we can, so that only the raw data remains as state, while the view reflects, without re-creating objects.

In this case for instance, something like this could work:

function Test() {
  const vertices = useMemo(() => new Float32Array([
    -1.0, -1.0, 1.0,
    1.0, -1.0, 1.0,
    1.0, 1.0, 1.0,
    1.0, 1.0, 1.0,
    -1.0, 1.0, 1.0,
    -1.0, -1.0, 1.0,
  ]))
  const update = useCallback(({ parent }) => {
    parent.attributes.position.needsUpdate = true
    parent.computeBoundingSphere()
  }), [])
  return (
    <mesh>
      <bufferGeometry attach="geometry">
        <bufferAttribute
          attachObject={['attributes', 'position']}
          array={vertices} 
          itemSize={3}
          onUpdate={update} />
      </bufferGeometry>
      <meshBasicMaterial attach="material" />
    </mesh>
  )
}

It doesn't work right now, because THREE.BufferGeometry.attributes is an object. But i am thinking anyway to retreat from using "name". If we have:

  • attach={target} // just overwrites, whatever the target is
  • attachArray={target} // appends on mount, removes on unmount
  • attachObject={[target, name]} // adds on mount, deletes on unmount

Then it could know what to do, and we could drive any three object, no matter what it is.

Another thing that needs solving is the onUpdate callback. Not sure if the parent is available like this right now. But in any way it should be.

from react-three-fiber.

ryanking1809 avatar ryanking1809 commented on May 18, 2024

Oh, I was thinking a more dumb run the update function instead of recreating the geometry - but this looks like it could work very nicely!

Perhaps you could just use refs in the update callback?

from react-three-fiber.

ryanking1809 avatar ryanking1809 commented on May 18, 2024

I missed your other comment! I think I prefer the 3rd param ref option. It feels more similar to how I would use useMemo. You apply the ref to the component and use it in the update function.

from react-three-fiber.

drcmda avatar drcmda commented on May 18, 2024

Alright, i'll get to it then, we need this as well at work. I don't think i can finish this until next week though, maybe monday.

from react-three-fiber.

ryanking1809 avatar ryanking1809 commented on May 18, 2024

Oh, no rush at all! Thanks for all your effort in building this!

from react-three-fiber.

drcmda avatar drcmda commented on May 18, 2024

@ryanking1809 the updates are in. useUpdate and attach/attachArray/attachObject https://github.com/drcmda/react-three-fiber/tree/2.0#objects-and-properties

Small warning, "name" has been deprecated on from the latest beta.

Makes it possible to handle buffer-attributes reactively

from react-three-fiber.

ryanking1809 avatar ryanking1809 commented on May 18, 2024

Great, I'll have a play! 2.0.0-beta.4?

from react-three-fiber.

drcmda avatar drcmda commented on May 18, 2024

Yep.

from react-three-fiber.

ryanking1809 avatar ryanking1809 commented on May 18, 2024

I'm just about to jump on a plane but might be able to make a sandbox later.
I have the following:

const BarGeometry = ({ bar }) => {
    const ref = useRef()
	console.log("TCL: BarGeometry -> bar", bar, ref)
    const vertices = verticeMap(bar.start, bar.end, bar.yIndex, 0)
    return (
        <bufferGeometry ref={ref}>
            <bufferAttribute attachObject={['attributes', 'position']} array={vertices} itemSize={3} />
        </bufferGeometry>
    )
}

export const BarMesh = ({bar}) => {
    const ref = useRef()
    console.log("TCL: BarMesh -> bar", bar, ref)
    return (
        <mesh ref={ref}>
            <BarGeometry attach="geometry" bar={bar} />
            <meshNormalMaterial attach="material" />
        </mesh>
    )
}

It doesn't appear to render BarMesh. When you look at the ref for BarGeometry the attribute look correct but boundingBox and boundingSphere are null. Is there a way to run the following functions?

geometry.attributes.position.needsUpdate = true;
geometry.computeBoundingSphere();

from react-three-fiber.

drcmda avatar drcmda commented on May 18, 2024

onUpdate={self => ...} . it gives you the instance, and it should have the parent as well.

from react-three-fiber.

drcmda avatar drcmda commented on May 18, 2024

Here's an example: https://codesandbox.io/s/v8k3z74kky

Had to make a change for this to work, it's in the latest beta. Also looks like array and itemSize wasn't enough, bufferAttribute needed the "count" property to function correctly.

from react-three-fiber.

ryanking1809 avatar ryanking1809 commented on May 18, 2024

Great, that does the trick! Thanks!

Any reason why your example doesn't need to check the parent exists and mine does? I have to do self.parent && self.parent.computeBoundingSphere() Not a huge issue but it's a bit odd considering my code almost exactly the same.

export const BarMesh = ({ bar }) => {
    const vertices = useMemo(
        () => verticeMap(bar.start, bar.end, bar.yIndex, bar.selected ? 100 : 0),
        [bar.start, bar.end, bar.yIndex, bar.selected]
    )
    const update = useCallback(self => {
        self.needsUpdate = true
        self.parent && self.parent.computeBoundingSphere()
    }, [])
    return (
        <mesh>
            <bufferGeometry attach="geometry">
                <bufferAttribute
                    attachObject={['attributes', 'position']}
                    array={vertices}
                    count={vertices.length / 3}
                    itemSize={3}
                    onUpdate={update}
                />
            </bufferGeometry>
            <meshNormalMaterial attach="material" />
        </mesh>
    )
}

from react-three-fiber.

ryanking1809 avatar ryanking1809 commented on May 18, 2024

Oops ignore that - forgot to restart the server after updating to the latest beta!

from react-three-fiber.

drcmda avatar drcmda commented on May 18, 2024

There was indeed a bug, onUpdate was called too early.

from react-three-fiber.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.