diff --git a/package-lock.json b/package-lock.json index 68fb17365403b32de0fe116d3096507f569d8d48..7096688c7817e9f74c7e5e0aa2870a7fa7b00616 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index 9e02ef7ae4361e444b771ee6c1c5b859bc848763..da05723d224acdbb60d28c43967eba40a4f25fda 100644 --- a/package.json +++ b/package.json @@ -63,29 +63,29 @@ "devDependencies": { "benchmark": "^2.1.4", "circular-dependency-plugin": "^5.0.2", - "concurrently": "^4.1.0", + "concurrently": "^4.1.1", "cpx": "^1.5.0", - "css-loader": "^3.0.0", + "css-loader": "^3.1.0", "extra-watch-webpack-plugin": "^1.0.3", - "file-loader": "^4.0.0", - "fs-extra": "^8.0.1", + "file-loader": "^4.1.0", + "fs-extra": "^8.1.0", "graphql-code-generator": "^0.18.2", "graphql-codegen-time": "^0.18.2", "graphql-codegen-typescript-template": "^0.18.2", "jest": "^24.8.0", "jest-raw-loader": "^1.0.1", - "mini-css-extract-plugin": "^0.7.0", + "mini-css-extract-plugin": "^0.8.0", "node-sass": "^4.12.0", - "raw-loader": "^3.0.0", + "raw-loader": "^3.1.0", "resolve-url-loader": "^3.1.0", "sass-loader": "^7.1.0", - "simple-git": "^1.116.0", + "simple-git": "^1.122.0", "style-loader": "^0.23.1", "ts-jest": "^24.0.2", "tslint": "^5.18.0", - "typescript": "^3.5.2", - "webpack": "^4.35.0", - "webpack-cli": "^3.3.4" + "typescript": "^3.5.3", + "webpack": "^4.36.1", + "webpack-cli": "^3.3.6" }, "dependencies": { "@types/argparse": "^1.0.36", @@ -93,22 +93,22 @@ "@types/compression": "0.0.36", "@types/express": "^4.17.0", "@types/jest": "^24.0.15", - "@types/node": "^12.0.10", + "@types/node": "^12.6.8", "@types/node-fetch": "^2.3.7", - "@types/react": "^16.8.22", + "@types/react": "^16.8.23", "@types/react-dom": "^16.8.4", "@types/swagger-ui-dist": "3.0.0", - "@types/webgl2": "0.0.4", + "@types/webgl2": "0.0.5", "argparse": "^1.0.10", "compression": "^1.7.4", "express": "^4.17.1", - "graphql": "^14.3.1", + "graphql": "^14.4.2", "immutable": "^3.8.2", "node-fetch": "^2.6.0", "react": "^16.8.6", "react-dom": "^16.8.6", "rxjs": "^6.5.2", - "swagger-ui-dist": "^3.22.3", + "swagger-ui-dist": "^3.23.1", "util.promisify": "^1.0.0", "xhr2": "^0.2.0" } diff --git a/src/examples/proteopedia-wrapper/changelog.md b/src/examples/proteopedia-wrapper/changelog.md index b9d8bd109b9c5e063795fe46f0cc3d03297e06aa..e8e8cb5a36a6716a6b0c00b497000109ceac6e5b 100644 --- a/src/examples/proteopedia-wrapper/changelog.md +++ b/src/examples/proteopedia-wrapper/changelog.md @@ -1,3 +1,7 @@ +== v3.3 == + +* Camera Clipping. + == v3.2 == * Fixed assembly loading. diff --git a/src/examples/proteopedia-wrapper/index.html b/src/examples/proteopedia-wrapper/index.html index 632496100c0c3df2f7d6238dbfbd8f84da98f45f..b7383173937cd7c1f8c700611fa7a875c7c52031 100644 --- a/src/examples/proteopedia-wrapper/index.html +++ b/src/examples/proteopedia-wrapper/index.html @@ -130,7 +130,11 @@ addSeparator(); addHeader('Camera'); - addControl('Toggle Spin', () => PluginWrapper.toggleSpin()); + addControl('Reset Position', () => PluginWrapper.camera.resetPosition()); + addControl('Toggle Spin', () => PluginWrapper.camera.toggleSpin()); + // Same as "wheel icon" and Viewport options + addControl('Clip', () => PluginWrapper.viewport.setSettings({ clip: [33, 66] })); + addControl('Reset Clip', () => PluginWrapper.viewport.setSettings({ clip: [1, 100] })); addSeparator(); diff --git a/src/examples/proteopedia-wrapper/index.ts b/src/examples/proteopedia-wrapper/index.ts index 750503e5ecad5a08eaed151f6e5ec3b963c7b1c7..1aa4f7c2a3bb521618a28da4e80d80c592546267 100644 --- a/src/examples/proteopedia-wrapper/index.ts +++ b/src/examples/proteopedia-wrapper/index.ts @@ -29,6 +29,7 @@ import { BuiltInSizeThemes } from '../../mol-theme/size'; import { ColorNames } from '../../mol-util/color/tables'; import { InitVolumeStreaming, CreateVolumeStreamingInfo } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers'; import { ParamDefinition } from '../../mol-util/param-definition'; +import { DefaultCanvas3DParams, Canvas3DProps } from '../../mol-canvas3d/canvas3d'; // import { Vec3 } from 'mol-math/linear-algebra'; // import { ParamDefinition } from 'mol-util/param-definition'; // import { Text } from 'mol-geo/geometry/text/text'; @@ -36,7 +37,7 @@ require('../../mol-plugin/skin/light.scss') class MolStarProteopediaWrapper { static VERSION_MAJOR = 3; - static VERSION_MINOR = 2; + static VERSION_MINOR = 3; private _ev = RxEventHelper.create(); @@ -241,6 +242,38 @@ class MolStarProteopediaWrapper { if (!spinning) PluginCommands.Camera.Reset.dispatch(this.plugin, { }); } + viewport = { + setSettings: (settings?: Canvas3DProps) => { + PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { + settings: settings || DefaultCanvas3DParams + }); + } + }; + + camera = { + toggleSpin: () => this.toggleSpin(), + resetPosition: () => PluginCommands.Camera.Reset.dispatch(this.plugin, { }), + // setClip: (options?: { distance?: number, near?: number, far?: number }) => { + // if (!options) { + // PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { + // settings: { + // cameraClipDistance: DefaultCanvas3DParams.cameraClipDistance, + // clip: DefaultCanvas3DParams.clip + // } + // }); + // return; + // } + + // options = options || { }; + // const props = this.plugin.canvas3d.props; + // const clipNear = typeof options.near === 'undefined' ? props.clip[0] : options.near; + // const clipFar = typeof options.far === 'undefined' ? props.clip[1] : options.far; + // PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { + // settings: { cameraClipDistance: options.distance, clip: [clipNear, clipFar] } + // }); + // } + } + animate = { modelIndex: { maxFPS: 8, diff --git a/src/mol-canvas3d/camera.ts b/src/mol-canvas3d/camera.ts index 64fc8773c80d89cedfff633a3d20a75571ea83a3..43b390255697572aa8cc33efb32a9ddb2c39a195 100644 --- a/src/mol-canvas3d/camera.ts +++ b/src/mol-canvas3d/camera.ts @@ -90,25 +90,30 @@ class Camera implements Object3D { return ret; } - getFocus(target: Vec3, radius: number): Partial<Camera.Snapshot> { + getFocus(target: Vec3, radius: number, dir?: Vec3): Partial<Camera.Snapshot> { const fov = this.state.fov const { width, height } = this.viewport const aspect = width / height const aspectFactor = (height < width ? 1 : aspect) const currentDistance = Vec3.distance(this.state.position, target) const targetDistance = Math.abs((radius / aspectFactor) / Math.sin(fov / 2)) + const deltaDistance = Math.abs(currentDistance - targetDistance) - Vec3.sub(this.deltaDirection, this.state.position, target) - Vec3.setMagnitude(this.deltaDirection, this.state.direction, deltaDistance) - if (currentDistance < targetDistance) Vec3.negate(this.deltaDirection, this.deltaDirection) - Vec3.add(this.newPosition, this.state.position, this.deltaDirection) + if (dir) { + Vec3.setMagnitude(this.deltaDirection, dir, targetDistance) + Vec3.add(this.newPosition, target, this.deltaDirection) + } else { + Vec3.setMagnitude(this.deltaDirection, this.state.direction, deltaDistance) + if (currentDistance < targetDistance) Vec3.negate(this.deltaDirection, this.deltaDirection) + Vec3.add(this.newPosition, this.state.position, this.deltaDirection) + } return { target, position: Vec3.clone(this.newPosition) }; } - focus(target: Vec3, radius: number) { - if (radius > 0) this.setState(this.getFocus(target, radius)); + focus(target: Vec3, radius: number, dir?: Vec3) { + if (radius > 0) this.setState(this.getFocus(target, radius, dir)); } // lookAt(target: Vec3) { diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index 8805de61b50af90bcc8c3819392338ab7e59e997..3ac440ca0d2214305cf0578fe580c3aa20c63059 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -47,6 +47,7 @@ export const Canvas3DParams = { trackball: PD.Group(TrackballControlsParams), debug: PD.Group(DebugHelperParams) } +export const DefaultCanvas3DParams = PD.getDefaultValues(Canvas3DParams); export type Canvas3DProps = PD.Values<typeof Canvas3DParams> export { Canvas3D } @@ -106,7 +107,7 @@ namespace Canvas3D { } export function create(gl: GLRenderingContext, input: InputObserver, props: Partial<Canvas3DProps> = {}, runTask = DefaultRunTask): Canvas3D { - const p = { ...PD.getDefaultValues(Canvas3DParams), ...props } + const p = { ...DefaultCanvas3DParams, ...props } const reprRenderObjects = new Map<Representation.Any, Set<GraphicsRenderObject>>() const reprUpdatedSubscriptions = new Map<Representation.Any, Subscription>() @@ -351,11 +352,12 @@ namespace Canvas3D { getLoci, handleResize, - resetCamera: () => { + resetCamera: (dir?: Vec3) => { if (scene.isCommiting) { + // TODO handle `dir` cameraResetRequested = true } else { - camera.focus(scene.boundingSphere.center, scene.boundingSphere.radius) + camera.focus(scene.boundingSphere.center, scene.boundingSphere.radius, dir) requestDraw(true); } },