Alexander Rose 7 years ago
parent
commit
d54c9f8a7b

+ 53 - 9
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))
+        }
+    }
 }

+ 3 - 4
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

+ 15 - 2
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) => {

+ 0 - 1
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
 

+ 3 - 3
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,