1 line
7.7 KiB
Plaintext
1 line
7.7 KiB
Plaintext
|
|
{"version":3,"file":"RoundedBoxGeometry.cjs","sources":["../../src/geometries/RoundedBoxGeometry.js"],"sourcesContent":["import { BoxGeometry, Vector3 } from 'three'\n\nconst tempNormal = /* @__PURE__ */ new Vector3()\n\nfunction getUv(faceDirVector, normal, uvAxis, projectionAxis, radius, sideLength) {\n const totArcLength = (2 * Math.PI * radius) / 4\n\n // length of the planes between the arcs on each axis\n const centerLength = Math.max(sideLength - 2 * radius, 0)\n const halfArc = Math.PI / 4\n\n // Get the vector projected onto the Y plane\n tempNormal.copy(normal)\n tempNormal[projectionAxis] = 0\n tempNormal.normalize()\n\n // total amount of UV space alloted to a single arc\n const arcUvRatio = (0.5 * totArcLength) / (totArcLength + centerLength)\n\n // the distance along one arc the point is at\n const arcAngleRatio = 1.0 - tempNormal.angleTo(faceDirVector) / halfArc\n\n if (Math.sign(tempNormal[uvAxis]) === 1) {\n return arcAngleRatio * arcUvRatio\n } else {\n // total amount of UV space alloted to the plane between the arcs\n const lenUv = centerLength / (totArcLength + centerLength)\n return lenUv + arcUvRatio + arcUvRatio * (1.0 - arcAngleRatio)\n }\n}\n\nclass RoundedBoxGeometry extends BoxGeometry {\n constructor(width = 1, height = 1, depth = 1, segments = 2, radius = 0.1) {\n // ensure segments is odd so we have a plane connecting the rounded corners\n segments = segments * 2 + 1\n\n // ensure radius isn't bigger than shortest side\n radius = Math.min(width / 2, height / 2, depth / 2, radius)\n\n super(1, 1, 1, segments, segments, segments)\n\n // if we just have one segment we're the same as a regular box\n if (segments === 1) return\n\n const geometry2 = this.toNonIndexed()\n\n this.index = null\n this.attributes.position = geometry2.attributes.position\n this.attributes.normal = geometry2.attributes.normal\n this.attributes.uv = geometry2.attributes.uv\n\n //\n\n const position = new Vector3()\n const normal = new Vector3()\n\n const box = new Vector3(width, height, depth).divideScalar(2).subScalar(radius)\n\n const positions = this.attributes.position.array\n const normals = this.attributes.normal.array\n const uvs = this.attributes.uv.array\n\n const faceTris = positions.length / 6\n const faceDirVector = new Vector3()\n const halfSegmentSize = 0.5 / segments\n\n for (let i = 0, j = 0; i < positions.length; i += 3, j += 2) {\n position.fromArray(positions, i)\n normal.copy(position)\n normal.x -= Math.sign(normal.x) * halfSegmentSize\n normal.y -= Math.sign(normal.y) * halfSegmentSize\n normal.z -= Math.sign(normal.z) * halfSegmentSize\n normal.normalize()\n\n positions[i + 0] = box.x * Math.sign(position.x) + normal.x * radius\n positions[i + 1] = box.y * Math.sign(position.y) + normal.y * radius\n positions[i + 2] = box.z * Math.sign(position.z) + normal.z * radius\n\n normals[i + 0] = normal.x\n normals[i + 1] = normal.y\n normals[i + 2] = normal.z\n\n const side = Math.floor(i / faceTris)\n\n switch (side) {\n case 0: // right\n // generate UVs along Z then Y\n faceDirVector.set(1, 0, 0)\n uvs[j + 0] = getUv(faceDirVector, normal, 'z', 'y', radius, depth)\n uvs[j + 1] = 1.0 - getUv(faceDirVector, normal, 'y', 'z', radius, height)\n break\n\n case 1: // left\n // generate UVs along Z then Y\n faceDirVector.set(-1, 0, 0)\n uvs[j + 0] = 1.0 - getUv(faceDirVector, normal, 'z', 'y', radius, depth)\n uvs[j + 1] = 1.0 - getUv(faceDirVector, normal, 'y', 'z', radius, height)\n break\n\n case 2: // top\n // generate UVs along X then Z\n faceDirVector.set(0, 1, 0)\n uvs[j + 0] = 1.0 - getUv(faceDirVector, normal, 'x', 'z', radius, width)\n uvs[j + 1] = getUv(faceDirVector, normal, 'z', 'x', radius, depth)\n break\n\n case 3: // bottom\n // generate UVs along X then Z\n
|