Skip to content
Snippets Groups Projects
Commit b0240b35 authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, mol-gl

parent 844c1f3d
Branches
Tags
No related merge requests found
Showing
with 110 additions and 44 deletions
......@@ -40,7 +40,7 @@ export type ColorTheme = keyof typeof ColorTheme
export default class State {
viewer: Viewer
pdbId = ''
pdbId = '1crn'
// pdbId = '5ire'
emdId = '8116'
// pdbId = '6G1K'
......@@ -77,6 +77,7 @@ export default class State {
getSpacefillProps (): SpacefillProps {
const colorThemeName = this.colorTheme.getValue()
return {
doubleSided: true,
detail: this.sphereDetail.getValue(),
colorTheme: colorThemeName === 'uniform' ?
{ name: colorThemeName, value: this.colorValue.getValue() } :
......@@ -161,7 +162,10 @@ export default class State {
this.surfaceRepr = VolumeRepresentation(Surface)
await Run(this.surfaceRepr.create(v.volume, {
isoValue: VolumeIsoValue.relative(v.volume.dataStats, 3.0),
alpha: 1.0
alpha: 0.5,
flatShaded: false,
flipSided: true,
doubleSided: true
}), log, 500)
viewer.add(this.surfaceRepr)
......
......@@ -20,7 +20,8 @@ import { deepEqual } from 'mol-util';
export const DefaultPointProps = {
colorTheme: { name: 'instance-index' } as ColorTheme,
sizeTheme: { name: 'vdw' } as SizeTheme,
alpha: 1
alpha: 1,
visible: true
}
export type PointProps = Partial<typeof DefaultPointProps>
......@@ -60,7 +61,7 @@ export default function Point(): UnitsRepresentation<PointProps> {
_units = units
_elementGroup = elementGroup
const { colorTheme, sizeTheme, alpha } = curProps
const { colorTheme, sizeTheme, alpha, visible } = curProps
const elementCount = OrderedSet.size(elementGroup.elements)
const unitCount = units.length
......@@ -86,6 +87,7 @@ export default function Point(): UnitsRepresentation<PointProps> {
points = createPointRenderObject({
objectId: 0,
alpha,
visible,
position: ValueCell.create(vertices),
id: ValueCell.create(fillSerial(new Float32Array(elementCount))),
......
......@@ -23,7 +23,9 @@ import { icosahedronVertexCount } from '../../primitive/icosahedron';
export const DefaultSpacefillProps = {
detail: 0,
colorTheme: { name: 'instance-index' } as ColorTheme,
alpha: 1
alpha: 1,
visible: true,
doubleSided: false
}
export type SpacefillProps = Partial<typeof DefaultSpacefillProps>
......@@ -79,7 +81,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
return Task.create('Spacefill.create', async ctx => {
renderObjects.length = 0 // clear
const { detail, colorTheme, alpha } = { ...DefaultSpacefillProps, ...props }
const { detail, colorTheme, alpha, visible, doubleSided } = { ...DefaultSpacefillProps, ...props }
await ctx.update('Computing spacefill mesh');
const mesh = await ctx.runChild(createSpacefillMesh(units[0], elementGroup, detail))
......@@ -96,6 +98,8 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
spheres = createMeshRenderObject({
objectId: 0,
alpha,
visible,
doubleSided,
position: mesh.vertexBuffer,
normal: mesh.normalBuffer as ValueCell<Float32Array>,
......
......@@ -36,6 +36,7 @@ export function computeVolumeSurface(volume: VolumeData, isoValue: VolumeIsoValu
export const DefaultSurfaceProps = {
isoValue: VolumeIsoValue.relative({ min: 0, max: 0, mean: 0, sigma: 0 }, 0),
alpha: 0.5,
visible: true,
flatShaded: true,
flipSided: true,
doubleSided: true
......@@ -53,13 +54,17 @@ export default function Surface(): VolumeElementRepresentation<SurfaceProps> {
return Task.create('Point.create', async ctx => {
renderObjects.length = 0 // clear
curProps = { ...DefaultSurfaceProps, ...props }
const { alpha, flatShaded, flipSided, doubleSided } = curProps
const { alpha, visible, flatShaded, flipSided, doubleSided } = curProps
const mesh = await ctx.runChild(computeVolumeSurface(volume, curProps.isoValue))
if (!flatShaded) {
Mesh.computeNormalsImmediate(mesh)
}
surface = createMeshRenderObject({
objectId: 0,
alpha,
visible,
position: mesh.vertexBuffer,
normal: mesh.normalBuffer,
......
......@@ -8,7 +8,7 @@ import { Task } from 'mol-task'
import { ValueCell } from 'mol-util'
import { Vec3, Mat4 } from 'mol-math/linear-algebra'
import { Sphere3D } from 'mol-math/geometry'
import { transformPositionArray } from '../util';
import { transformPositionArray/* , transformDirectionArray, getNormalMatrix */ } from '../util';
export interface Mesh {
/** Number of vertices in the mesh */
......@@ -86,7 +86,12 @@ export namespace Mesh {
export function transformRangeImmediate(mesh: Mesh, t: Mat4, offset: number, count: number) {
transformPositionArray(t, mesh.vertexBuffer.ref.value, offset, count)
// transformDirectionArray(n, mesh.normalBuffer.ref.value, offset, count) // TODO
// TODO normals transformation does not work for an unknown reason, ASR
// if (mesh.normalBuffer.ref.value) {
// const n = getNormalMatrix(Mat3.zero(), t)
// transformDirectionArray(n, mesh.normalBuffer.ref.value, offset, count)
// mesh.normalsComputed = true;
// }
mesh.normalsComputed = false;
// mesh.boundingSphere = void 0;
}
......
......@@ -19,21 +19,28 @@ export function normalizeVec3Array<T extends Helpers.NumberArray> (a: T) {
}
}
const tmpV = Vec3.zero()
export function getNormalMatrix(out: Mat3, t: Mat4) {
Mat3.fromMat4(out, t)
Mat3.invert(out, out)
Mat3.transpose(out, out)
return out
}
const tmpV3 = Vec3.zero()
export function transformPositionArray (t: Mat4, array: Helpers.NumberArray, offset: number, count: number) {
for (let i = 0, il = count * 3; i < il; i += 3) {
Vec3.fromArray(tmpV, array, offset + i)
Vec3.transformMat4(tmpV, tmpV, t)
Vec3.toArray(tmpV, array, offset + i)
Vec3.fromArray(tmpV3, array, offset + i)
Vec3.transformMat4(tmpV3, tmpV3, t)
Vec3.toArray(tmpV3, array, offset + i)
}
}
export function transformDirectionArray (n: Mat3, array: Helpers.NumberArray, offset: number, count: number) {
for (let i = 0, il = count * 3; i < il; i += 3) {
Vec3.fromArray(tmpV, array, offset + i)
Vec3.transformMat3(tmpV, tmpV, n)
Vec3.toArray(tmpV, array, offset + i)
Vec3.fromArray(tmpV3, array, offset + i)
Vec3.transformMat3(tmpV3, tmpV3, n)
Vec3.toArray(tmpV3, array, offset + i)
}
}
......
......@@ -51,6 +51,7 @@ function createPoints() {
return createPointRenderObject({
objectId: 0,
alpha: 1.0,
visible: true,
position,
id,
......
......@@ -8,6 +8,16 @@ import PointRenderable from './renderable/point'
import MeshRenderable from './renderable/mesh'
import { Program } from './webgl/program';
export type BaseProps = {
objectId: number
alpha: number
visible: boolean
flatShaded?: boolean
doubleSided?: boolean
flipSided?: boolean
}
export interface Renderable<T> {
draw: () => void
name: string
......
......@@ -7,7 +7,7 @@
import { ValueCell } from 'mol-util/value-cell'
import { ColorData } from 'mol-geo/util/color-data';
import { Renderable } from '../renderable'
import { Renderable, BaseProps } from '../renderable'
import { getBaseDefs, getBaseValues, getBaseDefines } from './util'
import { MeshShaderCode, addShaderDefines } from '../shader-code'
import { Context } from '../webgl/context';
......@@ -17,9 +17,6 @@ type Mesh = 'mesh'
namespace Mesh {
export type Props = {
objectId: number
alpha: number
position: ValueCell<Float32Array>
normal: ValueCell<Float32Array | undefined>
id: ValueCell<Float32Array>
......@@ -32,11 +29,7 @@ namespace Mesh {
instanceCount: number
elementCount: number
positionCount: number
flatShaded?: boolean
doubleSided?: boolean
flipSided?: boolean
}
} & BaseProps
export function create(ctx: Context, props: Props): Renderable<Props> {
const defines = getBaseDefines(props)
......
......@@ -6,7 +6,7 @@
import { ValueCell } from 'mol-util/value-cell'
import { Renderable } from '../renderable'
import { Renderable, BaseProps } from '../renderable'
import { getBaseValues, getBaseDefs, getBaseDefines } from './util'
import { PointShaderCode, addShaderDefines } from '../shader-code'
import { ColorData } from 'mol-geo/util/color-data';
......@@ -18,9 +18,6 @@ type Point = 'point'
namespace Point {
export type Props = {
objectId: number
alpha: number
position: ValueCell<Float32Array>
id: ValueCell<Float32Array>
......@@ -33,7 +30,7 @@ namespace Point {
positionCount: number,
usePointSizeAttenuation?: boolean
}
} & BaseProps
export function create<T = Props>(ctx: Context, props: Props): Renderable<Props> {
const defines = getBaseDefines(props)
......
......@@ -69,8 +69,22 @@ namespace Renderer {
let currentProgramId = -1
const drawObject = (r: Renderable<any>, o: RenderObject) => {
if (o.visible) {
if (o.props.visible) {
if (currentProgramId !== r.program.id) {
if (o.props.doubleSided) {
gl.disable(gl.CULL_FACE)
} else {
gl.enable(gl.CULL_FACE)
}
if (o.props.flipSided) {
gl.frontFace(gl.CW)
gl.cullFace(gl.FRONT)
} else {
gl.frontFace(gl.CCW)
gl.cullFace(gl.BACK)
}
r.program.use()
r.program.setUniforms({
model,
......
......@@ -16,16 +16,16 @@ function getNextId() {
export type RenderData = { [k: string]: ValueCell<Helpers.TypedArray> }
export interface BaseRenderObject { id: number, type: string, props: {}, visible: boolean, transparent: boolean }
export interface BaseRenderObject { id: number, type: string, props: {} }
export interface MeshRenderObject extends BaseRenderObject { type: 'mesh', props: MeshRenderable.Props }
export interface PointRenderObject extends BaseRenderObject { type: 'point', props: PointRenderable.Props }
export type RenderObject = MeshRenderObject | PointRenderObject
export function createMeshRenderObject(props: MeshRenderable.Props): MeshRenderObject {
return { id: getNextId(), type: 'mesh', props, visible: true, transparent: props.alpha < 1 }
return { id: getNextId(), type: 'mesh', props }
}
export function createPointRenderObject(props: PointRenderable.Props): PointRenderObject {
return { id: getNextId(), type: 'point', props, visible: true, transparent: props.alpha < 1 }
return { id: getNextId(), type: 'point', props }
}
export function createRenderable(ctx: Context, o: RenderObject) {
......@@ -73,12 +73,12 @@ namespace Scene {
},
eachOpaque: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
renderableMap.forEach((r, o) => {
if (!o.transparent) callbackFn(r, o)
if (o.props.alpha === 1) callbackFn(r, o)
})
},
eachTransparent: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
renderableMap.forEach((r, o) => {
if (o.transparent) callbackFn(r, o)
if (o.props.alpha < 1) callbackFn(r, o)
})
},
get count() {
......
......@@ -48,10 +48,7 @@ void main() {
#ifdef FLAT_SHADED
vec3 fdx = dFdx(vViewPosition);
vec3 fdy = dFdy(vViewPosition);
vec3 N = normalize(cross(fdx, fdy));
#ifdef FLIP_SIDED
N = -N;
#endif
vec3 N = -normalize(cross(fdx, fdy));
#else
vec3 N = -normalize(vNormal);
#ifdef DOUBLE_SIDED
......
......@@ -39,8 +39,8 @@ void main(){
#ifndef FLAT_SHADED
mat3 normalMatrix = transpose(inverse(mat3(modelView)));
vec3 transformedNormal = normalize(normalMatrix * normal);
#ifdef FLIP_SIDED
vec3 transformedNormal = normalize(normalMatrix * normalize(normal));
#if defined(FLIP_SIDED) && !defined(DOUBLE_SIDED) // TODO checking DOUBLE_SIDED should not be required, ASR
transformedNormal = -transformedNormal;
#endif
vNormal = transformedNormal;
......
......@@ -179,6 +179,19 @@ namespace Mat3 {
out[8] = (a11 * a00 - a01 * a10) * det;
return out;
}
export function determinant(a: Mat3) {
const a00 = a[0], a01 = a[1], a02 = a[2];
const a10 = a[3], a11 = a[4], a12 = a[5];
const a20 = a[6], a21 = a[7], a22 = a[8];
const b01 = a22 * a11 - a12 * a21;
const b11 = -a22 * a10 + a12 * a20;
const b21 = a21 * a10 - a11 * a20;
// Calculate the determinant
return a00 * b01 + a01 * b11 + a02 * b21;
}
}
export default Mat3
\ No newline at end of file
......@@ -62,6 +62,20 @@ namespace Vec4 {
return a
}
export function toVec3Array(a: Vec4, out: Helpers.NumberArray, offset: number) {
out[offset + 0] = a[0];
out[offset + 1] = a[1];
out[offset + 2] = a[2];
}
export function fromVec3Array(a: Vec4, array: Helpers.NumberArray, offset: number) {
a[0] = array[offset + 0]
a[1] = array[offset + 1]
a[2] = array[offset + 2]
a[3] = 0
return a
}
export function copy(out: Vec4, a: Vec4) {
out[0] = a[0];
out[1] = a[1];
......
......@@ -106,11 +106,11 @@ namespace Viewer {
return {
hide: (repr: Representation<any>) => {
const renderObjectSet = reprMap.get(repr)
if (renderObjectSet) renderObjectSet.forEach(o => o.visible = false)
if (renderObjectSet) renderObjectSet.forEach(o => o.props.visible = false)
},
show: (repr: Representation<any>) => {
const renderObjectSet = reprMap.get(repr)
if (renderObjectSet) renderObjectSet.forEach(o => o.visible = true)
if (renderObjectSet) renderObjectSet.forEach(o => o.props.visible = true)
},
add: (repr: Representation<any>) => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment