How to implement multiple cloud points and interact with them separately? - three.js

I display 2 cloud points from a PLY file. I need to trigger events on each cloud point. For example: Move or rotate only 1 cloud points.
My problem:
I think that the event is applied on each points of the 2 cloud points instead of the global model on which I triggered the event. So it takes a very long time to trigger a simple event (like a console.log for example).
Are cloud points correctly implemented?
How to interact with only 1 point cloud?
Code:
Here is the stackblitz to try.
And here is my code:
// 'Stage' and 'OrbitControls' are from #react-three/drei
function App() {
return (
<Canvas camera={{ position: [0, 0, 15] }} orthographic>
<Suspense fallback={null}>
<Stage fallback={null}>
<PLYVisualizationScreen color="green" position={[0, 0, 0]} />
<PLYVisualizationScreen color="blue" position={[-0.2, 0, 0]} />
<OrbitControls makeDefault enableDamping={false} />
</Stage>
<ambientLight intensity={1} />
</Suspense>
</Canvas>
);
}
function PLYVisualizationScreen({ color, position }) {
const geometry = useLoader(PLYLoader, 'bunny.ply');
const ref = useRef();
return (
<points
ref={ref}
position={position}
castShadow
receiveShadow
geometry={geometry}
// onClick={(e) => console.log("click on")}
>
<pointsMaterial
sizeAttenuation
attach="material"
color={color}
depthWrite={false}
size={0.001}
/>
</points>
);
}

Related

react-three-fiber: click with orthographic camera problem

clicks work well with the perspective camera, but don't work with the orthographic camera. If the orthographic camera is enabled, then dead zones appear in which the click does not work. How to make click work correctly with orthographic camera?
https://codesandbox.io/s/damp-water-2oqlvn?file=/src/index.js
function Thing() {
return (
<mesh
onClick={(e) => {
console.log('click')
}}>
<boxGeometry args={[10, 10, 10]} />
<meshNormalMaterial />
</mesh>
)
}
const App = () => {
return (
<Canvas
dpr={window.devicePixelRatio}
gl={{
antialias: true
}}
camera={{
far: Number.MAX_SAFE_INTEGER,
position: [0, 1, 0],
zoom: 10
}}
orthographic>
<Grid infiniteGrid sectionColor="#fff" fadeDistance={100} sectionThickness={0.5} sectionSize={10} />
<Thing />
<CameraControls />
</Canvas>
)
}

export 'Sparkles' (imported as 'Sparkles') was not found in '#react-three/drei'

Anyone knows if Sparkles particle has been removed or not in react-three/drei ? Didn't find anything in migration report of the package. It's giving error while importing.
I used the component like this:
<Canvas style={{ height: '100vh' }} >
<Environment>
<Stars radius={300} depth={60} count={5000} factor={20} saturation={1} fade />
<Cloud
opacity={0.1}
speed={0.1} // Rotation speed
width={20} // Width of the full cloud
depth={2} // Z-dir depth
segments={20} // Number of particles
/>
<pointLight position={[5, 5, 5]} intensity={.3} />
<ambientLight intensity={.3} />
<Box position={[0, 0, 0]} />
<OrbitControls autoRotate autoRotateSpeed={.5} ref={orbitRef} onChange={() => onOrbitChange() } />
</Environment>
</Canvas>
and the box component is:
<mesh
{...props}
ref={mesh}
// scale={active ? 1.5 : 1}
// onClick={(event) => setFlag(true) }
// onPointerOver={(event) => setHover(true)}
// onPointerOut={(event) => setHover(false)}
>
<boxBufferGeometry attach="geometry" args={[3, 3, 3 ]} />
<Sparkles count speed opacity color size scale noise />
</mesh>
I want to use Sparkles in Boxbuffergeometry.

How to get OrbitControls ref

