I try to use a conveyor in my simulation. I found this code that fits quite well with what I want, except that I work with R3F. I tried to convert this code, but I can’t get the bufferAttribute part to work.
I have pasted below two of my attempts. With this code, I can get a flat plane with the texture moving forward, but I can’t get the curvature and the second plane.
import * as THREE from "three";
import { useFrame } from "react-three-fiber";
import React, { useRef } from "react";
function createTexture() {
var c = document.createElement("canvas");
c.width = c.height = 256;
var ctx = c.getContext("2d");
ctx.fillStyle = "maroon";
ctx.fillRect(0, 0, c.width, c.height);
ctx.strokeStyle = "white";
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineWidth = 100;
ctx.lineTo(c.width, c.height);
ctx.stroke();
var texture = new THREE.CanvasTexture(c);
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.MirroredRepeatWrapping;
texture.repeat.set(10, 2);
return texture;
}
var clock = new THREE.Clock();
var path = new THREE.Path();
path.absarc(5, 0, 1, Math.PI * 0.5, Math.PI * 1.5, true);
path.absarc(-5, 0, 1, Math.PI * 1.5, Math.PI * 0.5, true);
path.closePath();
console.log(path);
var basePts = path.getSpacedPoints(200).reverse();
// first try not working
export function ConveyorBelt() {
var baseConv = [];
basePts.forEach((d) => {
baseConv.push(d.x, d.y, -2);
});
basePts.forEach((d) => {
baseConv.push(d.x, d.y, 2);
});
const MBasRef = useRef();
useFrame(() => {
MBasRef.current.map.offset.x = clock.getElapsedTime();
});
console.log(baseConv);
return (
<mesh>
<planeBufferGeometry attach="geometry">
<bufferAttribute
attachObject={["attributes", "position"]}
count={baseConv.length / 3}
array={baseConv}
itemSize={3}
/>
</planeBufferGeometry>
<meshBasicMaterial
ref={MBasRef}
side={THREE.DoubleSide}
map={createTexture()}
/>
</mesh>
);
}
// second try still not working...
export function ConveyorBelt() {
const MBasRef = useRef();
useFrame(() => {
MBasRef.current.map.offset.x = clock.getElapsedTime();
});
return (
<mesh>
<planeBufferGeometry attach="geometry">
{basePts.forEach(
(d, idx) => (
(
<bufferAttribute
attachObject={["attributes", "position"]}
args={([d.x, d.y, -2], idx)}
/>
),
(
<bufferAttribute
attachObject={["attributes", "position"]}
args={([d.x, d.y, 2], idx + 201)}
/>
)
)
)}
</planeBufferGeometry>
<meshBasicMaterial
ref={MBasRef}
side={THREE.DoubleSide}
map={createTexture()}
/>
</mesh>
);
}
Thank you very much! this part works now, but I have still a problem.
In line 21 of the original code, there is this part.
let g = new THREE.PlaneGeometry(1, 1, 200, 1);
widthSegments is set to 200, the value of the others keeps their default value.
I tried to set in my code like follow
or also
But this does not work, it seems to have no effect
I also tried to use but I can’t make it work with the other part of the code. Moreover “planeGeometry” is slightly less performant if I understood well.
as for performance i don’t know what you mean. there is no difference between jsx and vanilla, it’s the same exact thing in the end, just a different notation.
pBG and pG are the same thing. pG is the correct spelling afaik while the other is deprecated. geometry was removed from threejs, now there is only buffergeometry.