I am just a beginner for threejs and react-three-fiber, so I may make some basic mistakes. Sorry if I do so.
When I withdrew an object from scene by using the function getObjectByName
, the obj was not Mesh type object. Instead, children elements were Mesh type object.
Additionally, when I tried to convert first Mesh type object to particles by extracting positions and substituting to buffer geometry, the image seemed just parts of whole model.
So, I decided to integrate all mesh objects, but an issue occurred. Positions of geometry were NaN
Here are specific codes I wrote.
// particle3D component
"use client";
import { MeshSurfaceSampler } from 'three/addons/math/MeshSurfaceSampler.js';
import * as BGU from 'three/examples/jsm/utils/BufferGeometryUtils.js';
import { useGLTF } from '@react-three/drei';
import * as THREE from 'three';
import { useEffect, useState } from 'react';
export default function Particle3D({ url, particleCount = 100000 }: { url: string; particleCount?: number }) {
const { scene } = useGLTF(url);
const [geometry, setGeometry] = useState<THREE.BufferGeometry | null>(null);
useEffect(() => {
const geometries: THREE.BufferGeometry[] = [];
const obj = scene.getObjectByName("3d-modelobj");
obj?.children.forEach((child) => {
if (child instanceof THREE.Mesh) {
geometries.push(child.geometry);
}
});
const combinedGeometry = BGU.mergeGeometries(geometries, false);
const sampler = new MeshSurfaceSampler(new THREE.Mesh(combinedGeometry)).build();
const positions = new Float32Array(particleCount * 3);
const temp = new THREE.Vector3();
for (let i = 0; i < particleCount; i++) {
sampler.sample(temp);
positions[i * 3] = temp.x;
positions[i * 3 + 1] = temp.y;
positions[i * 3 + 2] = temp.z;
}
const geo = new THREE.BufferGeometry();
geo.setAttribute("position", new THREE.BufferAttribute(positions, 3));
const center = new THREE.Vector3();
geo.computeBoundingBox();
geo.boundingBox?.getCenter(center);
geo.translate(-center.x, -center.y, -center.z);
setGeometry(geo);
}, [scene, particleCount]);
if (!geometry) return null;
return (
<points geometry={geometry} position={[0, 0, 0]} rotation={[-Math.PI / 10, 0, 0]}>
<pointsMaterial size={0.01} color="white" sizeAttenuation />
</points>
);
}
I confirmed that the gltf model can be read by using primitive component, and so, the url path was also correct.