diff --git a/src/mol-geo/primitive/prism.ts b/src/mol-geo/primitive/prism.ts index 728d18404141229dd10e5cf063fc0b61e6711ac0..681bb3260cffacfa9e4f48d50bd0aafbfe54594e 100644 --- a/src/mol-geo/primitive/prism.ts +++ b/src/mol-geo/primitive/prism.ts @@ -8,6 +8,7 @@ import { Vec3 } from 'mol-math/linear-algebra' import { Primitive, PrimitiveBuilder } from './primitive'; import { polygon } from './polygon' +const on = Vec3.create(0, 0, -0.5), op = Vec3.create(0, 0, 0.5) const a = Vec3.zero(), b = Vec3.zero(), c = Vec3.zero(), d = Vec3.zero() /** @@ -58,12 +59,10 @@ export function Prism(points: ArrayLike<number>): Primitive { const ni = (i + 1) % sideCount Vec3.set(a, points[i * 2], points[i * 2 + 1], -0.5) Vec3.set(b, points[ni * 2], points[ni * 2 + 1], -0.5) - Vec3.set(c, 0, 0, -0.5) - builder.add(a, b, c) + builder.add(a, b, on) Vec3.set(a, points[i * 2], points[i * 2 + 1], 0.5) Vec3.set(b, points[ni * 2], points[ni * 2 + 1], 0.5) - Vec3.set(c, 0, 0, 0.5) - builder.add(c, b, a) + builder.add(op, b, a) } } diff --git a/src/mol-geo/primitive/pyramid.ts b/src/mol-geo/primitive/pyramid.ts new file mode 100644 index 0000000000000000000000000000000000000000..a188f7232fbd1a2ae5dff1edc04fcdef6e0c3b6a --- /dev/null +++ b/src/mol-geo/primitive/pyramid.ts @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Vec3 } from 'mol-math/linear-algebra' +import { Primitive, PrimitiveBuilder } from './primitive'; +import { polygon } from './polygon' + +const on = Vec3.create(0, 0, -0.5), op = Vec3.create(0, 0, 0.5) +const a = Vec3.zero(), b = Vec3.zero(), c = Vec3.zero(), d = Vec3.zero() + +/** + * Create a pyramide with a poligonal base + */ +export function Pyramide(points: ArrayLike<number>): Primitive { + const sideCount = points.length / 2 + const baseCount = sideCount === 3 ? 1 : sideCount === 4 ? 2 : sideCount + const count = 2 * baseCount + 2 * sideCount + const builder = PrimitiveBuilder(count) + + // create sides + for (let i = 0; i < sideCount; ++i) { + const ni = (i + 1) % sideCount + Vec3.set(a, points[i * 2], points[i * 2 + 1], -0.5) + Vec3.set(b, points[ni * 2], points[ni * 2 + 1], -0.5) + builder.add(a, b, op) + } + + // create base + if (sideCount === 3) { + Vec3.set(a, points[0], points[1], -0.5) + Vec3.set(b, points[2], points[3], -0.5) + Vec3.set(c, points[4], points[5], -0.5) + builder.add(a, b, c) + } else if (sideCount === 4) { + Vec3.set(a, points[0], points[1], -0.5) + Vec3.set(b, points[2], points[3], -0.5) + Vec3.set(c, points[4], points[5], -0.5) + Vec3.set(d, points[6], points[7], -0.5) + builder.add(a, b, c) + builder.add(c, d, a) + } else { + for (let i = 0; i < sideCount; ++i) { + const ni = (i + 1) % sideCount + Vec3.set(a, points[i * 2], points[i * 2 + 1], -0.5) + Vec3.set(b, points[ni * 2], points[ni * 2 + 1], -0.5) + builder.add(a, b, on) + } + } + + return builder.getPrimitive() +} + +let octagonalPyramide: Primitive +export function OctagonalPyramide() { + if (!octagonalPyramide) octagonalPyramide = Pyramide(polygon(8, true)) + return octagonalPyramide +} \ No newline at end of file diff --git a/src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts b/src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts index 70f363b02d7ba89d6b89be54e26e9ef7d0e61d4b..7d65aec3a074092a47986d592b4a2b91bf990556 100644 --- a/src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts +++ b/src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts @@ -28,8 +28,6 @@ const t = Mat4.identity() const sVec = Vec3.zero() const p = Vec3.zero() const pd = Vec3.zero() -const p1 = Vec3.zero() -const p2 = Vec3.zero() async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Structure, mesh?: Mesh) { const builder = MeshBuilder.create(256, 128, mesh) @@ -44,7 +42,6 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru const side = 1.75 * 2 * 0.806; // 0.806 == Math.cos(Math.PI / 4) const radius = 1.75 - const coneParams = { radiusTop: radius, radiusBottom: 0.0, topCap: true } const linkParams = { radiusTop: 0.4, radiusBottom: 0.4 } @@ -71,15 +68,15 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru builder.addBox(t) break; case SaccharideShapes.FilledCone: - Vec3.scaleAndSub(p1, cGeo.center, cGeo.direction, radius) - Vec3.scaleAndAdd(p2, cGeo.center, cGeo.direction, radius) - builder.addCylinder(p1, p2, 1, coneParams) + centerAlign(cGeo.center, cGeo.normal, cGeo.direction) + Mat4.scaleUniformly(t, t, side * 1.2) + builder.addOctagonalPyramid(t) break case SaccharideShapes.DevidedCone: // TODO split - Vec3.scaleAndSub(p1, cGeo.center, cGeo.direction, radius) - Vec3.scaleAndAdd(p2, cGeo.center, cGeo.direction, radius) - builder.addCylinder(p1, p2, 1, coneParams) + centerAlign(cGeo.center, cGeo.normal, cGeo.direction) + Mat4.scaleUniformly(t, t, side * 1.2) + builder.addOctagonalPyramid(t) break case SaccharideShapes.FlatBox: centerAlign(cGeo.center, cGeo.normal, cGeo.direction) diff --git a/src/mol-geo/shape/mesh-builder.ts b/src/mol-geo/shape/mesh-builder.ts index 535b86ca955b123b7f5c1b725f2aed8d8814b0b1..8b8404c19794dc5be1bb54f3a214d6aedbdb7269 100644 --- a/src/mol-geo/shape/mesh-builder.ts +++ b/src/mol-geo/shape/mesh-builder.ts @@ -19,6 +19,7 @@ import { StarProps, Star } from '../primitive/star'; import { Octahedron } from '../primitive/octahedron'; import { Primitive } from '../primitive/primitive'; import { Wedge, Box, DiamondPrism, PentagonalPrism, HexagonalPrism } from '../primitive/prism'; +import { OctagonalPyramide } from '../primitive/pyramid'; export interface MeshBuilderState { vertices: ChunkedArray<number, 3> @@ -34,6 +35,7 @@ export interface MeshBuilder { addDiamondPrism(t: Mat4): void addPentagonalPrism(t: Mat4): void addHexagonalPrism(t: Mat4): void + addOctagonalPyramid(t: Mat4): void addStar(t: Mat4, props?: StarProps): void addOctahedron(t: Mat4): void addCylinder(start: Vec3, end: Vec3, lengthScale: number, props: CylinderProps): void @@ -158,6 +160,10 @@ export namespace MeshBuilder { const { vertices, normals, indices } = HexagonalPrism() add(t, vertices, normals, indices) }, + addOctagonalPyramid: (t: Mat4) => { + const { vertices, normals, indices } = OctagonalPyramide() + add(t, vertices, normals, indices) + }, addStar: (t: Mat4, props?: StarProps) => { const { vertices, normals, indices } = Star(props) add(t, vertices, normals, indices)