common.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. * @author David Sehnal <david.sehnal@gmail.com>
  6. */
  7. import { Unit, Structure } from 'mol-model/structure';
  8. import { Mat4 } from 'mol-math/linear-algebra'
  9. import { createUniformColor, ColorData, createGroupColor, createGroupInstanceColor, createInstanceColor } from '../../../../util/color-data';
  10. import { createUniformSize, SizeData, createGroupSize, createGroupInstanceSize, createInstanceSize } from '../../../../util/size-data';
  11. import { ValueCell } from 'mol-util';
  12. import { LocationIterator } from '../../../../util/location-iterator';
  13. import { Mesh } from '../../../../mesh/mesh';
  14. import { MeshValues } from 'mol-gl/renderable';
  15. import { getMeshData } from '../../../../util/mesh-data';
  16. import { MeshProps, createMeshValues, createRenderableState, createIdentityTransform, TransformData } from '../../../util';
  17. import { StructureProps } from '../..';
  18. import { createMarkers } from '../../../../util/marker-data';
  19. import { createMeshRenderObject } from 'mol-gl/render-object';
  20. import { ColorThemeProps, ColorTheme } from 'mol-view/theme/color';
  21. import { SizeThemeProps, SizeTheme } from 'mol-view/theme/size';
  22. import { RuntimeContext } from 'mol-task';
  23. export function createTransforms({ units }: Unit.SymmetryGroup, transformData?: TransformData) {
  24. const unitCount = units.length
  25. const n = unitCount * 16
  26. const array = transformData && transformData.aTransform && transformData.aTransform.ref.value.length >= n ? transformData.aTransform.ref.value : new Float32Array(n)
  27. for (let i = 0; i < unitCount; i++) {
  28. Mat4.toArray(units[i].conformation.operator.matrix, array, i * 16)
  29. }
  30. if (transformData) {
  31. ValueCell.update(transformData.aTransform, array)
  32. return transformData
  33. } else {
  34. return { aTransform: ValueCell.create(array) }
  35. }
  36. }
  37. export function createColors(ctx: RuntimeContext, locationIt: LocationIterator, props: ColorThemeProps, colorData?: ColorData) {
  38. const colorTheme = ColorTheme(props)
  39. switch (colorTheme.kind) {
  40. case 'uniform': return createUniformColor(ctx, locationIt, colorTheme.color, colorData)
  41. case 'group': return createGroupColor(ctx, locationIt, colorTheme.color, colorData)
  42. case 'groupInstance': return createGroupInstanceColor(ctx, locationIt, colorTheme.color, colorData)
  43. case 'instance': return createInstanceColor(ctx, locationIt, colorTheme.color, colorData)
  44. }
  45. }
  46. export function createSizes(locationIt: LocationIterator, props: SizeThemeProps, sizeData?: SizeData): SizeData {
  47. const sizeTheme = SizeTheme(props)
  48. switch (sizeTheme.kind) {
  49. case 'uniform': return createUniformSize(locationIt, sizeTheme.size, sizeData)
  50. case 'group': return createGroupSize(locationIt, sizeTheme.size, sizeData)
  51. case 'groupInstance': return createGroupInstanceSize(locationIt, sizeTheme.size, sizeData)
  52. case 'instance': return createInstanceSize(locationIt, sizeTheme.size, sizeData)
  53. }
  54. }
  55. type StructureMeshProps = Required<MeshProps & StructureProps>
  56. async function _createMeshValues(ctx: RuntimeContext, transforms: TransformData, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
  57. const { instanceCount, groupCount } = locationIt
  58. console.time('createColors mesh')
  59. const color = await createColors(ctx, locationIt, props.colorTheme)
  60. console.timeEnd('createColors mesh')
  61. const marker = createMarkers(instanceCount * groupCount)
  62. const counts = { drawCount: mesh.triangleCount * 3, groupCount, instanceCount }
  63. return {
  64. ...getMeshData(mesh),
  65. ...color,
  66. ...marker,
  67. ...transforms,
  68. elements: mesh.indexBuffer,
  69. ...createMeshValues(props, counts)
  70. }
  71. }
  72. export async function createComplexMeshValues(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
  73. const transforms = createIdentityTransform()
  74. return _createMeshValues(ctx, transforms, mesh, locationIt, props)
  75. }
  76. export async function createUnitsMeshValues(ctx: RuntimeContext, group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
  77. const transforms = createTransforms(group)
  78. return _createMeshValues(ctx, transforms, mesh, locationIt, props)
  79. }
  80. export async function createComplexMeshRenderObject(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
  81. const values = await createComplexMeshValues(ctx, structure, mesh, locationIt, props)
  82. const state = createRenderableState(props)
  83. return createMeshRenderObject(values, state)
  84. }
  85. export async function createUnitsMeshRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
  86. const values = await createUnitsMeshValues(ctx, group, mesh, locationIt, props)
  87. const state = createRenderableState(props)
  88. return createMeshRenderObject(values, state)
  89. }
  90. export async function updateComplexMeshRenderObject(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
  91. const transforms = createIdentityTransform()
  92. return _createMeshValues(ctx, transforms, mesh, locationIt, props)
  93. }