diff --git a/src/mol-canvas3d/camera/base.ts b/src/mol-canvas3d/camera/base.ts index 891a8ec69ec11a0120dae82cb5e2d0fe250bc953..27c26287bd9386fa6bd16c5338ce7d81c4aebad1 100644 --- a/src/mol-canvas3d/camera/base.ts +++ b/src/mol-canvas3d/camera/base.ts @@ -6,7 +6,7 @@ import { Mat4, Vec3, Vec4 } from 'mol-math/linear-algebra' import { cameraProject, cameraUnproject, cameraLookAt, Viewport } from './util'; -import { Object3D, createObject3D } from 'mol-gl/object3d'; +import { Object3D } from 'mol-gl/object3d'; export interface Camera extends Object3D { readonly projection: Mat4, @@ -18,12 +18,6 @@ export interface Camera extends Object3D { far: number, fogNear: number, fogFar: number, - - translate: (v: Vec3) => void, - reset: () => void, - lookAt: (target: Vec3) => void, - project: (out: Vec4, point: Vec3) => Vec4, - unproject: (out: Vec3, point: Vec3) => Vec3 } export const DefaultCameraProps = { @@ -31,18 +25,19 @@ export const DefaultCameraProps = { direction: Vec3.create(0, 0, -1), up: Vec3.create(0, 1, 0), viewport: Viewport.create(-1, -1, 1, 1), + near: 0.1, far: 10000, fogNear: 0.1, fogFar: 10000, } -export type CameraProps = Partial<typeof DefaultCameraProps> +export type CameraProps = typeof DefaultCameraProps export namespace Camera { - export function create(props?: CameraProps): Camera { + export function create(props?: Partial<CameraProps>): Camera { const p = { ...DefaultCameraProps, ...props }; - const { view, position, direction, up } = createObject3D() + const { view, position, direction, up } = Object3D.create() Vec3.copy(position, p.position) Vec3.copy(direction, p.direction) Vec3.copy(up, p.up) @@ -52,63 +47,53 @@ export namespace Camera { const projectionView = Mat4.identity() const inverseProjectionView = Mat4.identity() - function update () { - Mat4.mul(projectionView, projection, view) - Mat4.invert(inverseProjectionView, projectionView) - } - - function lookAt (target: Vec3) { - cameraLookAt(direction, up, position, target) - } - - function reset () { - Vec3.copy(position, p.position) - Vec3.copy(direction, p.direction) - Vec3.copy(up, p.up) - Mat4.setIdentity(view) - Mat4.setIdentity(projection) - Mat4.setIdentity(projectionView) - Mat4.setIdentity(inverseProjectionView) - } - - function translate (v: Vec3) { - Vec3.add(position, position, v) - } - - function project (out: Vec4, point: Vec3) { - return cameraProject(out, point, viewport, projectionView) - } - - function unproject (out: Vec3, point: Vec3) { - return cameraUnproject(out, point, viewport, inverseProjectionView) - } - return { - view, projection, projectionView, inverseProjectionView, - viewport, + + view, position, direction, up, - get near() { return p.near }, - set near(value: number) { p.near = value }, - get far() { return p.far }, - set far(value: number) { p.far = value }, - get fogNear() { return p.fogNear }, - set fogNear(value: number) { p.fogNear = value }, - get fogFar() { return p.fogFar }, - set fogFar(value: number) { p.fogFar = value }, - - translate, - reset, - lookAt, - update, - project, - unproject + near: p.near, + far: p.far, + fogNear: p.fogNear, + fogFar: p.fogFar, } } + + export function update (camera: Camera) { + Mat4.mul(camera.projectionView, camera.projection, camera.view) + Mat4.invert(camera.inverseProjectionView, camera.projectionView) + return camera + } + + export function lookAt (camera: Camera, target: Vec3) { + cameraLookAt(camera.direction, camera.up, camera.position, target) + } + + export function reset (camera: Camera, props: CameraProps) { + Vec3.copy(camera.position, props.position) + Vec3.copy(camera.direction, props.direction) + Vec3.copy(camera.up, props.up) + Mat4.setIdentity(camera.view) + Mat4.setIdentity(camera.projection) + Mat4.setIdentity(camera.projectionView) + Mat4.setIdentity(camera.inverseProjectionView) + } + + export function translate (camera: Camera, v: Vec3) { + Vec3.add(camera.position, camera.position, v) + } + + export function project (camera: Camera, out: Vec4, point: Vec3) { + return cameraProject(out, point, camera.viewport, camera.projectionView) + } + + export function unproject (camera: Camera, out: Vec3, point: Vec3) { + return cameraUnproject(out, point, camera.viewport, camera.inverseProjectionView) + } } \ No newline at end of file diff --git a/src/mol-canvas3d/camera/perspective.ts b/src/mol-canvas3d/camera/perspective.ts index 1117fa3b1f6e931fc09a12c79bb3b0bd68b64da9..9fb89fe070af6e0c5d4410dc1f9b91adecef98a6 100644 --- a/src/mol-canvas3d/camera/perspective.ts +++ b/src/mol-canvas3d/camera/perspective.ts @@ -9,8 +9,6 @@ import { DefaultCameraProps, Camera } from './base' export interface PerspectiveCamera extends Camera { fov: number, - near: number, - far: number } export const DefaultPerspectiveCameraProps = { @@ -21,33 +19,30 @@ export type PerspectiveCameraProps = Partial<typeof DefaultPerspectiveCameraProp export namespace PerspectiveCamera { export function create(props: PerspectiveCameraProps = {}): PerspectiveCamera { - let { fov, near, far } = { ...DefaultPerspectiveCameraProps, ...props }; + let { fov } = { ...DefaultPerspectiveCameraProps, ...props }; - const camera = Camera.create(props) - const center = Vec3.zero() + const camera = { + ...Camera.create(props), + fov + } - function update () { - const aspect = camera.viewport.width / camera.viewport.height + update(camera) - // build projection matrix - Mat4.perspective(camera.projection, fov, aspect, Math.abs(near), Math.abs(far)) + return camera + } - // build view matrix - Vec3.add(center, camera.position, camera.direction) - Mat4.lookAt(camera.view, camera.position, center, camera.up) + const center = Vec3.zero() + export function update(camera: PerspectiveCamera) { + const aspect = camera.viewport.width / camera.viewport.height - // update projection * view and invert - camera.update() - } + // build projection matrix + Mat4.perspective(camera.projection, camera.fov, aspect, Math.abs(camera.near), Math.abs(camera.far)) - update() + // build view matrix + Vec3.add(center, camera.position, camera.direction) + Mat4.lookAt(camera.view, camera.position, center, camera.up) - return { - ...camera, - update, - - get fov() { return fov }, - set fov(value: number) { fov = value }, - } + // update projection * view and invert + Camera.update(camera) } } \ No newline at end of file diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index 692d71d248c0244b27450223825d95532c95f78b..14159075f12767e39bb3a2fe2428a74e8b6df9aa 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -132,13 +132,13 @@ namespace Canvas3D { } } - let nearPlaneDelta = 0 - function computeNearDistance() { - const focusRadius = scene.boundingSphere.radius - let dist = Vec3.distance(controls.target, camera.position) - if (dist > focusRadius) return dist - focusRadius - return 0 - } + // let nearPlaneDelta = 0 + // function computeNearDistance() { + // const focusRadius = scene.boundingSphere.radius + // let dist = Vec3.distance(controls.target, camera.position) + // if (dist > focusRadius) return dist - focusRadius + // return 0 + // } function render(variant: RenderVariant, force?: boolean) { if (isPicking) return false @@ -146,18 +146,19 @@ namespace Canvas3D { // console.log(p[0], p[1], p[2]) // Vec3.set(controls.target, p[0], p[1], p[2]) - const focusRadius = scene.boundingSphere.radius - const targetDistance = Vec3.distance(controls.target, camera.position) + // TODO update near/far + // const focusRadius = scene.boundingSphere.radius + // const targetDistance = Vec3.distance(controls.target, camera.position) // console.log(targetDistance, controls.target, camera.position) - let near = computeNearDistance() + nearPlaneDelta - camera.near = Math.max(0.01, Math.min(near, targetDistance - 0.5)) + // let near = computeNearDistance() + nearPlaneDelta + // camera.near = Math.max(0.01, Math.min(near, targetDistance - 0.5)) - let fogNear = targetDistance - camera.near + 1 * focusRadius - nearPlaneDelta; - let fogFar = targetDistance - camera.near + 2 * focusRadius - nearPlaneDelta; + // let fogNear = targetDistance - camera.near + 1 * focusRadius - nearPlaneDelta; + // let fogFar = targetDistance - camera.near + 2 * focusRadius - nearPlaneDelta; - // console.log(fogNear, fogFar); - camera.fogNear = Math.max(fogNear, 0.1); - camera.fogFar = Math.max(fogFar, 0.2); + // // console.log(fogNear, fogFar); + // camera.fogNear = Math.max(fogNear, 0.1); + // camera.fogFar = Math.max(fogFar, 0.2); // console.log(camera.fogNear, camera.fogFar, targetDistance) @@ -172,7 +173,7 @@ namespace Canvas3D { } let didRender = false controls.update() - camera.update() + PerspectiveCamera.update(camera) if (force || !Mat4.areEqual(camera.projectionView, prevProjectionView, EPSILON.Value) || !Mat4.areEqual(scene.view, prevSceneView, EPSILON.Value)) { // console.log('foo', force, prevSceneView, scene.view) Mat4.copy(prevProjectionView, camera.projectionView) diff --git a/src/mol-gl/object3d.ts b/src/mol-gl/object3d.ts index d8e4a93ec8e8c8c2fbceb51723391ef0a48a079d..45887fec47c16577a9a97dfbfb55a9dbddb2f5f5 100644 --- a/src/mol-gl/object3d.ts +++ b/src/mol-gl/object3d.ts @@ -7,36 +7,25 @@ import { Vec3, Mat4 } from 'mol-math/linear-algebra'; export interface Object3D { - readonly view: Mat4, - readonly position: Vec3, - readonly direction: Vec3, - readonly up: Vec3, - - update: () => void + readonly view: Mat4 + readonly position: Vec3 + readonly direction: Vec3 + readonly up: Vec3 } -export function createObject3D(): Object3D { - const view = Mat4.identity() - const position = Vec3.create(0, 0, 0) - const direction = Vec3.create(0, 0, -1) - const up = Vec3.create(0, 1, 0) +export namespace Object3D { + export function create(): Object3D { + return { + view: Mat4.identity(), + position: Vec3.create(0, 0, 0), + direction: Vec3.create(0, 0, -1), + up: Vec3.create(0, 1, 0), + } + } const center = Vec3.zero() - - return { - view, - position, - direction, - up, - - update() { - // console.log('position', position) - // console.log('direction', direction) - // console.log('up', up) - Vec3.add(center, position, direction) - Mat4.lookAt(view, position, center, up) - // Mat4.lookAt(view, center, position, up) - // console.log('view', view) - } + export function update(object3d: Object3D) { + Vec3.add(center, object3d.position, object3d.direction) + Mat4.lookAt(object3d.view, object3d.position, center, object3d.up) } } \ No newline at end of file diff --git a/src/mol-gl/scene.ts b/src/mol-gl/scene.ts index 217f082cdc9552682057fee189adc1f52adbce03..8b995572d9fa6491a0b6eebf68d661f006a36399 100644 --- a/src/mol-gl/scene.ts +++ b/src/mol-gl/scene.ts @@ -8,7 +8,7 @@ import { Renderable } from './renderable' import { WebGLContext } from './webgl/context'; import { RenderableValues, BaseValues } from './renderable/schema'; import { RenderObject, createRenderable } from './render-object'; -import { Object3D, createObject3D } from './object3d'; +import { Object3D } from './object3d'; import { Sphere3D } from 'mol-math/geometry'; import { Vec3 } from 'mol-math/linear-algebra'; @@ -39,6 +39,7 @@ interface Scene extends Object3D { readonly count: number readonly boundingSphere: Sphere3D + update: () => void add: (o: RenderObject) => void remove: (o: RenderObject) => void clear: () => void @@ -52,14 +53,13 @@ namespace Scene { const renderableMap = new Map<RenderObject, Renderable<RenderableValues & BaseValues>>() let boundingSphere: Sphere3D | undefined - const { view, position, up, direction, update } = createObject3D() + const object3d = Object3D.create() return { - // ...createObject3D(), // TODO does not work in conjunction with getter - view, position, up, direction, + ...object3d, update: () => { - update() + Object3D.update(object3d) renderableMap.forEach(r => r.update()) boundingSphere = undefined },