I am trying to access OrbitControls ref as follow:
const controlsRef = useRef<any>();
return (
<>
<Canvas
camera={{
position: [0, 0, 100],
up: [0, 0, 1],
}}
>
<OrbitControls makeDefault ref={controlsRef} />
<ambientLight />
<FakeSphere position={[0, 0, 0]} color="red" />
<FakeSphere position={[100, 100, 0]} color="blue" />
<Nav controls={controlsRef.current} />
</Canvas>
</>
);
Code:
https://codesandbox.io/s/cool-flower-f5qr0?file=/src/App.tsx:949-962
The ref is undefined. Any idea please?
Found a hint hehe (https://github.com/pmndrs/drei/issues/718). Cant get ref from outside Canvas.
For now, add a wrapper over OrbitControls to capture the ref. Not sure if any better solution or not.
const MyControls = (props: any) => {
const { setControls } = props;
const ref = useRef<any>();
useEffect(() => {
if (!ref.current) return;
setControls(ref.current);
}, ref.current);
return <OrbitControls makeDefault ref={ref} />;
};

Sphere not respecting gravity outside plane geometry

I have this simple environment with a sphere and a plane. Both of the objects are wrapped within a Physics component and the physics work, if I remove the plane the sphere will fall. But when I run the sphere outside the plane, the sphere does not fall. I don't know if I have misunderstood something trivial, maybe the plane is wider than what it looks like for example?
I don't think there is a way to set the width/depth of the mesh, so I assume it is the width/depth of the planeBufferGeometry that counts?
main.js:
import { Canvas } from '#react-three/fiber'
import { Sky, PointerLockControls } from '#react-three/drei'
import { Physics } from '#react-three/cannon'
import { Ground, Sphere } from '../components/'
export default function Game(props) {
return (
<>
<Canvas shadows colorManagement camera={{ fov: 45 }}>
<Sky sunPosition={[100, 10, 100]} />
<ambientLight intensity={0.3} />
<pointLight castShadow intensity={2.8} position={[100, 100, 100]} />
<Physics gravity={[0, -106, 0]}>
<Ground />
<Sphere />
</Physics>
<PointerLockControls />
</Canvas>
</>
)
}
Ground.js:
import { usePlane } from '#react-three/cannon'
import { useNormalTexture } from '#react-three/drei'
export default function Ground(props) {
const [ref] = usePlane(() => ({ rotation: [-Math.PI / 2, 0, 0], ...props }))
const [normalMap] = useNormalTexture(32, {
offset: [0, 0],
repeat: [100, 100],
anisotropy: 8
})
return (
<mesh ref={ref} receiveShadow>
<planeBufferGeometry attach="geometry" args={[50, 50]} />
<meshStandardMaterial
attach="material"
normalMap={normalMap}
color="#dadb84"
/>
</mesh>
)
}

How to use PointerLockControls with useFrame

I will implement an effect that I can move camera around an object.
Error example is this and I need to fix it. The difference between this and the latter is that this can update camera position to a 3D object in a model. This example eventually can move camera around a 3D object after updating camera position. But if I follow general use case, i.e. the latter, it can't function correctly. I wonder what's difference between this and the latter.
function Button(props) {
const vec = new THREE.Vector3(0, 3, 5);
const { x, y, z } = props.position;
if (x && y && z) {
vec.set(x, y, z);
}
useFrame((state) => {
const step = 0.1;
state.camera.position.lerp(vec, step);
state.camera.lookAt(0, 0, 0);
state.camera.updateProjectionMatrix();
});
return null;
}
const ModelCanvas = (props) => {
return (
<div className="center">
<Canvas
shadowMap
style={{ background: "#ffffff" }}
camera={{ position: [0, 3, 10], fov: 100 }}
gl={{ antialias: false, logarithmicDepthBuffer: true }}
id="my-canvas"
>
<ambientLight intensity={0.5} />
<pointLight position={[0, 60, -100]} intensity={20} />
<pointLight position={[-50, 0, -50]} intensity={2} />
<spotLight
castShadow
intensity={8}
angle={Math.PI / 10}
position={[10, 10, 10]}
shadow-mapSize-width={2048}
shadow-mapSize-height={2048}
/>
<Suspense fallback={null}>
<Model url={"/compressed.glb"} />
</Suspense>
{/* <PointerLockControls /> */}
<Button position={props.value} />
<PointerLockControls />
</Canvas>
</div>
);
};
And this example functions correctly.
const ModelCanvas = (props) => {
return (
<div className="center">
<Canvas
shadowMap
style={{ background: "#ffffff" }}
camera={{ position: [0, 3, 10], fov: 100 }}
gl={{ antialias: false, logarithmicDepthBuffer: true }}
id="my-canvas"
>
<ambientLight intensity={0.5} />
<pointLight position={[0, 60, -100]} intensity={20} />
<pointLight position={[-50, 0, -50]} intensity={2} />
<spotLight
castShadow
intensity={8}
angle={Math.PI / 10}
position={[10, 10, 10]}
shadow-mapSize-width={2048}
shadow-mapSize-height={2048}
/>
<Suspense fallback={null}>
<Model url={"/compressed.glb"} />
</Suspense>
{/* <PointerLockControls /> */}
{/* <Button position={props.value} /> */}
<PointerLockControls />
</Canvas>
</div>
);
};

Resources