Jelajahi Sumber

use mesh-builder for spacefill repr

Alexander Rose 7 tahun lalu
induk
melakukan
5151fb5fba

+ 48 - 50
src/apps/render-test/state.ts

@@ -32,7 +32,7 @@ async function getPdb(pdb: string) {
 }
 
 import mcubes from './mcubes'
-import Cylinder from 'mol-geo/primitive/cylinder';
+// import Cylinder from 'mol-geo/primitive/cylinder';
 
 export default class State {
     async initRenderer (container: HTMLDivElement) {
@@ -41,8 +41,8 @@ export default class State {
         const p1 = Vec3.create(0, 4, 0)
         const p2 = Vec3.create(-3, 0, 0)
 
-        const position = ValueCell.create(new Float32Array([0, -1, 0, -1, 0, 0, 1, 1, 0]))
-        const normal = ValueCell.create(new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0]))
+        // const position = ValueCell.create(new Float32Array([0, -1, 0, -1, 0, 0, 1, 1, 0]))
+        // const normal = ValueCell.create(new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0]))
 
         const transformArray1 = ValueCell.create(new Float32Array(16))
         const transformArray2 = ValueCell.create(new Float32Array(16 * 3))
@@ -61,41 +61,41 @@ export default class State {
             255, 0, 0
         ])
 
-        const points = createRenderObject('point', {
-            position,
-            transform: transformArray1
-        })
-        renderer.add(points)
-
-        const mesh = createRenderObject('mesh', {
-            position,
-            normal,
-            color,
-            transform: transformArray2
-        })
-        renderer.add(mesh)
-
-        const cylinder = Cylinder({ height: 3, radiusBottom: 0.5, radiusTop: 0.5 })
-        console.log(cylinder)
-        const cylinderMesh = createRenderObject('mesh', {
-            position: ValueCell.create(cylinder.vertices),
-            normal: ValueCell.create(cylinder.normals),
-            color,
-            transform: transformArray2
-        }, cylinder.indices)
-        renderer.add(cylinderMesh)
-
-        const sphere = Icosahedron()
-        console.log(sphere)
-
-        const box = Box()
-        console.log(box)
-
-        const points2 = createRenderObject('point', {
-            position: ValueCell.create(new Float32Array(box.vertices)),
-            transform: transformArray1
-        })
-        renderer.add(points2)
+        // const points = createRenderObject('point', {
+        //     position,
+        //     transform: transformArray1
+        // })
+        // // renderer.add(points)
+
+        // const mesh = createRenderObject('mesh', {
+        //     position,
+        //     normal,
+        //     color,
+        //     transform: transformArray2
+        // })
+        // renderer.add(mesh)
+
+        // const cylinder = Cylinder({ height: 3, radiusBottom: 0.5, radiusTop: 0.5 })
+        // console.log(cylinder)
+        // const cylinderMesh = createRenderObject('mesh', {
+        //     position: ValueCell.create(cylinder.vertices),
+        //     normal: ValueCell.create(cylinder.normals),
+        //     color,
+        //     transform: transformArray2
+        // }, cylinder.indices)
+        // renderer.add(cylinderMesh)
+
+        // const sphere = Icosahedron()
+        // console.log(sphere)
+
+        // const box = Box()
+        // console.log(box)
+
+        // const points2 = createRenderObject('point', {
+        //     position: ValueCell.create(new Float32Array(box.vertices)),
+        //     transform: transformArray1
+        // })
+        // renderer.add(points2)
 
         let rr = 0.7;
         function cubesF(x: number, y: number, z: number) {
@@ -107,8 +107,13 @@ export default class State {
             position: cubes.surface.vertexBuffer,
             normal: cubes.surface.normalBuffer,
             color,
-            transform: transformArray1,
-        }, cubes.surface.indexBuffer.ref.value);
+            transform: transformArray2,
+            elements: cubes.surface.indexBuffer,
+
+            instanceCount: transformArray2.ref.value.length / 16,
+            elementCount: cubes.surface.triangleCount,
+            positionCount: cubes.surface.vertexCount
+        }, {});
         const mesh2 = makeCubesMesh();
         renderer.add(mesh2)
 
