You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
greetings to all, As you can see in this example, it is divided into dot-to-dot particles. I'm trying to adapt this for every cylinder in instancedmesh, but the 1. particles are too big. 2.There is only 1 piece. How can I include them all? Should I use meshRef.current.geometry in pointsGeom function (it gives an error) or new THREE.CylinderGeometry(0.5, 0.5, 0.15, 32) ? I'd be grateful if you could help, I'm confused My Code
import * as React from "react";
import * as THREE from "three";
import { useAnimatedLayout } from "./layouts";
import { a } from "@react-spring/three";
import { useFrame, extend } from "@react-three/fiber";
////////////////////////////////////////////
import {
PointsMaterial,
Color,
Mesh,
Vector3,
BufferGeometry,
Float32BufferAttribute,
} from "three";
import { MeshSurfaceSampler } from "three/examples/jsm/math/MeshSurfaceSampler";
import { mergeBufferGeometries } from "three/examples/jsm/utils/BufferGeometryUtils";
import {
meshBounds,
useGLTF,
OrbitControls,
Html,
Environment,
} from "@react-three/drei";
import glsl from "babel-plugin-glsl/macro";
// re-use for instance computations
class MyPointsMaterial extends PointsMaterial {
constructor(parameters) {
super();
this.setValues(parameters);
this._time = { value: 0 };
}
onBeforeCompile(shader, gl) {
shader.uniforms.time = this._time;
shader.vertexShader = shader.vertexShader.replace(
"#include <common>",
glsl`
//#pragma glslify: snoise3 = require(glsl-curl-noise);
#pragma glslify: snoise3 = require(glsl-noise/simplex/3d.glsl);
uniform float time;
#include <common>`,
);
shader.vertexShader = shader.vertexShader.replace(
"#include <begin_vertex>",
`
vec3 transformed = vec3( position );
transformed += snoise3(position * time * 20.) * 0.002;
`,
);
}
get time() {
return this._time.value;
}
set time(v) {
this._time.value = v;
}
}
extend({ MyPointsMaterial });
const scratchObject3D = new THREE.Object3D();
function updateInstancedMeshMatrices({ mesh, data }) {
if (!mesh) return;
// set the transform matrix for each instance
for (let i = 0; i < data.length; ++i) {
const { x, y, z } = data[i];
scratchObject3D.position.set(x, y, z);
scratchObject3D.rotation.set(0.5 * Math.PI, 0, 0); // cylinders face z direction
scratchObject3D.updateMatrix();
mesh.setMatrixAt(i, scratchObject3D.matrix);
}
mesh.instanceMatrix.needsUpdate = true;
}
const SELECTED_COLOR = "#000";
const SELECTEDD_COLOR = "#000";
const DEFAULT_COLOR = "#000";
// const SELECTED_COLOR = "#6f6";
// const DEFAULT_COLOR = "#ff8080";
// re-use for instance computations
const scratchColor = new THREE.Color();
const usePointColors = ({ data, selectedPoint }) => {
const numPoints = data.length;
const colorAttrib = React.useRef();
const colorArray = React.useMemo(
() => new Float32Array(numPoints * 3),
[numPoints],
);
React.useEffect(() => {
for (let i = 0; i < data.length; ++i) {
scratchColor.set(
data[i] === selectedPoint
? SELECTEDD_COLOR
: DEFAULT_COLOR && data[i].analiz == 1
? SELECTED_COLOR
: DEFAULT_COLOR,
);
scratchColor.toArray(colorArray, i * 3);
}
colorAttrib.current.needsUpdate = true;
}, [data, selectedPoint, colorArray]);
return { colorAttrib, colorArray };
};
const useMousePointInteraction = ({
data,
selectedPoint,
onSelectPoint,
clickForZoom,
}) => {
// track mousedown position to skip click handlers on drags
const mouseDownRef = React.useRef([0, 0]);
const handlePointerDown = (e) => {
mouseDownRef.current[0] = e.clientX;
mouseDownRef.current[1] = e.clientY;
};
const handleClick = (event) => {
const { instanceId, clientX, clientY } = event;
const downDistance = Math.sqrt(
Math.pow(mouseDownRef.current[0] - clientX, 2) +
Math.pow(mouseDownRef.current[1] - clientY, 2),
);
// skip click if we dragged more than 5px distance
if (downDistance > 5) {
event.stopPropagation();
return;
}
// index is instanceId if we never change sort order
const index = instanceId;
const point = data[index];
console.log("got point =", point);
// toggle the point
if (point === selectedPoint) {
onSelectPoint(null);
} else {
onSelectPoint(point);
clickForZoom(point);
}
};
return { handlePointerDown, handleClick };
};
const InstancedPoints = ({ data, layout, selectedPoint, onSelectPoint }) => {
const meshRef = React.useRef();
const material = React.useRef();
const tempPos = React.useRef(new Vector3()).current;
const tempNormals = React.useRef(new Vector3()).current;
const tempColor = React.useRef(new Vector3()).current;
const verticesArray = React.useRef([]).current;
const colorsArray = React.useRef([]).current;
const numPoints = data.length;
const vec = new THREE.Vector3();
const [clicked, setClicked] = React.useState(false);
useFrame((state) => {
if (clicked && selectedPoint !== null) {
state.camera.lookAt(selectedPoint.x, selectedPoint.y, selectedPoint.z);
state.camera.position.lerp(
vec.set(selectedPoint.x, selectedPoint.y, 5),
0.01,
);
state.camera.updateProjectionMatrix();
} else {
state.camera.lookAt(0, 0, 0);
window.innerWidth < 600
? state.camera.position.lerp(vec.set(0, 0, 50), 0.1)
: state.camera.position.lerp(vec.set(0, 0, 25), 0.1);
}
material.current.time = state.clock.getElapsedTime() * 0.5;
});
const clickForZoom = (point) => {
setClicked(true);
};
// run the layout, animating on change
const { animationProgress } = useAnimatedLayout({
data,
layout,
onFrame: () => {
updateInstancedMeshMatrices({ mesh: meshRef.current, data });
},
});
// update instance matrices only when needed
React.useEffect(() => {
updateInstancedMeshMatrices({ mesh: meshRef.current, data });
}, [data, layout]);
const { handleClick, handlePointerDown } = useMousePointInteraction({
data,
selectedPoint,
onSelectPoint,
clickForZoom,
});
// const { colorAttrib, colorArray } = usePointColors({ data, selectedPoint });
/////////////////////////////////////////////////////
const pointsGeom = React.useMemo(
(e) => {
const geometries = [meshRef.current.geometry];
const mergedGeom = mergeBufferGeometries(geometries);
const sampler = new MeshSurfaceSampler(new Mesh(mergedGeom)).build();
for (let i = 0; i < 10000; i++) {
sampler.sample(tempPos, tempNormals, tempColor);
verticesArray.push(tempPos.x, tempPos.y, tempPos.z);
colorsArray.push(tempNormals.x, tempNormals.y, tempNormals.z);
}
const geom = new BufferGeometry();
geom.setAttribute(
"position",
new Float32BufferAttribute(verticesArray, 3),
);
geom.setAttribute("color", new Float32BufferAttribute(colorsArray, 3));
return geom;
},
[meshRef, tempPos, verticesArray],
);
return (
<>
<instancedMesh
ref={meshRef}
args={[null, null, numPoints]}
frustumCulled={false}
// onClick={handleClick}
onPointerDown={handlePointerDown}
>
<cylinderBufferGeometry
attach="geometry"
args={[0.5, 0.5, 0.15, 32]}
></cylinderBufferGeometry>
<meshStandardMaterial attach="material" color="white" />
<points geometry={pointsGeom} rotation={[Math.PI / 2, 0, 0]}>
<myPointsMaterial ref={material} size={0.001} vertexColors={true} />
</points>
</instancedMesh>
{/* {selectedPoint && (
<a.group
position={animationProgress.interpolate(() => [
selectedPoint.x,
selectedPoint.y,
selectedPoint.z,
])}
>
<pointLight
distance={9}
position={[0, 0, 0.3]}
intensity={2.2}
decay={30}
color="#3f3"
/>
<pointLight
position={[0, 0, 0]}
decay={1}
distance={5}
intensity={1.5}
color="#2f0"
/>
</a.group>
)} */}
</>
);
};
export default InstancedPoints;
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
https://hhc8xf.csb.app/
greetings to all, As you can see in this example, it is divided into dot-to-dot particles. I'm trying to adapt this for every cylinder in instancedmesh, but the 1. particles are too big. 2.There is only 1 piece. How can I include them all? Should I use meshRef.current.geometry in pointsGeom function (it gives an error) or new THREE.CylinderGeometry(0.5, 0.5, 0.15, 32) ? I'd be grateful if you could help, I'm confused My Code
Beta Was this translation helpful? Give feedback.
All reactions