diff --git a/src/mol-geo/representation/custom/index.ts b/src/mol-geo/representation/custom/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..4189a143f0e87a1a4bc3f93e3bab9373828397ed --- /dev/null +++ b/src/mol-geo/representation/custom/index.ts @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Task } from 'mol-task' +import { RenderObject, createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'; +import { RepresentationProps, Representation } from '..'; +import { PickingId } from '../../util/picking'; +import { Loci, EmptyLoci, CustomLoci, isCustomLoci, isEveryLoci } from 'mol-model/loci'; +import { MarkerAction, applyMarkerAction, createMarkers } from '../../util/marker-data'; +import { createRenderableState, createMeshValues, createIdentityTransform, DefaultMeshProps } from '../util'; +import { Mesh } from '../../shape/mesh'; +import { getMeshData } from '../../util/mesh-data'; +import { MeshValues } from 'mol-gl/renderable'; +import { createValueColor } from '../../util/color-data'; +import { Color } from 'mol-util/color'; +import { CustomLocation } from 'mol-model/location'; +import { ValueCell } from 'mol-util'; + +export interface CustomRepresentation<P extends RepresentationProps = {}> extends Representation<Mesh, P> { } + +export const DefaultCustomProps = { + ...DefaultMeshProps, +} +export type CustomProps = typeof DefaultCustomProps + +export function CustomRepresentation<P extends CustomProps>(): CustomRepresentation<P> { + const renderObjects: RenderObject[] = [] + let _renderObject: MeshRenderObject + let _mesh: Mesh + let _props: P + + function create(mesh: Mesh, props: Partial<P> = {}) { + _props = Object.assign({}, DefaultCustomProps, _props, props) + return Task.create('CustomRepresentation.create', async ctx => { + renderObjects.length = 0 + _mesh = mesh + + const elementCount = mesh.triangleCount + const instanceCount = 1 + + const color = createValueColor(Color(0x7ec0ee)) + const marker = createMarkers(instanceCount * elementCount) + const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount } + + const values: MeshValues = { + ...getMeshData(mesh), + ...createMeshValues(_props, counts), + aTransform: createIdentityTransform(), + ...color, + ...marker, + + elements: mesh.indexBuffer, + } + const state = createRenderableState(_props) + + _renderObject = createMeshRenderObject(values, state) + renderObjects.push(_renderObject) + }); + } + + function update(props: Partial<P>) { + return Task.create('CustomRepresentation.update', async ctx => { + // TODO + }) + } + + return { + get renderObjects () { return renderObjects }, + get props () { return _props }, + create, + update, + getLoci(pickingId: PickingId) { + const { objectId, elementId } = pickingId + if (_renderObject.id === objectId) { + return CustomLoci([ CustomLocation(_mesh, elementId) ]) + } + return EmptyLoci + }, + mark(loci: Loci, action: MarkerAction) { + const { tMarker } = _renderObject.values + let changed = false + if (isEveryLoci(loci)) { + if (applyMarkerAction(tMarker.ref.value.array, 0, _mesh.triangleCount, action)) changed = true + changed = true + } else if (isCustomLoci(loci)) { + for (const l of loci.locations) { + if (l.data === _mesh) { + if (applyMarkerAction(tMarker.ref.value.array, 0, _mesh.triangleCount, action)) changed = true + // TODO + // const idx = l.key + // if (idx !== undefined) { + // if (applyMarkerAction(tMarker.ref.value.array, idx, idx + 1, action)) changed = true + // } + } + } + } + if (changed) { + ValueCell.update(tMarker, tMarker.ref.value) + } + }, + destroy() { + // TODO + } + } +} \ No newline at end of file diff --git a/src/mol-geo/representation/structure/visual/util/common.ts b/src/mol-geo/representation/structure/visual/util/common.ts index fb7f11bf733b6055d8968d4c2dd7b5231608810a..406abfd2e93c228f20e54db68ee8e7b29f4a7154 100644 --- a/src/mol-geo/representation/structure/visual/util/common.ts +++ b/src/mol-geo/representation/structure/visual/util/common.ts @@ -15,7 +15,7 @@ import { LocationIterator } from './location-iterator'; import { Mesh } from '../../../../shape/mesh'; import { MeshValues } from 'mol-gl/renderable'; import { getMeshData } from '../../../../util/mesh-data'; -import { MeshProps, createMeshValues, createRenderableState } from '../../../util'; +import { MeshProps, createMeshValues, createRenderableState, createIdentityTransform } from '../../../util'; import { StructureProps } from '../..'; import { createMarkers } from '../../../../util/marker-data'; import { createMeshRenderObject } from 'mol-gl/render-object'; @@ -32,12 +32,6 @@ export function createTransforms({ units }: Unit.SymmetryGroup, transforms?: Val return transforms ? ValueCell.update(transforms, array) : ValueCell.create(array) } -const identityTransform = new Float32Array(16) -Mat4.toArray(Mat4.identity(), identityTransform, 0) -export function createIdentityTransform(transforms?: ValueCell<Float32Array>) { - return transforms ? ValueCell.update(transforms, identityTransform) : ValueCell.create(identityTransform) -} - export function createColors(locationIt: LocationIterator, props: ColorThemeProps, colorData?: ColorData) { const colorTheme = ColorTheme(props) switch (colorTheme.kind) { diff --git a/src/mol-geo/representation/util.ts b/src/mol-geo/representation/util.ts index 13d34ebeccba7dae263d2b78e32fd55dca4fc02c..410623a925372b241e4c3e4f28e5f6c578b99b10 100644 --- a/src/mol-geo/representation/util.ts +++ b/src/mol-geo/representation/util.ts @@ -10,6 +10,7 @@ import { MeshValues, RenderableState } from 'mol-gl/renderable'; import { defaults } from 'mol-util'; import { Structure } from 'mol-model/structure'; import { fillSerial } from 'mol-util/array'; +import { Mat4 } from 'mol-math/linear-algebra'; export const DefaultBaseProps = { alpha: 1, @@ -28,6 +29,12 @@ export const DefaultMeshProps = { } export type MeshProps = typeof DefaultMeshProps +const identityTransform = new Float32Array(16) +Mat4.toArray(Mat4.identity(), identityTransform, 0) +export function createIdentityTransform(transforms?: ValueCell<Float32Array>) { + return transforms ? ValueCell.update(transforms, identityTransform) : ValueCell.create(identityTransform) +} + type Counts = { drawCount: number, elementCount: number, instanceCount: number } export function createBaseValues(props: Required<BaseProps>, counts: Counts) {