diff --git a/src/mol-geo/primitive/polyhedron.ts b/src/mol-geo/primitive/polyhedron.ts index e5a4be6eef5830c6f707fef965d6d0124d528e1b..558cce08d59c2e61618855a2bfb5697e386e0eea 100644 --- a/src/mol-geo/primitive/polyhedron.ts +++ b/src/mol-geo/primitive/polyhedron.ts @@ -7,7 +7,7 @@ // adapted from three.js, MIT License Copyright 2010-2018 three.js authors import { Vec3 } from 'mol-math/linear-algebra' -import { computeVertexNormals, appplyRadius } from '../util' +import { computeIndexedVertexNormals, appplyRadius } from '../util' export const DefaultPolyhedronProps = { radius: 1, @@ -17,9 +17,8 @@ export type PolyhedronProps = Partial<typeof DefaultPolyhedronProps> export default function Polyhedron(_vertices: Helpers.NumberArray, _indices: Helpers.NumberArray, props?: PolyhedronProps) { const { radius, detail } = { ...DefaultPolyhedronProps, ...props } - - const vertices: number[] = []; - const indices: number[] = []; + const builder = createBuilder() + const { vertices, indices } = builder // the subdivision creates the vertex buffer data subdivide(detail); @@ -28,7 +27,7 @@ export default function Polyhedron(_vertices: Helpers.NumberArray, _indices: Hel appplyRadius(vertices, radius); const normals = new Float32Array(vertices.length); - computeVertexNormals(vertices, normals) + computeIndexedVertexNormals(vertices, indices, normals) // this.normalizeNormals(); // smooth normals return { @@ -86,18 +85,63 @@ export default function Polyhedron(_vertices: Helpers.NumberArray, _indices: Hel } } + // // 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) { const k = Math.floor(j / 2) if (j % 2 === 0) { - vertices.push(...v[i][k + 1], ...v[i + 1][k], ...v[i][k]) + builder.add + builder.add(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]) + builder.add(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) } } } +} + +interface Builder { + vertices: number[] + indices: number[] + add: (v1: Vec3, v2: Vec3, v3: Vec3) => void +} + +function createBuilder(): Builder { + const vertices: number[] = [] + const indices: number[] = [] + + const vertexMap = new Map<string, number>() + + function addVertex(v: Vec3) { + const key = `${v[0].toFixed(5)}|${v[1].toFixed(5)}|${v[2].toFixed(5)}` + let idx = vertexMap.get(key) + if (idx === undefined) { + idx = vertices.length / 3 + vertexMap.set(key, idx) + vertices.push(...v) + } + return idx + } + + return { + vertices, + indices, + add: (v1: Vec3, v2: Vec3, v3: Vec3) => { + indices.push(addVertex(v1), addVertex(v2), addVertex(v3)) + } + } } \ No newline at end of file diff --git a/src/mol-geo/representation/structure/spacefill.ts b/src/mol-geo/representation/structure/spacefill.ts index bf3cb8f3511f65a6e690e8254bc6e39d74bae5b5..03cc5f995c07f7d23620927006ddd8f5fcc86a5d 100644 --- a/src/mol-geo/representation/structure/spacefill.ts +++ b/src/mol-geo/representation/structure/spacefill.ts @@ -15,8 +15,7 @@ import { RepresentationProps, UnitsRepresentation } from './index'; import { Task } from 'mol-task' import { MeshBuilder } from '../../shape/mesh-builder'; import { VdwRadius } from 'mol-model/structure/model/properties/atomic'; -import { ElementColor, colorToArray, normalizedColorToArray, ColorScale, colorToRgb } from '../../color'; -import { ChunkedArray } from 'mol-data/util'; +import { ElementColor, colorToArray, normalizedColorToArray, ColorScale } from '../../color'; import { Color } from 'mol-gl/renderable/mesh'; import { createColorTexture } from 'mol-gl/util'; @@ -68,7 +67,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> { } const mesh = meshBuilder.getMesh() - console.log(mesh) + // console.log(mesh) if (!mesh.offsetBuffer.ref.value) return const unitsCount = units.length @@ -77,7 +76,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> { Mat4.toArray(units[i].operator.matrix, transformArray, i * 16) } - console.log({ unitsCount, elementCount }) + // console.log({ unitsCount, elementCount }) let colorType = 'element' let color: Color diff --git a/src/mol-geo/shape/mesh-builder.ts b/src/mol-geo/shape/mesh-builder.ts index 6122d7aea49145d973f56e32c8455d5665efe5d2..7bf4cf995851893c66f66fc874389670b5033707 100644 --- a/src/mol-geo/shape/mesh-builder.ts +++ b/src/mol-geo/shape/mesh-builder.ts @@ -13,6 +13,12 @@ import Cylinder, { CylinderProps } from '../primitive/cylinder'; import Icosahedron, { IcosahedronProps } from '../primitive/icosahedron'; import { Mesh } from './mesh'; +type Primitive = { + vertices: Float32Array + normals: Float32Array + indices: Uint32Array +} + export interface MeshBuilder { add(t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices?: Uint32Array): number addBox(t: Mat4, props?: BoxProps): number @@ -37,6 +43,8 @@ export namespace MeshBuilder { let currentId = -1 + const icosahedronMap = new Map<string, Primitive>() + const add = (t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices: Uint32Array) => { const { elementCount, elementSize } = vertices for (let i = 0, il = _vertices.length; i < il; i += 3) { @@ -67,8 +75,13 @@ export namespace MeshBuilder { const cylinder = Cylinder(props) return add(t, cylinder.vertices, cylinder.normals, cylinder.indices) }, - addIcosahedron: (t: Mat4, props?: IcosahedronProps) => { - const icosahedron = Icosahedron(props) + addIcosahedron: (t: Mat4, props: IcosahedronProps) => { + const key = JSON.stringify(props) + let icosahedron = icosahedronMap.get(key) + if (icosahedron === undefined) { + icosahedron = Icosahedron(props) + icosahedronMap.set(key, icosahedron) + } return add(t, icosahedron.vertices, icosahedron.normals, icosahedron.indices) }, setId: (id: number) => { diff --git a/src/mol-gl/shader/mesh.vert b/src/mol-gl/shader/mesh.vert index 8f8b904babb84bd51c7404c582377a785724e5e9..91b2c82de177b602dc183825e80bd208fd6c088a 100644 --- a/src/mol-gl/shader/mesh.vert +++ b/src/mol-gl/shader/mesh.vert @@ -45,7 +45,6 @@ void main(){ #elif defined( INSTANCE_COLOR ) vColor = read_vec3(colorTex, instanceId, colorTexSize); #elif defined( ELEMENT_COLOR ) - // vColor = read_vec3(colorTex, elementId, colorTexSize); vColor = read_vec3(colorTex, instanceId * float(elementCount) + elementId, colorTexSize); #endif diff --git a/src/mol-view/controls/trackball.ts b/src/mol-view/controls/trackball.ts index 3e3ee683d2aec00abd2f2b7dda7be3ae0b05262b..5535d7c6f6d562b00ca4d315bd5ff41848244ab0 100644 --- a/src/mol-view/controls/trackball.ts +++ b/src/mol-view/controls/trackball.ts @@ -17,10 +17,10 @@ export const DefaultTrackballControlsProps = { noScroll: true, rotateSpeed: 3.0, - zoomSpeed: 2.0, - panSpeed: 0.1, + zoomSpeed: 4.0, + panSpeed: 0.8, - staticMoving: false, + staticMoving: true, dynamicDampingFactor: 0.2, minDistance: 0,