123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- * @author David Sehnal <david.sehnal@gmail.com>
- */
- import { Vec3 } from 'mol-math/linear-algebra';
- import { ChunkedArray } from 'mol-data/util';
- import { MeshBuilderState } from './mesh-builder';
- const tA = Vec3.zero()
- const tB = Vec3.zero()
- const tV = Vec3.zero()
- const horizontalVector = Vec3.zero()
- const verticalVector = Vec3.zero()
- const normalOffset = Vec3.zero()
- const positionVector = Vec3.zero()
- const normalVector = Vec3.zero()
- const torsionVector = Vec3.zero()
- const p1 = Vec3.zero()
- const p2 = Vec3.zero()
- const p3 = Vec3.zero()
- const p4 = Vec3.zero()
- export function addSheet(controlPoints: ArrayLike<number>, normalVectors: ArrayLike<number>, binormalVectors: ArrayLike<number>, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean, state: MeshBuilderState) {
- const { vertices, normals, indices } = state
- let vertexCount = vertices.elementCount
- let offsetLength = 0
- if (arrowHeight > 0) {
- Vec3.fromArray(tA, controlPoints, 0)
- Vec3.fromArray(tB, controlPoints, linearSegments * 3)
- offsetLength = arrowHeight / Vec3.magnitude(Vec3.sub(tV, tB, tA))
- }
- for (let i = 0; i <= linearSegments; ++i) {
- const actualHeight = arrowHeight === 0 ? height : arrowHeight * (1 - i / linearSegments);
- const i3 = i * 3
- Vec3.fromArray(verticalVector, normalVectors, i3)
- Vec3.scale(verticalVector, verticalVector, actualHeight);
- Vec3.fromArray(horizontalVector, binormalVectors, i3)
- Vec3.scale(horizontalVector, horizontalVector, width);
- if (arrowHeight > 0) {
- Vec3.fromArray(tA, normalVectors, i3)
- Vec3.fromArray(tB, binormalVectors, i3)
- Vec3.scale(normalOffset, Vec3.cross(normalOffset, tA, tB), offsetLength)
- }
- Vec3.fromArray(positionVector, controlPoints, i3)
- Vec3.fromArray(normalVector, normalVectors, i3)
- Vec3.fromArray(torsionVector, binormalVectors, i3)
- Vec3.add(tA, Vec3.add(tA, positionVector, horizontalVector), verticalVector)
- Vec3.copy(tB, normalVector)
- ChunkedArray.add3(vertices, tA[0], tA[1], tA[2])
- ChunkedArray.add3(normals, tB[0], tB[1], tB[2])
- Vec3.add(tA, Vec3.sub(tA, positionVector, horizontalVector), verticalVector)
- ChunkedArray.add3(vertices, tA[0], tA[1], tA[2])
- ChunkedArray.add3(normals, tB[0], tB[1], tB[2])
- // Vec3.add(tA, Vec3.sub(tA, positionVector, horizontalVector), verticalVector) // reuse tA
- Vec3.add(tB, Vec3.negate(tB, torsionVector), normalOffset)
- ChunkedArray.add3(vertices, tA[0], tA[1], tA[2])
- ChunkedArray.add3(normals, tB[0], tB[1], tB[2])
- Vec3.sub(tA, Vec3.sub(tA, positionVector, horizontalVector), verticalVector)
- ChunkedArray.add3(vertices, tA[0], tA[1], tA[2])
- ChunkedArray.add3(normals, tB[0], tB[1], tB[2])
- // Vec3.sub(tA, Vec3.sub(tA, positionVector, horizontalVector), verticalVector) // reuse tA
- Vec3.negate(tB, normalVector)
- ChunkedArray.add3(vertices, tA[0], tA[1], tA[2])
- ChunkedArray.add3(normals, tB[0], tB[1], tB[2])
- Vec3.sub(tA, Vec3.add(tA, positionVector, horizontalVector), verticalVector)
- ChunkedArray.add3(vertices, tA[0], tA[1], tA[2])
- ChunkedArray.add3(normals, tB[0], tB[1], tB[2])
- // Vec3.sub(tA, Vec3.add(tA, positionVector, horizontalVector), verticalVector) // reuse tA
- Vec3.add(tB, torsionVector, normalOffset)
- ChunkedArray.add3(vertices, tA[0], tA[1], tA[2])
- ChunkedArray.add3(normals, tB[0], tB[1], tB[2])
- Vec3.add(tA, Vec3.add(tA, positionVector, horizontalVector), verticalVector)
- ChunkedArray.add3(vertices, tA[0], tA[1], tA[2])
- ChunkedArray.add3(normals, tB[0], tB[1], tB[2])
- }
- for (let i = 0; i < linearSegments; ++i) {
- for (let j = 0; j < 4; j++) {
- ChunkedArray.add3(
- indices,
- vertexCount + i * 8 + 2 * j,
- vertexCount + (i + 1) * 8 + 2 * j + 1,
- vertexCount + i * 8 + 2 * j + 1
- );
- ChunkedArray.add3(
- indices,
- vertexCount + i * 8 + 2 * j,
- vertexCount + (i + 1) * 8 + 2 * j,
- vertexCount + (i + 1) * 8 + 2 * j + 1
- );
- }
- }
- if (startCap) {
- const offset = 0
- vertexCount = vertices.elementCount
- Vec3.fromArray(verticalVector, normalVectors, offset)
- Vec3.scale(verticalVector, verticalVector, arrowHeight === 0 ? height : arrowHeight);
- Vec3.fromArray(horizontalVector, binormalVectors, offset)
- Vec3.scale(horizontalVector, horizontalVector, width);
- Vec3.fromArray(positionVector, controlPoints, offset)
- Vec3.add(p1, Vec3.add(p1, positionVector, horizontalVector), verticalVector)
- Vec3.sub(p2, Vec3.add(p2, positionVector, horizontalVector), verticalVector)
- Vec3.sub(p3, Vec3.sub(p3, positionVector, horizontalVector), verticalVector)
- Vec3.add(p4, Vec3.sub(p4, positionVector, horizontalVector), verticalVector)
- ChunkedArray.add3(vertices, p1[0], p1[1], p1[2])
- ChunkedArray.add3(vertices, p2[0], p2[1], p2[2])
- ChunkedArray.add3(vertices, p3[0], p3[1], p3[2])
- ChunkedArray.add3(vertices, p4[0], p4[1], p4[2])
- Vec3.cross(normalVector, horizontalVector, verticalVector)
- for (let i = 0; i < 4; ++i) {
- ChunkedArray.add3(normals, normalVector[0], normalVector[1], normalVector[2])
- }
- ChunkedArray.add3(indices, vertexCount + 2, vertexCount + 1, vertexCount);
- ChunkedArray.add3(indices, vertexCount, vertexCount + 3, vertexCount + 2);
- }
- if (endCap && arrowHeight === 0) {
- const offset = linearSegments * 3
- vertexCount = vertices.elementCount
- Vec3.fromArray(verticalVector, normalVectors, offset)
- Vec3.scale(verticalVector, verticalVector, height);
- Vec3.fromArray(horizontalVector, binormalVectors, offset)
- Vec3.scale(horizontalVector, horizontalVector, width);
- Vec3.fromArray(positionVector, controlPoints, offset)
- Vec3.add(p1, Vec3.add(p1, positionVector, horizontalVector), verticalVector)
- Vec3.sub(p2, Vec3.add(p2, positionVector, horizontalVector), verticalVector)
- Vec3.sub(p3, Vec3.sub(p3, positionVector, horizontalVector), verticalVector)
- Vec3.add(p4, Vec3.sub(p4, positionVector, horizontalVector), verticalVector)
- ChunkedArray.add3(vertices, p1[0], p1[1], p1[2])
- ChunkedArray.add3(vertices, p2[0], p2[1], p2[2])
- ChunkedArray.add3(vertices, p3[0], p3[1], p3[2])
- ChunkedArray.add3(vertices, p4[0], p4[1], p4[2])
- Vec3.cross(normalVector, horizontalVector, verticalVector)
- for (let i = 0; i < 4; ++i) {
- ChunkedArray.add3(normals, normalVector[0], normalVector[1], normalVector[2])
- }
- ChunkedArray.add3(indices, vertexCount + 2, vertexCount + 1, vertexCount);
- ChunkedArray.add3(indices, vertexCount, vertexCount + 3, vertexCount + 2);
- }
- return (linearSegments + 1) * 8 + (startCap ? 4 : 0) + (endCap && arrowHeight === 0 ? 4 : 0)
- }
|