@@ -120,18 +125,11 @@ export default class State {
         async function createSpacefills (structure: Structure) {
             const spacefills: RenderObject[] = []
             const { elements, units } = structure;
-            const unitIds = ElementSet.unitIds(elements);
-            for (let i = 0, _i = unitIds.length; i < _i; i++) {
-                const unitId = unitIds[i];
-                const unit = units[unitId];
-                const atomGroup = ElementSet.unitGetByIndex(elements, i);
-
-                const spacefill = Spacefill()
-                spacefills.push(...await Run(spacefill.create(unit, atomGroup), log, 1))
-            }
+            const spacefill = Spacefill()
+            spacefills.push(...await Run(spacefill.create(units, elements), log, 100))
             return spacefills
         }
-        const structures = await getPdb('1crn')
+        const structures = await getPdb('3pqr')
         const spacefills = await createSpacefills(structures[0])
         spacefills.forEach(renderer.add)
 

+ 2 - 2
src/mol-geo/primitive/box.ts

@@ -16,9 +16,9 @@ export const DefaultBoxProps = {
     heightSegments: 1,
     depthSegments: 1
 }
-export type BoxProps = typeof DefaultBoxProps
+export type BoxProps = Partial<typeof DefaultBoxProps>
 
-export default function Box(props?: Partial<BoxProps>) {
+export default function Box(props?: BoxProps) {
     const { width, height, depth, widthSegments, heightSegments, depthSegments } = { ...DefaultBoxProps, ...props }
 
     // buffers

+ 2 - 2
src/mol-geo/primitive/cylinder.ts

@@ -18,9 +18,9 @@ export const DefaultCylinderProps = {
     thetaStart: 0.0,
     thetaLength: Math.PI * 2
 }
-export type CylinderProps = typeof DefaultCylinderProps
+export type CylinderProps = Partial<typeof DefaultCylinderProps>
 
-export default function Cylinder(props?: Partial<CylinderProps>) {
+export default function Cylinder(props?: CylinderProps) {
     const { radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength } = { ...DefaultCylinderProps, ...props };
 
     // buffers

+ 2 - 2
src/mol-geo/primitive/icosahedron.ts

@@ -27,8 +27,8 @@ export const DefaultIcosahedronProps = {
     radius: 1,
     detail: 0
 }
-export type IcosahedronProps = typeof DefaultIcosahedronProps
+export type IcosahedronProps = Partial<typeof DefaultIcosahedronProps>
 
-export default function Icosahedron(props?: Partial<IcosahedronProps>) {
+export default function Icosahedron(props?: IcosahedronProps) {
     return Polyhedron(vertices, indices, { ...DefaultIcosahedronProps, ...props })
 }

+ 4 - 2
src/mol-geo/primitive/polyhedron.ts

@@ -13,9 +13,9 @@ export const DefaultPolyhedronProps = {
     radius: 1,
     detail: 0
 }
-export type PolyhedronProps = typeof DefaultPolyhedronProps
+export type PolyhedronProps = Partial<typeof DefaultPolyhedronProps>
 
-export default function Polyhedron(_vertices: Helpers.NumberArray, _indices: Helpers.NumberArray, props?: Partial<PolyhedronProps>) {
+export default function Polyhedron(_vertices: Helpers.NumberArray, _indices: Helpers.NumberArray, props?: PolyhedronProps) {
     const { radius, detail } = { ...DefaultPolyhedronProps, ...props }
 
     const vertices: number[] = [];
@@ -95,6 +95,8 @@ export default function Polyhedron(_vertices: Helpers.NumberArray, _indices: Hel
                 } 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)
             }
         }
     }

+ 2 - 2
src/mol-geo/representation/structure/index.ts

@@ -15,7 +15,7 @@ export interface RepresentationProps {
 }
 
 export interface UnitRepresentation {
-    create: (unit: Unit, elementGroup: ElementGroup, props?: Partial<RepresentationProps>) => Task<RenderObject[]>,
+    create: (units: ReadonlyArray<Unit>, elements: ElementSet, props?: Partial<RepresentationProps>) => Task<RenderObject[]>,
     update: (props: RepresentationProps) => boolean,
 }
 
@@ -42,7 +42,7 @@ export class StructureRepresentation {
 
             }
 
-            const u = this.repr.create(units[0], 0 as any, 0 as any);
+            const u = this.repr.create(units, 0 as any, 0 as any);
             await ctx.update('Building units...');
             await ctx.runChild(u);
 

+ 37 - 40
src/mol-geo/representation/structure/spacefill.ts

@@ -8,78 +8,75 @@ import { ValueCell } from 'mol-util/value-cell'
 
 import { createRenderObject, RenderObject } from 'mol-gl/renderer'
 import { createColorTexture } from 'mol-gl/util';
-import Icosahedron from 'mol-geo/primitive/icosahedron'
 import { Vec3, Mat4 } from 'mol-math/linear-algebra'
 import { OrderedSet } from 'mol-data/int'
-import { Element, ElementGroup, Unit } from 'mol-model/structure';
+import { Element, Unit, ElementSet } from 'mol-model/structure';
 import P from 'mol-model/structure/query/properties';
 import { RepresentationProps, UnitRepresentation } from './index';
 import { Task } from 'mol-task'
+import { MeshBuilder } from '../../shape/mesh-builder';
 
 export default function Spacefill(): UnitRepresentation {
-    let vertices: Float32Array
-    let normals: Float32Array
-
     const renderObjects: RenderObject[] = []
 
     // unit: Unit, atomGroup: AtomGroup
 
     return {
-        create: (unit: Unit, elementGroup: ElementGroup, props: Partial<RepresentationProps> = {}) => Task.create('Spacefill', async ctx => {
-            const elementCount = OrderedSet.size(elementGroup.elements)
-
+        create: (units: ReadonlyArray<Unit>, elements: ElementSet, props: Partial<RepresentationProps> = {}) => Task.create('Spacefill', async ctx => {
             const l = Element.Location();
-            l.unit = unit;
+            const meshBuilder = MeshBuilder.create()
 
-            const sphere = Icosahedron({ radius: 1, detail: 0 })
-            const vertexCount = sphere.vertices.length / 3
+            const unitIds = ElementSet.unitIds(elements);
+            for (let i = 0, _i = unitIds.length; i < _i; i++) {
+                const unitId = unitIds[i];
+                const unit = units[unitId];
+                const elementGroup = ElementSet.unitGetByIndex(elements, i);
 
-            vertices = new Float32Array(elementCount * vertexCount * 3)
-            normals = new Float32Array(elementCount * vertexCount * 3)
+                const elementCount = OrderedSet.size(elementGroup.elements)
 
-            const v = Vec3.zero()
-            const m = Mat4.identity()
+                l.unit = unit;
 
-            for (let i = 0; i < elementCount; i++) {
-                l.element = OrderedSet.getAt(elementGroup.elements, i)
+                const v = Vec3.zero()
+                const m = Mat4.identity()
 
-                v[0] = P.atom.x(l)
-                v[1] = P.atom.y(l)
-                v[2] = P.atom.z(l)
-                Mat4.setTranslation(m, v)
+                for (let i = 0; i < elementCount; i++) {
+                    l.element = OrderedSet.getAt(elementGroup.elements, i)
 
-                for (let j = 0; j < vertexCount; ++j) {
-                    Vec3.fromArray(v, sphere.vertices, j * 3)
-                    Vec3.transformMat4(v, v, m)
-                    Vec3.toArray(v, vertices, i * vertexCount * 3 + j * 3)
-                }
+                    v[0] = P.atom.x(l)
+                    v[1] = P.atom.y(l)
+                    v[2] = P.atom.z(l)
+                    Mat4.setTranslation(m, v)
 
-                normals.set(sphere.normals, i * vertexCount * 3);
+                    meshBuilder.addIcosahedron(m, { radius: P.atom.vdw(l), detail: 1 })
+                }
 
-                if (i % 100 === 0 && ctx.shouldUpdate) {
-                    await ctx.update({ message: 'Spacefill', current: i, max: elementCount });
+                if (i % 10 === 0 && ctx.shouldUpdate) {
+                    await ctx.update({ message: 'Spacefill', current: i, max: _i });
                 }
             }
 
-            const transformArray = new Float32Array(16)
+            const transformArray = new Float32Array(32)
             const m4 = Mat4.identity()
             Mat4.toArray(m4, transformArray, 0)
 
             const color = ValueCell.create(createColorTexture(1))
             color.ref.value.set([ 0, 0, 255 ])
 
-            const spheres = createRenderObject(
-                'mesh',
-                {
-                    position: ValueCell.create(new Float32Array(vertices)),
-                    normal: ValueCell.create(new Float32Array(normals)),
-                    color,
-                    transform: ValueCell.create(transformArray)
-                }
-            )
+            const mesh = meshBuilder.getMesh()
+
+            // console.log(mesh)
 
-            // console.log({ vertices, normals, vertexCount, atomCount })
+            const spheres = createRenderObject('mesh', {
+                position: mesh.vertexBuffer,
+                normal: mesh.normalBuffer,
+                color,
+                transform: ValueCell.create(transformArray),
+                elements: mesh.indexBuffer,
 
+                instanceCount: transformArray.length / 16,
+                elementCount: mesh.triangleCount,
+                positionCount: mesh.vertexCount
+            }, {})
             renderObjects.push(spheres)
 
             return renderObjects

+ 20 - 6
src/mol-geo/shape/mesh-builder.ts

@@ -9,18 +9,22 @@ import { Vec3, Mat4 } from 'mol-math/linear-algebra';
 import { ChunkedArray } from 'mol-data/util';
 
 import Box, { BoxProps } from '../primitive/box';
+import Icosahedron, { IcosahedronProps } from '../primitive/icosahedron';
 import { Mesh } from './mesh';
 
-type ElementId = { id: number }
+type ElementId = { id?: number }
 
 export interface MeshBuilder {
     add(t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices?: Uint32Array): number
     addBox(t: Mat4, props?: BoxProps & ElementId): number
+    addIcosahedron(t: Mat4, props?: IcosahedronProps & ElementId): number
     getMesh(): Mesh
 }
 
 const tmpV = Vec3.zero()
 
+// TODO cache primitives based on props
+
 export namespace MeshBuilder {
     export function create(initialCount = 2048, chunkSize = 1024): MeshBuilder {
         const vertices = ChunkedArray.create(Float32Array, 3, chunkSize, initialCount);
@@ -32,16 +36,22 @@ export namespace MeshBuilder {
 
         ChunkedArray.compact(indices, true)
 
-        const add = (t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices?: Uint32Array) => {
-            const offset = vertices.elementCount * vertices.elementSize
+        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) {
+                // position
                 Vec3.fromArray(tmpV, _vertices, i)
                 Vec3.transformMat4(tmpV, tmpV, t)
-                // Vec3.transformDirection(tmpV, tmpV, n)  // TODO
                 ChunkedArray.add3(vertices, tmpV[0], tmpV[1], tmpV[2]);
+                // normal
+                Vec3.fromArray(tmpV, _normals, i)
+                // Vec3.transformDirection(tmpV, tmpV, n)  // TODO
+                ChunkedArray.add3(normals, tmpV[0], tmpV[1], tmpV[2]);
             }
-            // ChunkedArray.add(vertices, _vertices[i])
-            return offset
+            for (let i = 0, il = _indices.length; i < il; i += 3) {
+                ChunkedArray.add3(indices, _indices[i] + elementCount, _indices[i + 1] + elementCount, _indices[i + 2] + elementCount);
+            }
+            return elementCount * elementSize
         }
 
         return {
@@ -50,6 +60,10 @@ export namespace MeshBuilder {
                 const box = Box(props)
                 return add(t, box.vertices, box.normals, box.indices)
             },
+            addIcosahedron: (t: Mat4, props?: IcosahedronProps & ElementId) => {
+                const icosahedron = Icosahedron(props)
+                return add(t, icosahedron.vertices, icosahedron.normals, icosahedron.indices)
+            },
             getMesh: () => {
                 return {
                     vertexCount: vertices.elementCount,

+ 18 - 5
src/mol-gl/attribute.ts

@@ -63,13 +63,26 @@ namespace Attribute {
     export type ArrayCell<T> = { array: ReferenceCell<T> }
     export type ReferenceCell<T> = { readonly version: number, readonly value: T }
 
-    export function create<T extends Helpers.TypedArray>(regl: REGL.Regl, array: ValueCell<T>, props: AttributeProps): Attribute<T> {
+    export function create<T extends Float32Array>(regl: REGL.Regl, array: ValueCell<T>, count: number, props: AttributeProps): Attribute<T> {
         const itemSize = props.size
         let _array = array.ref.value
-        let _count = _array.length / itemSize
-        if (props.stride) _count = _array.length / (props.stride / _array.BYTES_PER_ELEMENT)
-        console.log(_array.length, props.stride)
-        const buffer = regl.buffer(_array)
+        let _count = count
+        // if (props.stride) _count = _array.length / (props.stride / _array.BYTES_PER_ELEMENT)
+        // console.log(_array.length, props.stride)
+        // console.log('buffer', {
+        //     data: _array,
+        //     length: count * itemSize,
+        //     usage: 'dynamic',
+        //     type: 'float32'
+        // })
+        const buffer = regl.buffer({
+            data: _array,
+            // length: count * itemSize * _array.BYTES_PER_ELEMENT,
+            usage: 'dynamic',
+            type: 'float32',
+            dimension: itemSize
+        } as any)
+        // console.log(buffer)
         const attribute: REGL.AttributeConfig = { ...props, buffer }
         const growIfNeeded = function(count: number) {
             if (count * itemSize > _array.length) {

+ 1 - 1
src/mol-gl/renderable.ts

@@ -14,7 +14,7 @@ export type AttributesData = { [k: string]: Helpers.TypedArray }
 export type Attributes<T extends AttributesData> = { [K in keyof T]: Attribute<T[K]> }
 export type AttributesBuffers<T extends AttributesData> = { [K in keyof T]: REGL.AttributeConfig }
 
-export interface Renderable<T extends AttributesData> {
+export interface Renderable {
     draw(): void
     // isPicking: () => boolean
     // isVisible: () => boolean

+ 28 - 31
src/mol-gl/renderable/mesh.ts

@@ -18,52 +18,49 @@ type Mesh = 'mesh'
 type Uniforms = { [k: string]: REGL.Uniform | REGL.Texture }
 
 namespace Mesh {
-    export type DataType = {
-        position: { type: Float32Array, itemSize: 3 }
-        normal: { type: Float32Array, itemSize: 3 }
-        transform: { type: Float32Array, itemSize: 16 }
-        color: { type: ColorTexture, itemSize: 16 }
+    export type Data = {
+        position: ValueCell<Float32Array>
+        normal: ValueCell<Float32Array>
+        transform: ValueCell<Float32Array>
+        color: ValueCell<ColorTexture>
+        elements: ValueCell<Uint32Array>
+
+        instanceCount: number
+        elementCount: number
+        positionCount: number
     }
-    export type Data = { [K in keyof DataType]: DataType[K]['type'] }
-    export type BoxedData = { [K in keyof Data]: ValueCell<Data[K]> }
 
-    export function create(regl: REGL.Regl, data: BoxedData, uniforms: Uniforms, elements?: Helpers.UintArray): Renderable<Data> {
-        // console.log('mesh', {
-        //     count: attributes.position.getCount(),
-        //     instances: attributes.transformColumn0.getCount(),
-        //     attributes,
-        //     uniforms
-        // })
-        const instanceCount = data.transform.ref.value.length / 16
-        const instanceId = ValueCell.create(fillSerial(new Float32Array(instanceCount)))
-        // console.log(instanceId)
+    export function create(regl: REGL.Regl, data: Data, uniforms: Uniforms): Renderable {
+        console.log(data)
+        const instanceId = ValueCell.create(fillSerial(new Float32Array(data.instanceCount)))
         const command = regl({
             ...MeshShaders,
             uniforms: {
                 objectId: uniforms.objectId || 0,
-                instanceCount,
+                instanceCount: data.instanceCount,
                 ...createColorUniforms(regl, data.color),
                 ...uniforms
             },
             attributes: getBuffers({
-                instanceId: Attribute.create(regl, instanceId, { size: 1, divisor: 1 }),
-                position: Attribute.create(regl, data.position, { size: 3 }),
-                normal: Attribute.create(regl, data.normal, { size: 3 }),
-                ...createTransformAttributes(regl, data.transform)
+                instanceId: Attribute.create(regl, instanceId, data.instanceCount, { size: 1, divisor: 1 }),
+                position: Attribute.create(regl, data.position, data.positionCount, { size: 3 }),
+                normal: Attribute.create(regl, data.normal, data.positionCount, { size: 3 }),
+                ...createTransformAttributes(regl, data.transform, data.instanceCount)
             }),
-            elements: elements && regl.elements({
-                data: new Uint16Array(elements),
+            elements: regl.elements({
+                data: data.elements.ref.value,
                 primitive: 'triangles',
-                // type: 'uint16',
-                // count: elements.length / 3,
-                // length: elements.length * 2
+                type: 'uint32',
+                count: data.elementCount * 3,
+                // length: count * 3 * 2
             }),
-            count: elements ? elements.length : data.position.ref.value.length / 3,
-            instances: instanceCount,
-            primitive: 'triangles'
+            instances: data.instanceCount,
         })
         return {
-            draw: () => command(),
+            draw: () => {
+                command()
+                console.log(command.stats)
+            }
         }
     }
 }

+ 13 - 13
src/mol-gl/renderable/point.ts

@@ -15,25 +15,25 @@ import { PointShaders } from '../shaders'
 type Point = 'point'
 
 namespace Point {
-    export type DataType = {
-        position: { type: Float32Array, itemSize: 3 }
-        transform: { type: Float32Array, itemSize: 16 }
+    export type Data = {
+        position: ValueCell<Float32Array>
+        transform: ValueCell<Float32Array>
+
+        instanceCount: number
+        positionCount: number
     }
-    export type Data = { [K in keyof DataType]: DataType[K]['type'] }
-    export type BoxedData = { [K in keyof Data]: ValueCell<Data[K]> }
 
-    export function create(regl: REGL.Regl, data: BoxedData): Renderable<Data> {
-        const instanceCount = data.transform.ref.value.length / 16
-        const instanceId = ValueCell.create(fillSerial(new Float32Array(instanceCount)))
+    export function create(regl: REGL.Regl, data: Data): Renderable {
+        const instanceId = ValueCell.create(fillSerial(new Float32Array(data.instanceCount)))
         const command = regl({
             ...PointShaders,
             attributes: getBuffers({
-                instanceId: Attribute.create(regl, instanceId, { size: 1, divisor: 1 }),
-                position: Attribute.create(regl, data.position, { size: 3 }),
-                ...createTransformAttributes(regl, data.transform)
+                instanceId: Attribute.create(regl, instanceId, data.instanceCount, { size: 1, divisor: 1 }),
+                position: Attribute.create(regl, data.position, data.positionCount, { size: 3 }),
+                ...createTransformAttributes(regl, data.transform, data.positionCount)
             }),
-            count: data.position.ref.value.length / 3,
-            instances: instanceCount,
+            count: data.positionCount,
+            instances: data.instanceCount,
             primitive: 'points'
         })
         return {

+ 5 - 5
src/mol-gl/renderable/util.ts

@@ -11,16 +11,16 @@ import { ColorTexture } from '../util';
 import { Attributes, AttributesData, AttributesBuffers } from '../renderable'
 import Attribute from '../attribute'
 
-export function createTransformAttributes (regl: REGL.Regl, transform: ValueCell<Float32Array>) {
+export function createTransformAttributes (regl: REGL.Regl, transform: ValueCell<Float32Array>, count: number) {
     const size = 4
     const divisor = 1
     const bpe = transform.ref.value.BYTES_PER_ELEMENT
     const stride = 16 * bpe
     return {
-        transformColumn0: Attribute.create(regl, transform, { size, divisor, offset: 0, stride }),
-        transformColumn1: Attribute.create(regl, transform, { size, divisor, offset: 4 * bpe, stride }),
-        transformColumn2: Attribute.create(regl, transform, { size, divisor, offset: 8 * bpe, stride }),
-        transformColumn3: Attribute.create(regl, transform, { size, divisor, offset: 12 * bpe, stride })
+        transformColumn0: Attribute.create(regl, transform, count, { size, divisor, offset: 0, stride }),
+        transformColumn1: Attribute.create(regl, transform, count, { size, divisor, offset: 4 * bpe, stride }),
+        transformColumn2: Attribute.create(regl, transform, count, { size, divisor, offset: 8 * bpe, stride }),
+        transformColumn3: Attribute.create(regl, transform, count, { size, divisor, offset: 12 * bpe, stride })
     }
 }
 

+ 9 - 10
src/mol-gl/renderer.ts

@@ -28,13 +28,12 @@ export type RenderData = { [k: string]: ValueCell<Helpers.TypedArray> }
 export interface RenderObject {
     id: number
     type: 'mesh' | 'point'
-    data: any
-    elements: any
-    uniforms: any
+    data: PointRenderable.Data | MeshRenderable.Data
+    uniforms: { [k: string]: REGL.Uniform }
 }
 
-export function createRenderObject(type: 'mesh' | 'point', data: any, elements?: any, uniforms?: any) {
-    return { id: getNextId(), type, data, elements, uniforms }
+export function createRenderObject(type: 'mesh' | 'point', data: PointRenderable.Data | MeshRenderable.Data, uniforms: { [k: string]: REGL.Uniform }) {
+    return { id: getNextId(), type, data, uniforms }
 }
 
 export interface Renderer {
@@ -46,14 +45,14 @@ export interface Renderer {
 
 export function createRenderable(regl: REGL.Regl, o: RenderObject) {
     switch (o.type) {
-        case 'mesh': return MeshRenderable.create(regl, o.data, o.uniforms || {}, o.elements)
-        case 'point': return PointRenderable.create(regl, o.data)
+        case 'mesh': return MeshRenderable.create(regl, o.data as MeshRenderable.Data, o.uniforms || {})
+        case 'point': return PointRenderable.create(regl, o.data as PointRenderable.Data)
     }
 }
 
 export function createRenderer(container: HTMLDivElement): Renderer {
-    const renderableList: Renderable<any>[] = []
-    const objectIdRenderableMap: { [k: number]: Renderable<any> } = {}
+    const renderableList: Renderable[] = []
+    const objectIdRenderableMap: { [k: number]: Renderable } = {}
 
     const regl = glContext.create({
         container,
@@ -65,7 +64,7 @@ export function createRenderer(container: HTMLDivElement): Renderer {
             'EXT_blend_minmax',
             'ANGLE_instanced_arrays'
         ],
-        // profile: true
+        profile: true
     })
 
     const camera = Camera.create(regl, container, {

+ 1 - 0
src/mol-gl/shader/mesh.frag

@@ -71,5 +71,6 @@ void main() {
     vec3 color = vColor * (diffuse + ambient) + specular;
 
     gl_FragColor.rgb = N;
+    // gl_FragColor.rgb = vec3(1.0, 0.0, 0.0);
     gl_FragColor.a = 1.0;
 }

+ 1 - 1
src/mol-gl/shader/point.vert

@@ -21,6 +21,6 @@ attribute vec4 transformColumn0, transformColumn1, transformColumn2, transformCo
 void main(){
     mat4 transform = mat4(transformColumn0, transformColumn1, transformColumn2, transformColumn3);
     // vColor = color;
-    gl_PointSize = 20.0;
+    gl_PointSize = 5.0;
     gl_Position = projection * view * model * transform * vec4(position, 1.0);
 }