|
@@ -21,15 +21,7 @@ import { RepresentationContext, RepresentationParamsGetter } from '../representa
|
|
|
import { Interval } from '../../mol-data/int';
|
|
|
import { Loci, EmptyLoci } from '../../mol-model/loci';
|
|
|
import { PickingId } from '../../mol-geo/geometry/picking';
|
|
|
-import { eachVolumeLoci } from './util';
|
|
|
-
|
|
|
-
|
|
|
-const v3set = Vec3.set;
|
|
|
-const v3normalize = Vec3.normalize;
|
|
|
-const v3sub = Vec3.sub;
|
|
|
-const v3addScalar = Vec3.addScalar;
|
|
|
-const v3scale = Vec3.scale;
|
|
|
-const v3toArray = Vec3.toArray;
|
|
|
+import { createVolumeTexture2d, createVolumeTexture3d, eachVolumeLoci } from './util';
|
|
|
|
|
|
function getBoundingBox(gridDimension: Vec3, transform: Mat4) {
|
|
|
const bbox = Box3D();
|
|
@@ -40,75 +32,9 @@ function getBoundingBox(gridDimension: Vec3, transform: Mat4) {
|
|
|
|
|
|
|
|
|
|
|
|
-function getVolumeTexture2dLayout(dim: Vec3, maxTextureSize: number) {
|
|
|
- let width = 0;
|
|
|
- let height = dim[1];
|
|
|
- let rows = 1;
|
|
|
- let columns = dim[0];
|
|
|
- if (maxTextureSize < dim[0] * dim[2]) {
|
|
|
- columns = Math.floor(maxTextureSize / dim[0]);
|
|
|
- rows = Math.ceil(dim[2] / columns);
|
|
|
- width = columns * dim[0];
|
|
|
- height *= rows;
|
|
|
- } else {
|
|
|
- width = dim[0] * dim[2];
|
|
|
- }
|
|
|
- return { width, height, columns, rows };
|
|
|
-}
|
|
|
-
|
|
|
-function createVolumeTexture2d(volume: Volume, maxTextureSize: number) {
|
|
|
- const { cells: { space, data }, stats: { max, min } } = volume.grid;
|
|
|
- const dim = space.dimensions as Vec3;
|
|
|
- const { dataOffset: o } = space;
|
|
|
- const { width, height } = getVolumeTexture2dLayout(dim, maxTextureSize);
|
|
|
-
|
|
|
- const array = new Uint8Array(width * height * 4);
|
|
|
- const textureImage = { array, width, height };
|
|
|
-
|
|
|
- const diff = max - min;
|
|
|
- const [ xn, yn, zn ] = dim;
|
|
|
-
|
|
|
- const n0 = Vec3();
|
|
|
- const n1 = Vec3();
|
|
|
-
|
|
|
- const xn1 = xn - 1;
|
|
|
- const yn1 = yn - 1;
|
|
|
- const zn1 = zn - 1;
|
|
|
-
|
|
|
- for (let z = 0; z < zn; ++z) {
|
|
|
- for (let y = 0; y < yn; ++y) {
|
|
|
- for (let x = 0; x < xn; ++x) {
|
|
|
- const column = Math.floor(((z * xn) % width) / xn);
|
|
|
- const row = Math.floor((z * xn) / width);
|
|
|
- const px = column * xn + x;
|
|
|
- const index = 4 * ((row * yn * width) + (y * width) + px);
|
|
|
- const offset = o(x, y, z);
|
|
|
-
|
|
|
- v3set(n0,
|
|
|
- data[o(Math.max(0, x - 1), y, z)],
|
|
|
- data[o(x, Math.max(0, y - 1), z)],
|
|
|
- data[o(x, y, Math.max(0, z - 1))]
|
|
|
- );
|
|
|
- v3set(n1,
|
|
|
- data[o(Math.min(xn1, x + 1), y, z)],
|
|
|
- data[o(x, Math.min(yn1, y + 1), z)],
|
|
|
- data[o(x, y, Math.min(zn1, z + 1))]
|
|
|
- );
|
|
|
- v3normalize(n0, v3sub(n0, n0, n1));
|
|
|
- v3addScalar(n0, v3scale(n0, n0, 0.5), 0.5);
|
|
|
- v3toArray(v3scale(n0, n0, 255), array, index);
|
|
|
-
|
|
|
- array[index + 3] = ((data[offset] - min) / diff) * 255;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return textureImage;
|
|
|
-}
|
|
|
-
|
|
|
export function createDirectVolume2d(ctx: RuntimeContext, webgl: WebGLContext, volume: Volume, directVolume?: DirectVolume) {
|
|
|
const gridDimension = volume.grid.cells.space.dimensions as Vec3;
|
|
|
- const textureImage = createVolumeTexture2d(volume, webgl.maxTextureSize);
|
|
|
+ const textureImage = createVolumeTexture2d(volume, 'normals');
|
|
|
|
|
|
const transform = Grid.getGridToCartesianTransform(volume.grid);
|
|
|
const bbox = getBoundingBox(gridDimension, transform);
|
|
@@ -123,51 +49,6 @@ export function createDirectVolume2d(ctx: RuntimeContext, webgl: WebGLContext, v
|
|
|
|
|
|
|
|
|
|
|
|
-function createVolumeTexture3d(volume: Volume) {
|
|
|
- const { cells: { space, data }, stats: { max, min } } = volume.grid;
|
|
|
- const [ width, height, depth ] = space.dimensions as Vec3;
|
|
|
- const { dataOffset: o } = space;
|
|
|
-
|
|
|
- const array = new Uint8Array(width * height * depth * 4);
|
|
|
- const textureVolume = { array, width, height, depth };
|
|
|
- const diff = max - min;
|
|
|
-
|
|
|
- const n0 = Vec3();
|
|
|
- const n1 = Vec3();
|
|
|
-
|
|
|
- const width1 = width - 1;
|
|
|
- const height1 = height - 1;
|
|
|
- const depth1 = depth - 1;
|
|
|
-
|
|
|
- let i = 0;
|
|
|
- for (let z = 0; z < depth; ++z) {
|
|
|
- for (let y = 0; y < height; ++y) {
|
|
|
- for (let x = 0; x < width; ++x) {
|
|
|
- const offset = o(x, y, z);
|
|
|
-
|
|
|
- v3set(n0,
|
|
|
- data[o(Math.max(0, x - 1), y, z)],
|
|
|
- data[o(x, Math.max(0, y - 1), z)],
|
|
|
- data[o(x, y, Math.max(0, z - 1))]
|
|
|
- );
|
|
|
- v3set(n1,
|
|
|
- data[o(Math.min(width1, x + 1), y, z)],
|
|
|
- data[o(x, Math.min(height1, y + 1), z)],
|
|
|
- data[o(x, y, Math.min(depth1, z + 1))]
|
|
|
- );
|
|
|
- v3normalize(n0, v3sub(n0, n0, n1));
|
|
|
- v3addScalar(n0, v3scale(n0, n0, 0.5), 0.5);
|
|
|
- v3toArray(v3scale(n0, n0, 255), array, i);
|
|
|
-
|
|
|
- array[i + 3] = ((data[offset] - min) / diff) * 255;
|
|
|
- i += 4;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return textureVolume;
|
|
|
-}
|
|
|
-
|
|
|
function getUnitToCartn(grid: Grid) {
|
|
|
if (grid.transform.kind === 'matrix') {
|
|
|
return {
|