UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

125 lines (124 loc) 4.59 kB
import { BufferAttribute, DynamicDrawUsage, BufferGeometry, MeshStandardMaterial, Mesh, Vector3, Color, Matrix4 } from "three"; function TubePainter() { const BUFFER_SIZE = 1e6 * 3; const positions = new BufferAttribute(new Float32Array(BUFFER_SIZE), 3); positions.usage = DynamicDrawUsage; const normals = new BufferAttribute(new Float32Array(BUFFER_SIZE), 3); normals.usage = DynamicDrawUsage; const colors = new BufferAttribute(new Float32Array(BUFFER_SIZE), 3); colors.usage = DynamicDrawUsage; const geometry = new BufferGeometry(); geometry.setAttribute("position", positions); geometry.setAttribute("normal", normals); geometry.setAttribute("color", colors); geometry.drawRange.count = 0; const material = new MeshStandardMaterial({ vertexColors: true }); const mesh = new Mesh(geometry, material); mesh.frustumCulled = false; function getPoints(size2) { const PI2 = Math.PI * 2; const sides = 10; const array = []; const radius = 0.01 * size2; for (let i = 0; i < sides; i++) { const angle = i / sides * PI2; array.push(new Vector3(Math.sin(angle) * radius, Math.cos(angle) * radius, 0)); } return array; } const vector1 = new Vector3(); const vector2 = new Vector3(); const vector3 = new Vector3(); const vector4 = new Vector3(); const color = new Color(16777215); let size = 1; function stroke(position1, position2, matrix12, matrix22) { if (position1.distanceToSquared(position2) === 0) return; let count2 = geometry.drawRange.count; const points = getPoints(size); for (let i = 0, il = points.length; i < il; i++) { const vertex1 = points[i]; const vertex2 = points[(i + 1) % il]; vector1.copy(vertex1).applyMatrix4(matrix22).add(position2); vector2.copy(vertex2).applyMatrix4(matrix22).add(position2); vector3.copy(vertex2).applyMatrix4(matrix12).add(position1); vector4.copy(vertex1).applyMatrix4(matrix12).add(position1); vector1.toArray(positions.array, (count2 + 0) * 3); vector2.toArray(positions.array, (count2 + 1) * 3); vector4.toArray(positions.array, (count2 + 2) * 3); vector2.toArray(positions.array, (count2 + 3) * 3); vector3.toArray(positions.array, (count2 + 4) * 3); vector4.toArray(positions.array, (count2 + 5) * 3); vector1.copy(vertex1).applyMatrix4(matrix22).normalize(); vector2.copy(vertex2).applyMatrix4(matrix22).normalize(); vector3.copy(vertex2).applyMatrix4(matrix12).normalize(); vector4.copy(vertex1).applyMatrix4(matrix12).normalize(); vector1.toArray(normals.array, (count2 + 0) * 3); vector2.toArray(normals.array, (count2 + 1) * 3); vector4.toArray(normals.array, (count2 + 2) * 3); vector2.toArray(normals.array, (count2 + 3) * 3); vector3.toArray(normals.array, (count2 + 4) * 3); vector4.toArray(normals.array, (count2 + 5) * 3); color.toArray(colors.array, (count2 + 0) * 3); color.toArray(colors.array, (count2 + 1) * 3); color.toArray(colors.array, (count2 + 2) * 3); color.toArray(colors.array, (count2 + 3) * 3); color.toArray(colors.array, (count2 + 4) * 3); color.toArray(colors.array, (count2 + 5) * 3); count2 += 6; } geometry.drawRange.count = count2; } const up = new Vector3(0, 1, 0); const point1 = new Vector3(); const point2 = new Vector3(); const matrix1 = new Matrix4(); const matrix2 = new Matrix4(); function moveTo(position) { point1.copy(position); matrix1.lookAt(point2, point1, up); point2.copy(position); matrix2.copy(matrix1); } function lineTo(position) { point1.copy(position); matrix1.lookAt(point2, point1, up); stroke(point1, point2, matrix1, matrix2); point2.copy(point1); matrix2.copy(matrix1); } function setSize(value) { size = value; } let count = 0; function update() { const start = count; const end = geometry.drawRange.count; if (start === end) return; positions.updateRange.offset = start * 3; positions.updateRange.count = (end - start) * 3; positions.needsUpdate = true; normals.updateRange.offset = start * 3; normals.updateRange.count = (end - start) * 3; normals.needsUpdate = true; colors.updateRange.offset = start * 3; colors.updateRange.count = (end - start) * 3; colors.needsUpdate = true; count = geometry.drawRange.count; } return { mesh, moveTo, lineTo, setSize, update }; } export { TubePainter }; //# sourceMappingURL=TubePainter.js.map