diff --git a/src/mol-geo/primitive/box.ts b/src/mol-geo/primitive/box.ts index 9ba23149f07dfba0daea75f5656101119a272145..ee7e5b906485c4546c6a9bfb29e07c11b627e35c 100644 --- a/src/mol-geo/primitive/box.ts +++ b/src/mol-geo/primitive/box.ts @@ -7,6 +7,7 @@ // adapted from three.js, MIT License Copyright 2010-2018 three.js authors import { Vec3 } from 'mol-math/linear-algebra' +import { Primitive } from './primitive'; export const DefaultBoxProps = { width: 1, @@ -17,7 +18,7 @@ export type BoxProps = Partial<typeof DefaultBoxProps> const tmpVector = Vec3.zero(); -export function Box(props?: BoxProps) { +export function Box(props?: BoxProps): Primitive { const { width, height, depth } = { ...DefaultBoxProps, ...props } // buffers diff --git a/src/mol-geo/primitive/cylinder.ts b/src/mol-geo/primitive/cylinder.ts index a17cc3ff8d68539e0f19c4365b82ab6d967f7acf..58f8b893e80e64bbca425e43d42f293c7ef2ded3 100644 --- a/src/mol-geo/primitive/cylinder.ts +++ b/src/mol-geo/primitive/cylinder.ts @@ -7,6 +7,7 @@ // adapted from three.js, MIT License Copyright 2010-2018 three.js authors import { Vec3 } from 'mol-math/linear-algebra' +import { Primitive } from './primitive'; export const DefaultCylinderProps = { radiusTop: 1, @@ -21,7 +22,7 @@ export const DefaultCylinderProps = { } export type CylinderProps = Partial<typeof DefaultCylinderProps> -export function Cylinder(props?: CylinderProps) { +export function Cylinder(props?: CylinderProps): Primitive { const { radiusTop, radiusBottom, height, radialSegments, heightSegments, topCap, bottomCap, thetaStart, thetaLength } = { ...DefaultCylinderProps, ...props }; // buffers diff --git a/src/mol-geo/primitive/icosahedron.ts b/src/mol-geo/primitive/icosahedron.ts index d9383aa0fe1dc119ec344dc351b1d80e098c6ea6..096945994adb3b20a1bc5680814117cbecc7a694 100644 --- a/src/mol-geo/primitive/icosahedron.ts +++ b/src/mol-geo/primitive/icosahedron.ts @@ -4,35 +4,23 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -// adapted from three.js, MIT License Copyright 2010-2018 three.js authors - -import { Polyhedron } from './polyhedron' +import { createPrimitive, Primitive } from './primitive'; const t = ( 1 + Math.sqrt( 5 ) ) / 2; -const vertices = [ - - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0, - 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, - t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1 +const icosahedronVertices: ReadonlyArray<number> = [ + -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, + 0, -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, + t, 0, -1, t, 0, 1, -t, 0, -1, -t, 0, 1 ]; -const indices = [ - 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, - 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, - 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, - 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 +const icosahedronIndices: ReadonlyArray<number> = [ + 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, + 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, + 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, + 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 ]; -export function icosahedronVertexCount(detail: number) { - return 10 * Math.pow(Math.pow(2, detail), 2) + 2 -} - -export const DefaultIcosahedronProps = { - radius: 1, - detail: 0 -} -export type IcosahedronProps = Partial<typeof DefaultIcosahedronProps> +const icosahedron = createPrimitive(icosahedronVertices, icosahedronIndices) -export function Icosahedron(props?: IcosahedronProps) { - return Polyhedron(vertices, indices, { ...DefaultIcosahedronProps, ...props }) -} \ No newline at end of file +export function Icosahedron(): Primitive { return icosahedron } \ No newline at end of file diff --git a/src/mol-geo/primitive/octahedron.ts b/src/mol-geo/primitive/octahedron.ts new file mode 100644 index 0000000000000000000000000000000000000000..3375145fa02c4984f6121038392c6b6cd90b696b --- /dev/null +++ b/src/mol-geo/primitive/octahedron.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { createPrimitive, Primitive } from './primitive'; + +export const octahedronVertices: ReadonlyArray<number> = [ + 0.5, 0, 0, -0.5, 0, 0, 0, 0.5, 0, + 0, -0.5, 0, 0, 0, 0.5, 0, 0, -0.5 +]; + +export const octahedronIndices: ReadonlyArray<number> = [ + 0, 2, 4, 0, 4, 3, 0, 3, 5, + 0, 5, 2, 1, 2, 5, 1, 5, 3, + 1, 3, 4, 1, 4, 2 +]; + +const octahedron = createPrimitive(octahedronVertices, octahedronIndices) + +export function Octahedron(): Primitive { return octahedron } \ No newline at end of file diff --git a/src/mol-geo/primitive/plane.ts b/src/mol-geo/primitive/plane.ts index c6e02744074056da32d3627050132a0e9d1c9267..aeeeb371d933a4f18a333709790d626cd505a19b 100644 --- a/src/mol-geo/primitive/plane.ts +++ b/src/mol-geo/primitive/plane.ts @@ -1,3 +1,5 @@ +import { Primitive } from './primitive'; + /** * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * @@ -10,7 +12,7 @@ export const DefaultPlaneProps = { } export type PlaneProps = Partial<typeof DefaultPlaneProps> -export function Plane(props?: PlaneProps) { +export function Plane(props?: PlaneProps): Primitive { const { width, height } = { ...DefaultPlaneProps, ...props } return { diff --git a/src/mol-geo/primitive/polyhedron.ts b/src/mol-geo/primitive/polyhedron.ts index d5818b6a77ff30a2f9ae72d2e416cec4dc112655..120d127be6e49b4b3151113e8fa3018ef2349520 100644 --- a/src/mol-geo/primitive/polyhedron.ts +++ b/src/mol-geo/primitive/polyhedron.ts @@ -8,6 +8,7 @@ import { Vec3 } from 'mol-math/linear-algebra' import { computeIndexedVertexNormals, appplyRadius } from '../util' +import { Primitive } from './primitive'; export const DefaultPolyhedronProps = { radius: 1, @@ -15,7 +16,7 @@ export const DefaultPolyhedronProps = { } export type PolyhedronProps = Partial<typeof DefaultPolyhedronProps> -export function Polyhedron(_vertices: Helpers.NumberArray, _indices: Helpers.NumberArray, props?: PolyhedronProps) { +export function Polyhedron(_vertices: ArrayLike<number>, _indices: ArrayLike<number>, props?: PolyhedronProps): Primitive { const { radius, detail } = { ...DefaultPolyhedronProps, ...props } const builder = createBuilder() const { vertices, indices } = builder @@ -85,20 +86,6 @@ export function Polyhedron(_vertices: Helpers.NumberArray, _indices: Helpers.Num } } - // // construct all of the faces - // for (let i = 0; i < cols; ++i) { - // for (let j = 0; j < 2 * (cols - i) - 1; ++j) { - // const k = Math.floor(j / 2) - // if (j % 2 === 0) { - // vertices.push(...v[i][k + 1], ...v[i + 1][k], ...v[i][k]) - // } else { - // vertices.push(...v[i][k + 1], ...v[i + 1][k + 1], ...v[i + 1][k]) - // } - // const l = vertices.length / 3 - // indices.push(l - 3, l - 2, l - 1) - // } - // } - // construct all of the faces for (let i = 0; i < cols; ++i) { for (let j = 0; j < 2 * (cols - i) - 1; ++j) { diff --git a/src/mol-geo/primitive/primitive.ts b/src/mol-geo/primitive/primitive.ts new file mode 100644 index 0000000000000000000000000000000000000000..c49d17f09485552ade99c076a3450f8c30243887 --- /dev/null +++ b/src/mol-geo/primitive/primitive.ts @@ -0,0 +1,40 @@ +/** + * 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'; + +export interface Primitive { + vertices: ArrayLike<number> + normals: ArrayLike<number> + indices: ArrayLike<number> +} + +const tri = [ Vec3.zero(), Vec3.zero(), Vec3.zero() ] +const n = Vec3.zero() + +/** Create primitive with face normals from vertices and indices */ +export function createPrimitive(_vertices: ArrayLike<number>, _indices: ArrayLike<number>): Primitive { + const count = _indices.length + const vertices = new Float32Array(count * 3) + const normals = new Float32Array(count * 3) + const indices = new Uint32Array(count) + + for (let i = 0; i < count; i += 3) { + for (let j = 0; j < 3; ++j) { + Vec3.fromArray(tri[j], _vertices, _indices[i + j] * 3) + Vec3.toArray(tri[j], vertices, i * 3 + j * 3) + } + + Vec3.triangleNormal(n, tri[0], tri[1], tri[2]) + + for (let j = 0; j < 3; ++j) { + Vec3.toArray(n, normals, i * 3 + j * 3) + indices[i + j] = i + j + } + } + + return { vertices, normals, indices } +} \ No newline at end of file diff --git a/src/mol-geo/primitive/sheet.ts b/src/mol-geo/primitive/sheet.ts index 194a0871a9ff056135c59a2f4256cbbeef35f556..7176f04ba40fa08380075fec443c8137f0a915b4 100644 --- a/src/mol-geo/primitive/sheet.ts +++ b/src/mol-geo/primitive/sheet.ts @@ -30,7 +30,7 @@ const p6 = Vec3.zero() const p7 = Vec3.zero() const p8 = Vec3.zero() -export function addSheet(controlPoints: Helpers.NumberArray, normalVectors: Helpers.NumberArray, binormalVectors: Helpers.NumberArray, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean, state: MeshBuilderState) { +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 diff --git a/src/mol-geo/primitive/sphere.ts b/src/mol-geo/primitive/sphere.ts new file mode 100644 index 0000000000000000000000000000000000000000..bcf1460dca677832fa68f057e4ef87b2ca6d87b8 --- /dev/null +++ b/src/mol-geo/primitive/sphere.ts @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Polyhedron } from './polyhedron' +import { Icosahedron } from './icosahedron' +import { Primitive } from './primitive'; + +const { vertices, indices } = Icosahedron() + +/** Calculate vertex count for subdived icosahedron */ +export function sphereVertexCount(detail: number) { + return 10 * Math.pow(Math.pow(2, detail), 2) + 2 +} + +export const DefaultSphereProps = { + radius: 1, + detail: 0 +} +export type SphereProps = Partial<typeof DefaultSphereProps> + +/** Create sphere by subdividing an icosahedron */ +export function Sphere(props?: SphereProps): Primitive { + return Polyhedron(vertices, indices, { ...DefaultSphereProps, ...props }) +} \ No newline at end of file diff --git a/src/mol-geo/primitive/star.ts b/src/mol-geo/primitive/star.ts index f55871a87f9780711c1ccd7ba19aba21672d1c6c..fbbf5043906fbe131db051731b4f817213f996d2 100644 --- a/src/mol-geo/primitive/star.ts +++ b/src/mol-geo/primitive/star.ts @@ -5,6 +5,7 @@ */ import { Vec3 } from 'mol-math/linear-algebra' +import { Primitive } from './primitive'; export const DefaultStarProps = { pointCount: 5, @@ -21,7 +22,7 @@ const p1 = Vec3.zero() const p2 = Vec3.zero() const p3 = Vec3.zero() -export function Star(props?: StarProps) { +export function Star(props?: StarProps): Primitive { const { outerRadius, innerRadius, thickness, pointCount } = { ...DefaultStarProps, ...props } const triangleCount = pointCount * 2 * 2 diff --git a/src/mol-geo/primitive/tube.ts b/src/mol-geo/primitive/tube.ts index ade73172b2ed986f3d836ff4d13ffe7a2b8aa2f7..7bc62c2c0f494a261ebd5ca28a50eb82fb97f668 100644 --- a/src/mol-geo/primitive/tube.ts +++ b/src/mol-geo/primitive/tube.ts @@ -18,7 +18,7 @@ const b = Vec3.zero() const u = Vec3.zero() const v = Vec3.zero() -export function addTube(controlPoints: Helpers.NumberArray, normalVectors: Helpers.NumberArray, binormalVectors: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean, state: MeshBuilderState) { +export function addTube(controlPoints: ArrayLike<number>, normalVectors: ArrayLike<number>, binormalVectors: ArrayLike<number>, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean, state: MeshBuilderState) { const { vertices, normals, indices } = state let vertexCount = vertices.elementCount diff --git a/src/mol-geo/primitive/wedge.ts b/src/mol-geo/primitive/wedge.ts index f15642e1e428e824d8efed00e51c7599112e5224..1b00533691b83741e101278050762b9c8db19dd9 100644 --- a/src/mol-geo/primitive/wedge.ts +++ b/src/mol-geo/primitive/wedge.ts @@ -5,6 +5,7 @@ */ import { Vec3 } from 'mol-math/linear-algebra' +import { Primitive } from './primitive'; export const DefaultWedgeProps = { width: 1, @@ -31,7 +32,7 @@ const nacdf = Vec3.zero() const s = Vec3.zero() -export function Wedge(props?: WedgeProps) { +export function Wedge(props?: WedgeProps): Primitive { const { width, height, depth } = { ...DefaultWedgeProps, ...props } const vertices = new Float32Array(54) 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 ad9c384dabeefb3071fa5fbb4ada91bb9d7621cf..1459b499dd52ea8fca99c58518b83451383cd891 100644 --- a/src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts +++ b/src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts @@ -28,6 +28,8 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru const builder = MeshBuilder.create(256, 128, mesh) const t = Mat4.identity() + const sMat = Mat4.identity() + const sVec = Vec3.zero() const p = Vec3.zero() const pd = Vec3.zero() const p1 = Vec3.zero() @@ -54,11 +56,12 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru const shapeType = getSaccharideShape(c.component.type) switch (shapeType) { case SaccharideShapes.FilledSphere: - builder.addIcosahedron(cGeo.center, radius, 2) + builder.addSphere(cGeo.center, radius, 2) break; case SaccharideShapes.FilledCube: centerAlign(cGeo.center, cGeo.normal, cGeo.direction) builder.addBox(t, { width: side, height: side, depth: side }) + builder.addOctahedron(t) break; case SaccharideShapes.CrossedCube: // TODO split @@ -85,7 +88,18 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru builder.addStar(t, { outerRadius: side, innerRadius: side / 2, thickness: side / 2, pointCount: 5 }) break case SaccharideShapes.FilledDiamond: + centerAlign(cGeo.center, cGeo.normal, cGeo.direction) + Mat4.fromScaling(sMat, Vec3.set(sVec, side * 1.4, side * 1.4, side * 1.4)) + Mat4.mul(t, t, sMat) + builder.addOctahedron(t) + break case SaccharideShapes.DividedDiamond: + // TODO split + centerAlign(cGeo.center, cGeo.normal, cGeo.direction) + Mat4.fromScaling(sMat, Vec3.set(sVec, side * 1.4, side * 1.4, side * 1.4)) + Mat4.mul(t, t, sMat) + builder.addOctahedron(t) + break case SaccharideShapes.FlatDiamond: case SaccharideShapes.Pentagon: centerAlign(cGeo.center, cGeo.normal, cGeo.direction) diff --git a/src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts b/src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts index 6e095c7f13d4bbc89d7fa94468625fd2ccc74830..d1f289ec99b41a30b4356e43b2dfbf80da4f2a22 100644 --- a/src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts +++ b/src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts @@ -46,7 +46,7 @@ async function createPolymerGapCylinderMesh(ctx: RuntimeContext, unit: Unit, mes if (centerA.element === centerB.element) { builder.setId(centerA.element) pos(elements[centerA.element], pA) - builder.addIcosahedron(pA, 0.6, 0) + builder.addSphere(pA, 0.6, 0) } else { pos(elements[centerA.element], pA) pos(elements[centerB.element], pB) diff --git a/src/mol-geo/representation/structure/visual/util/element.ts b/src/mol-geo/representation/structure/visual/util/element.ts index 50a44321e32420b54cf80f80a4ab28f2cbc140e7..885b96aec12a1b09e8a815e48bbb401b001374ef 100644 --- a/src/mol-geo/representation/structure/visual/util/element.ts +++ b/src/mol-geo/representation/structure/visual/util/element.ts @@ -8,7 +8,7 @@ import { Vec3 } from 'mol-math/linear-algebra'; import { Unit, StructureElement } from 'mol-model/structure'; import { SizeTheme } from '../../../../theme'; import { RuntimeContext } from 'mol-task'; -import { icosahedronVertexCount } from '../../../../primitive/icosahedron'; +import { sphereVertexCount } from '../../../../primitive/sphere'; import { Mesh } from '../../../../shape/mesh'; import { MeshBuilder } from '../../../../shape/mesh-builder'; import { ValueCell, defaults } from 'mol-util'; @@ -33,7 +33,7 @@ export function getElementRadius(unit: Unit, props: SizeTheme): StructureElement export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, radius: StructureElement.Property<number>, detail: number, mesh?: Mesh) { const { elements } = unit; const elementCount = elements.length; - const vertexCount = elementCount * icosahedronVertexCount(detail) + const vertexCount = elementCount * sphereVertexCount(detail) const meshBuilder = MeshBuilder.create(vertexCount, vertexCount / 2, mesh) const v = Vec3.zero() @@ -46,7 +46,7 @@ export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, r pos(elements[i], v) meshBuilder.setId(i) - meshBuilder.addIcosahedron(v, radius(l), detail) + meshBuilder.addSphere(v, radius(l), detail) if (i % 10000 === 0 && ctx.shouldUpdate) { await ctx.update({ message: 'Sphere mesh', current: i, max: elementCount }); diff --git a/src/mol-geo/shape/mesh-builder.ts b/src/mol-geo/shape/mesh-builder.ts index f566e1b08e37aa3afc290ef5a027edbf5e1adbe9..9427faa6981313720e1e77208d1c375090507b30 100644 --- a/src/mol-geo/shape/mesh-builder.ts +++ b/src/mol-geo/shape/mesh-builder.ts @@ -12,18 +12,14 @@ import { Box, BoxProps } from '../primitive/box'; import { Plane, PlaneProps } from '../primitive/plane'; import { Wedge, WedgeProps } from '../primitive/wedge'; import { Cylinder, CylinderProps } from '../primitive/cylinder'; -import { Icosahedron, IcosahedronProps } from '../primitive/icosahedron'; +import { Sphere, SphereProps } from '../primitive/sphere'; import { Mesh } from './mesh'; import { getNormalMatrix } from '../util'; import { addSheet } from '../primitive/sheet'; import { addTube } from '../primitive/tube'; import { StarProps, Star } from '../primitive/star'; - -interface Primitive { - vertices: Float32Array - normals: Float32Array - indices: Uint32Array -} +import { Octahedron } from '../primitive/octahedron'; +import { Primitive } from '../primitive/primitive'; export interface MeshBuilderState { vertices: ChunkedArray<number, 3> @@ -32,23 +28,24 @@ export interface MeshBuilderState { } export interface MeshBuilder { - add(t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices?: Uint32Array): void + add(t: Mat4, _vertices: ArrayLike<number>, _normals: ArrayLike<number>, _indices?: ArrayLike<number>): void addBox(t: Mat4, props?: BoxProps): void addPlane(t: Mat4, props?: PlaneProps): void addWedge(t: Mat4, props?: WedgeProps): void addStar(t: Mat4, props?: StarProps): void + addOctahedron(t: Mat4): void addCylinder(start: Vec3, end: Vec3, lengthScale: number, props: CylinderProps): void addDoubleCylinder(start: Vec3, end: Vec3, lengthScale: number, shift: Vec3, props: CylinderProps): void addFixedCountDashedCylinder(start: Vec3, end: Vec3, lengthScale: number, segmentCount: number, props: CylinderProps): void - addIcosahedron(center: Vec3, radius: number, detail: number): void - addTube(centers: Helpers.NumberArray, normals: Helpers.NumberArray, binormals: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean): void - addSheet(centers: Helpers.NumberArray, normals: Helpers.NumberArray, binormals: Helpers.NumberArray, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean): void + addSphere(center: Vec3, radius: number, detail: number): void + addTube(centers: ArrayLike<number>, normals: ArrayLike<number>, binormals: ArrayLike<number>, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean): void + addSheet(centers: ArrayLike<number>, normals: ArrayLike<number>, binormals: ArrayLike<number>, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean): void setId(id: number): void getMesh(): Mesh } const cylinderMap = new Map<string, Primitive>() -const icosahedronMap = new Map<string, Primitive>() +const sphereMap = new Map<string, Primitive>() const up = Vec3.create(0, 1, 0) const tmpV = Vec3.zero() @@ -83,20 +80,20 @@ function getCylinder(props: CylinderProps) { return cylinder } -const tmpIcosahedronMat = Mat4.identity() +const tmpSphereMat = Mat4.identity() -function setIcosahedronMat(m: Mat4, center: Vec3) { +function setSphereMat(m: Mat4, center: Vec3) { return Mat4.setTranslation(m, center) } -function getIcosahedron(props: IcosahedronProps) { +function getSphere(props: SphereProps) { const key = JSON.stringify(props) - let icosahedron = icosahedronMap.get(key) - if (icosahedron === undefined) { - icosahedron = Icosahedron(props) - icosahedronMap.set(key, icosahedron) + let sphere = sphereMap.get(key) + if (sphere === undefined) { + sphere = Sphere(props) + sphereMap.set(key, sphere) } - return icosahedron + return sphere } // TODO cache primitives based on props @@ -113,7 +110,7 @@ export namespace MeshBuilder { let currentId = -1 - function add(t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices: Uint32Array) { + function add(t: Mat4, _vertices: ArrayLike<number>, _normals: ArrayLike<number>, _indices: ArrayLike<number>) { const { elementCount } = vertices const n = getNormalMatrix(tmpMat3, t) for (let i = 0, il = _vertices.length; i < il; i += 3) { @@ -151,6 +148,10 @@ export namespace MeshBuilder { const { vertices, normals, indices } = Star(props) add(t, vertices, normals, indices) }, + addOctahedron: (t: Mat4) => { + const { vertices, normals, indices } = Octahedron() + add(t, vertices, normals, indices) + }, addCylinder: (start: Vec3, end: Vec3, lengthScale: number, props: CylinderProps) => { const d = Vec3.distance(start, end) * lengthScale props.height = d @@ -197,16 +198,16 @@ export namespace MeshBuilder { add(tmpCylinderMat, vertices, normals, indices) } }, - addIcosahedron: (center: Vec3, radius: number, detail: number) => { - const { vertices, normals, indices } = getIcosahedron({ radius, detail }) - setIcosahedronMat(tmpIcosahedronMat, center) - add(tmpIcosahedronMat, vertices, normals, indices) + addSphere: (center: Vec3, radius: number, detail: number) => { + const { vertices, normals, indices } = getSphere({ radius, detail }) + setSphereMat(tmpSphereMat, center) + add(tmpSphereMat, vertices, normals, indices) }, - addTube: (centers: Helpers.NumberArray, normals: Helpers.NumberArray, binormals: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean) => { + addTube: (centers: ArrayLike<number>, normals: ArrayLike<number>, binormals: ArrayLike<number>, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean) => { const addedVertexCount = addTube(centers, normals, binormals, linearSegments, radialSegments, width, height, waveFactor, startCap, endCap, state) for (let i = 0, il = addedVertexCount; i < il; ++i) ChunkedArray.add(ids, currentId); }, - addSheet: (controls: Helpers.NumberArray, normals: Helpers.NumberArray, binormals: Helpers.NumberArray, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean) => { + addSheet: (controls: ArrayLike<number>, normals: ArrayLike<number>, binormals: ArrayLike<number>, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean) => { const addedVertexCount = addSheet(controls, normals, binormals, linearSegments, width, height, arrowHeight, startCap, endCap, state) for (let i = 0, il = addedVertexCount; i < il; ++i) ChunkedArray.add(ids, currentId); }, diff --git a/src/mol-math/linear-algebra/3d/vec3.ts b/src/mol-math/linear-algebra/3d/vec3.ts index 7d45fb810d52d8965f7275f82454034aa12b9083..2527ca8724068857a12562845ee7895800901c72 100644 --- a/src/mol-math/linear-algebra/3d/vec3.ts +++ b/src/mol-math/linear-algebra/3d/vec3.ts @@ -46,7 +46,7 @@ namespace Vec3 { return { x: v[0], y: v[1], z: v[2] }; } - export function fromArray(v: Vec3, array: Helpers.NumberArray, offset: number) { + export function fromArray(v: Vec3, array: ArrayLike<number>, offset: number) { v[0] = array[offset + 0] v[1] = array[offset + 1] v[2] = array[offset + 2]