Spaces:
Sleeping
Sleeping
| import { BufferGeometry } from '../core/BufferGeometry.js'; | |
| import { Float32BufferAttribute } from '../core/BufferAttribute.js'; | |
| import { Vector3 } from '../math/Vector3.js'; | |
| class WireframeGeometry extends BufferGeometry { | |
| constructor(geometry = null) { | |
| super(); | |
| this.type = 'WireframeGeometry'; | |
| this.parameters = { | |
| geometry: geometry, | |
| }; | |
| if (geometry !== null) { | |
| // buffer | |
| const vertices = []; | |
| const edges = new Set(); | |
| // helper variables | |
| const start = new Vector3(); | |
| const end = new Vector3(); | |
| if (geometry.index !== null) { | |
| // indexed BufferGeometry | |
| const position = geometry.attributes.position; | |
| const indices = geometry.index; | |
| let groups = geometry.groups; | |
| if (groups.length === 0) { | |
| groups = [{ start: 0, count: indices.count, materialIndex: 0 }]; | |
| } | |
| // create a data structure that contains all eges without duplicates | |
| for (let o = 0, ol = groups.length; o < ol; ++o) { | |
| const group = groups[o]; | |
| const groupStart = group.start; | |
| const groupCount = group.count; | |
| for (let i = groupStart, l = groupStart + groupCount; i < l; i += 3) { | |
| for (let j = 0; j < 3; j++) { | |
| const index1 = indices.getX(i + j); | |
| const index2 = indices.getX(i + ((j + 1) % 3)); | |
| start.fromBufferAttribute(position, index1); | |
| end.fromBufferAttribute(position, index2); | |
| if (isUniqueEdge(start, end, edges) === true) { | |
| vertices.push(start.x, start.y, start.z); | |
| vertices.push(end.x, end.y, end.z); | |
| } | |
| } | |
| } | |
| } | |
| } else { | |
| // non-indexed BufferGeometry | |
| const position = geometry.attributes.position; | |
| for (let i = 0, l = position.count / 3; i < l; i++) { | |
| for (let j = 0; j < 3; j++) { | |
| // three edges per triangle, an edge is represented as (index1, index2) | |
| // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) | |
| const index1 = 3 * i + j; | |
| const index2 = 3 * i + ((j + 1) % 3); | |
| start.fromBufferAttribute(position, index1); | |
| end.fromBufferAttribute(position, index2); | |
| if (isUniqueEdge(start, end, edges) === true) { | |
| vertices.push(start.x, start.y, start.z); | |
| vertices.push(end.x, end.y, end.z); | |
| } | |
| } | |
| } | |
| } | |
| // build geometry | |
| this.setAttribute('position', new Float32BufferAttribute(vertices, 3)); | |
| } | |
| } | |
| } | |
| function isUniqueEdge(start, end, edges) { | |
| const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`; | |
| const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge | |
| if (edges.has(hash1) === true || edges.has(hash2) === true) { | |
| return false; | |
| } else { | |
| edges.add(hash1, hash2); | |
| return true; | |
| } | |
| } | |
| export { WireframeGeometry }; | |