diff --git a/src/mol-geo/geometry/size-data.ts b/src/mol-geo/geometry/size-data.ts index 87211474c561d24aeb46593b057698abd7948e00..f0c4d8e7c597f1a181cfc5ca1737b62a6b9840c0 100644 --- a/src/mol-geo/geometry/size-data.ts +++ b/src/mol-geo/geometry/size-data.ts @@ -31,6 +31,24 @@ export function createSizes(locationIt: LocationIterator, sizeTheme: SizeTheme<a } } +export function getMaxSize(sizeData: SizeData): number { + const type = sizeData.dSizeType.ref.value as SizeType + switch (type) { + case 'uniform': + return sizeData.uSize.ref.value + case 'instance': + case 'group': + case 'groupInstance': + let maxSize = 0 + const array = sizeData.tSize.ref.value.array + for (let i = 0, il = array.length; i < il; ++i) { + const value = array[i] + if (maxSize < value) maxSize = value + } + return maxSize + } +} + export type LocationSize = (location: Location) => number const emptySizeTexture = { array: new Uint8Array(1), width: 1, height: 1 } diff --git a/src/mol-geo/geometry/spheres/spheres-builder.ts b/src/mol-geo/geometry/spheres/spheres-builder.ts index 39db630f863a092be67177d09d89afce46990012..b4fb62c2ade317ad82e988e6e5db2cf4a36580c5 100644 --- a/src/mol-geo/geometry/spheres/spheres-builder.ts +++ b/src/mol-geo/geometry/spheres/spheres-builder.ts @@ -15,7 +15,7 @@ const quadMapping = new Float32Array([ 1.0, -1.0 ]) -const quadMappingIndices = new Uint16Array([ +const quadIndices = new Uint16Array([ 0, 1, 2, 1, 3, 2 ]) @@ -42,8 +42,8 @@ export namespace SpheresBuilder { ChunkedArray.add2(mappings, quadMapping[i * 2], quadMapping[i * 2 + 1]) ChunkedArray.add(groups, group) } - ChunkedArray.add3(indices, offset + quadMappingIndices[0], offset + quadMappingIndices[1], offset + quadMappingIndices[2]) - ChunkedArray.add3(indices, offset + quadMappingIndices[3], offset + quadMappingIndices[4], offset + quadMappingIndices[5]) + ChunkedArray.add3(indices, offset + quadIndices[0], offset + quadIndices[1], offset + quadIndices[2]) + ChunkedArray.add3(indices, offset + quadIndices[3], offset + quadIndices[4], offset + quadIndices[5]) }, getSpheres: () => { const cb = ChunkedArray.compact(centers, true) as Float32Array diff --git a/src/mol-geo/geometry/spheres/spheres.ts b/src/mol-geo/geometry/spheres/spheres.ts index a460d763912dd2cf521ce1f12ddbd2132c9062e6..84c79a72d2c75702eb278c815d08c4d238b273e3 100644 --- a/src/mol-geo/geometry/spheres/spheres.ts +++ b/src/mol-geo/geometry/spheres/spheres.ts @@ -11,12 +11,15 @@ import { TransformData, createIdentityTransform } from '../transform-data'; import { LocationIterator } from 'mol-geo/util/location-iterator'; import { Theme } from 'mol-theme/theme'; import { SpheresValues } from 'mol-gl/renderable/spheres'; -import { createColors, createValueColor } from '../color-data'; +import { createColors } from '../color-data'; import { createMarkers } from '../marker-data'; import { calculateBoundingSphere } from 'mol-gl/renderable/util'; import { ColorNames } from 'mol-util/color/tables'; import { Sphere3D } from 'mol-math/geometry'; -import { createSizes, createValueSize } from '../size-data'; +import { createSizes, getMaxSize } from '../size-data'; +import { NullLocation } from 'mol-model/location'; +import { UniformColorTheme } from 'mol-theme/color/uniform'; +import { UniformSizeTheme } from 'mol-theme/size/uniform'; /** Spheres */ export interface Spheres { @@ -70,7 +73,7 @@ export namespace Spheres { const counts = { drawCount: spheres.sphereCount * 2 * 3, groupCount, instanceCount } - const padding = 5 // TODO get max sphere size + const padding = getMaxSize(size) const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( spheres.centerBuffer.ref.value, spheres.sphereCount * 4, transform.aTransform.ref.value, instanceCount, padding @@ -97,39 +100,16 @@ export namespace Spheres { } export function createValuesSimple(spheres: Spheres, props: Partial<PD.Values<Params>>, colorValue = ColorNames.grey, sizeValue = 1, transform?: TransformData): SpheresValues { - const p = { ...PD.getDefaultValues(Params), ...props } - if (!transform) transform = createIdentityTransform() - const instanceCount = transform.instanceCount.ref.value - const groupCount = 1 - const color = createValueColor(colorValue) - const size = createValueSize(sizeValue) - const marker = createMarkers(instanceCount * groupCount) - const counts = { drawCount: spheres.sphereCount * 2 * 3, groupCount, instanceCount } - - const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( - spheres.centerBuffer.ref.value, spheres.sphereCount * 4, - transform.aTransform.ref.value, instanceCount, sizeValue - ) - - return { - aPosition: spheres.centerBuffer, - aMapping: spheres.mappingBuffer, - aGroup: spheres.groupBuffer, - elements: spheres.indexBuffer, - boundingSphere: ValueCell.create(boundingSphere), - invariantBoundingSphere: ValueCell.create(invariantBoundingSphere), - ...color, - ...size, - ...marker, - ...transform, - - padding: ValueCell.create(sizeValue), - - ...Geometry.createValues(p, counts), - uSizeFactor: ValueCell.create(p.sizeFactor), - dDoubleSided: ValueCell.create(p.doubleSided), + if (!transform) transform = createIdentityTransform() + const locationIterator = LocationIterator(1, transform.instanceCount.ref.value, () => NullLocation, false, () => false) + const theme: Theme = { + color: UniformColorTheme({}, { value: colorValue}), + size: UniformSizeTheme({}, { value: sizeValue}) } + const p = { ...PD.getDefaultValues(Params), ...props } + + return createValues(spheres, transform, locationIterator, theme, p) } export function updateValues(values: SpheresValues, props: PD.Values<Params>) { @@ -139,9 +119,10 @@ export namespace Spheres { } export function updateBoundingSphere(values: SpheresValues, spheres: Spheres) { + const padding = getMaxSize(values) const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( values.aPosition.ref.value, spheres.sphereCount * 4, - values.aTransform.ref.value, values.instanceCount.ref.value, values.padding.ref.value + values.aTransform.ref.value, values.instanceCount.ref.value, padding ) if (!Sphere3D.equals(boundingSphere, values.boundingSphere.ref.value)) { ValueCell.update(values.boundingSphere, boundingSphere)