From 18ec79cd2b2283b518f847e726c9a5550b0003e0 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alexander.rose@weirdbyte.de> Date: Fri, 8 Jun 2018 18:44:35 +0200 Subject: [PATCH] wip, fog --- src/mol-gl/_spec/renderable.spec.ts | 42 +++++++++++++++ src/mol-gl/_spec/renderer.spec.ts | 2 +- src/mol-gl/object3d.ts | 42 +++++++++++++++ src/mol-gl/renderable.ts | 26 +++++++-- src/mol-gl/renderable/util.ts | 64 ++++++++++++++++++++++ src/mol-gl/renderer.ts | 28 +++++----- src/mol-gl/scene.ts | 56 ++++++++++++++++--- src/mol-gl/shader/chunks/apply-fog.glsl | 4 +- src/mol-view/camera/base.ts | 39 +++++++------- src/mol-view/camera/util.ts | 8 ++- src/mol-view/controls/trackball.ts | 9 +--- src/mol-view/viewer.ts | 71 ++++++++++++++++++------- 12 files changed, 319 insertions(+), 72 deletions(-) create mode 100644 src/mol-gl/_spec/renderable.spec.ts create mode 100644 src/mol-gl/object3d.ts diff --git a/src/mol-gl/_spec/renderable.spec.ts b/src/mol-gl/_spec/renderable.spec.ts new file mode 100644 index 000000000..a0e486863 --- /dev/null +++ b/src/mol-gl/_spec/renderable.spec.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { calculateBoundingSphere } from '../renderable/util'; + +describe('renderable', () => { + it('calculateBoundingSphere', () => { + const position = new Float32Array([ + 0, 0, 0, + 1, 0, 0 + ]) + const transform = new Float32Array([ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 0, + + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 0, 0, 0, + + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 2, 0, 0, 0 + ]) + + const bs = calculateBoundingSphere({ + position, + positionCount: position.length / 3, + transform, + transformCount: transform.length / 16 + }) + + expect(bs.radius).toBe(1.5) + expect(bs.center).toEqual([1.5, 0.0, 0.0]) + }) +}) diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts index a08748287..c922e3219 100644 --- a/src/mol-gl/_spec/renderer.spec.ts +++ b/src/mol-gl/_spec/renderer.spec.ts @@ -97,7 +97,7 @@ describe('renderer', () => { expect(ctx.programCache.count).toBe(0); expect(ctx.shaderCache.count).toBe(0); - renderer.setViewport({ x: 0, y: 0, width: 64, height: 48 }) + renderer.setViewport(0, 0, 64, 48) expect(ctx.gl.getParameter(ctx.gl.VIEWPORT)[2]).toBe(64) expect(ctx.gl.getParameter(ctx.gl.VIEWPORT)[3]).toBe(48) }) diff --git a/src/mol-gl/object3d.ts b/src/mol-gl/object3d.ts new file mode 100644 index 000000000..d8e4a93ec --- /dev/null +++ b/src/mol-gl/object3d.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +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 +} + +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) + + 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) + } + } +} \ No newline at end of file diff --git a/src/mol-gl/renderable.ts b/src/mol-gl/renderable.ts index b3a72be16..1e69c6755 100644 --- a/src/mol-gl/renderable.ts +++ b/src/mol-gl/renderable.ts @@ -5,17 +5,20 @@ */ import { Program } from './webgl/program'; -import { RenderableValues, Values, RenderableSchema } from './renderable/schema'; +import { RenderableValues, Values, RenderableSchema, BaseValues } from './renderable/schema'; import { RenderVariant, RenderItem } from './webgl/render-item'; +import { Sphere3D } from 'mol-math/geometry'; +import { calculateBoundingSphere } from './renderable/util'; export type RenderableState = { visible: boolean depthMask: boolean } -export interface Renderable<T extends RenderableValues> { +export interface Renderable<T extends RenderableValues & BaseValues> { readonly values: T readonly state: RenderableState + readonly boundingSphere: Sphere3D render: (variant: RenderVariant) => void getProgram: (variant: RenderVariant) => Program @@ -23,14 +26,29 @@ export interface Renderable<T extends RenderableValues> { dispose: () => void } -export function createRenderable<T extends Values<RenderableSchema>>(renderItem: RenderItem, values: T, state: RenderableState): Renderable<T> { +export function createRenderable<T extends Values<RenderableSchema> & BaseValues>(renderItem: RenderItem, values: T, state: RenderableState): Renderable<T> { + const position = values.aPosition.ref.value + const transform = values.aTransform.ref.value + const positionCount = values.drawCount.ref.value / 3 / 3 + const transformCount = values.instanceCount.ref.value + + let boundingSphere: Sphere3D | undefined + return { get values () { return values }, get state () { return state }, + get boundingSphere () { + if (boundingSphere) return boundingSphere + boundingSphere = calculateBoundingSphere({ position, positionCount, transform, transformCount }) + return boundingSphere + }, render: (variant: RenderVariant) => renderItem.render(variant), getProgram: (variant: RenderVariant) => renderItem.getProgram(variant), - update: () => renderItem.update(), + update: () => { + renderItem.update() + boundingSphere = undefined + }, dispose: () => renderItem.destroy() } } diff --git a/src/mol-gl/renderable/util.ts b/src/mol-gl/renderable/util.ts index 3c6048dd8..650831214 100644 --- a/src/mol-gl/renderable/util.ts +++ b/src/mol-gl/renderable/util.ts @@ -4,6 +4,9 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ +import { Sphere3D } from 'mol-math/geometry' +import { Mat4, Vec3 } from 'mol-math/linear-algebra' + export function calculateTextureInfo (n: number, itemSize: number) { const sqN = Math.sqrt(n * itemSize) let width = Math.ceil(sqN) @@ -27,4 +30,65 @@ export function fillSerial<T extends Helpers.NumberArray> (array: T) { const n = array.length for (let i = 0; i < n; ++i) array[ i ] = i return array +} + +export interface PositionData { + position: Float32Array + positionCount: number, + transform: Float32Array, + transformCount: number, +} + +export function calculateBoundingSphere(data: PositionData): Sphere3D { + const { position, positionCount, transform, transformCount } = data + + const m = Mat4.zero() + + let cx = 0, cy = 0, cz = 0; + let radiusSq = 0; + + for (let i = 0, _i = positionCount * 3; i < _i; i += 3) { + cx += position[i]; + cy += position[i + 1]; + cz += position[i + 2]; + } + + if (positionCount > 0) { + cx /= positionCount; + cy /= positionCount; + cz /= positionCount; + } + + for (let i = 0, _i = positionCount * 3; i < _i; i += 3) { + const dx = position[i] - cx + const dy = position[i + 1] - cy + const dz = position[i + 2] - cz; + const d = dx * dx + dy * dy + dz * dz; + if (d > radiusSq) radiusSq = d; + } + + const c = Vec3.create(cx, cy, cz) + const ct = Vec3.zero() + + const center = Vec3.zero() + const centers = new Float32Array(3 * transformCount) + + for (let i = 0, _i = transformCount; i < _i; ++i) { + Mat4.fromArray(m, transform, i * 16) + Vec3.transformMat4(ct, c, m) + Vec3.add(center, center, ct) + Vec3.toArray(ct, centers, i * 3) + } + + Vec3.scale(center, center, 1 / transformCount) + + let r = Math.sqrt(radiusSq) + let radius = r + + for (let i = 0, _i = transformCount; i < _i; ++i) { + Vec3.fromArray(ct, centers, i * 3) + radius = Math.max(radius, Vec3.distance(center, ct) + r) + } + + return { center, radius }; } \ No newline at end of file diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 885ae9f82..cbc4ffffa 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -14,7 +14,7 @@ import { Mat4, Vec3 } from 'mol-math/linear-algebra'; import { Renderable } from './renderable'; import { Color } from 'mol-util/color'; import { ValueCell } from 'mol-util'; -import { RenderableValues, GlobalUniformValues } from './renderable/schema'; +import { RenderableValues, GlobalUniformValues, BaseValues } from './renderable/schema'; import { RenderVariant } from './webgl/render-item'; export interface RendererStats { @@ -29,13 +29,12 @@ export interface RendererStats { } interface Renderer { - render: (scene: Scene, variant: RenderVariant) => void + readonly stats: RendererStats - setViewport: (viewport: Viewport) => void + render: (scene: Scene, variant: RenderVariant) => void + setViewport: (x: number, y: number, width: number, height: number) => void setClearColor: (color: Color) => void getImageData: () => ImageData - - stats: RendererStats dispose: () => void } @@ -50,7 +49,6 @@ namespace Renderer { const { gl } = ctx let { clearColor, viewport: _viewport } = { ...DefaultRendererProps, ...props } - const model = Mat4.identity() const viewport = Viewport.clone(_viewport) // const lightPosition = Vec3.create(0, 0, -100) @@ -67,7 +65,7 @@ namespace Renderer { setClearColor(clearColor) const globalUniforms: GlobalUniformValues = { - uModel: ValueCell.create(Mat4.clone(model)), + uModel: ValueCell.create(Mat4.identity()), uView: ValueCell.create(Mat4.clone(camera.view)), uProjection: ValueCell.create(Mat4.clone(camera.projection)), @@ -86,7 +84,7 @@ namespace Renderer { } let currentProgramId = -1 - const renderObject = (r: Renderable<RenderableValues>, variant: RenderVariant) => { + const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: RenderVariant) => { const program = r.getProgram(variant) if (r.state.visible) { if (currentProgramId !== program.id) { @@ -115,10 +113,16 @@ namespace Renderer { } const render = (scene: Scene, variant: RenderVariant) => { + ValueCell.update(globalUniforms.uModel, scene.view) ValueCell.update(globalUniforms.uView, camera.view) ValueCell.update(globalUniforms.uProjection, camera.projection) + ValueCell.update(globalUniforms.uFogFar, camera.fogFar) + ValueCell.update(globalUniforms.uFogNear, camera.fogNear) + currentProgramId = -1 + // scene.unsetBoundingSphere() + // console.log('scene.boundingSphere', scene.boundingSphere) gl.depthMask(true) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) @@ -138,10 +142,10 @@ namespace Renderer { render, setClearColor, - setViewport: (newViewport: Viewport) => { - Viewport.copy(viewport, newViewport) - gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height) - ValueCell.update(globalUniforms.uViewportHeight, viewport.height) + setViewport: (x: number, y: number, width: number, height: number) => { + Viewport.set(viewport, x, y, width, height) + gl.viewport(x, y, width, height) + ValueCell.update(globalUniforms.uViewportHeight, height) }, getImageData: () => { const { width, height } = viewport diff --git a/src/mol-gl/scene.ts b/src/mol-gl/scene.ts index 52f098944..0cd225b7b 100644 --- a/src/mol-gl/scene.ts +++ b/src/mol-gl/scene.ts @@ -6,29 +6,63 @@ import { Renderable } from './renderable' import { Context } from './webgl/context'; -import { RenderableValues } from './renderable/schema'; +import { RenderableValues, BaseValues } from './renderable/schema'; import { RenderObject, createRenderable } from './render-object'; +import { Object3D, createObject3D } from './object3d'; +import { Sphere3D } from 'mol-math/geometry'; +import { Vec3 } from 'mol-math/linear-algebra'; +function calculateBoundingSphere(renderableMap: Map<RenderObject, Renderable<RenderableValues & BaseValues>>): Sphere3D { + let count = 0 + const center = Vec3.zero() + renderableMap.forEach((r, o) => { + if (r.boundingSphere.radius) { + Vec3.add(center, center, r.boundingSphere.center) + ++count + } + }) + if (count > 0) { + Vec3.scale(center, center, 1 / count) + } + + let radius = 0 + renderableMap.forEach((r, o) => { + if (r.boundingSphere.radius) { + radius = Math.max(radius, Vec3.distance(center, r.boundingSphere.center) + r.boundingSphere.radius) + } + }) + + return { center, radius }; +} + +interface Scene extends Object3D { + readonly count: number + readonly boundingSphere: Sphere3D -interface Scene { add: (o: RenderObject) => void remove: (o: RenderObject) => void - update: () => void clear: () => void forEach: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void eachOpaque: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void eachTransparent: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void - count: number + unsetBoundingSphere: () => void } namespace Scene { export function create(ctx: Context): Scene { - const renderableMap = new Map<RenderObject, Renderable<RenderableValues>>() + const renderableMap = new Map<RenderObject, Renderable<RenderableValues & BaseValues>>() + let boundingSphere: Sphere3D | undefined + + const { view, position, up, direction, update } = createObject3D() return { + // ...createObject3D(), // TODO does not work in conjunction with getter + view, position, up, direction, update, + add: (o: RenderObject) => { if (!renderableMap.has(o)) { renderableMap.set(o, createRenderable(ctx, o)) + boundingSphere = undefined } else { console.warn(`RenderObject with id '${o.id}' already present`) } @@ -38,14 +72,13 @@ namespace Scene { if (renderable) { renderable.dispose() renderableMap.delete(o) + boundingSphere = undefined } }, - update: () => { - renderableMap.forEach((r, o) => r.update()) - }, clear: () => { renderableMap.forEach(renderable => renderable.dispose()) renderableMap.clear() + boundingSphere = undefined }, forEach: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => { renderableMap.forEach(callbackFn) @@ -60,8 +93,15 @@ namespace Scene { if (o.values.uAlpha.ref.value < 1) callbackFn(r, o) }) }, + unsetBoundingSphere: () => boundingSphere = undefined, get count() { return renderableMap.size + }, + get boundingSphere() { + if (boundingSphere) return boundingSphere + // TODO avoid array creation + boundingSphere = calculateBoundingSphere(renderableMap) + return boundingSphere } } } diff --git a/src/mol-gl/shader/chunks/apply-fog.glsl b/src/mol-gl/shader/chunks/apply-fog.glsl index 3b8896f5c..9e176cbaa 100644 --- a/src/mol-gl/shader/chunks/apply-fog.glsl +++ b/src/mol-gl/shader/chunks/apply-fog.glsl @@ -1,6 +1,6 @@ // #ifdef dUseFog - // float depth = length(vViewPosition); - float depth = gl_FragCoord.z / gl_FragCoord.w; + float depth = length(vViewPosition); + // float depth = gl_FragCoord.z / gl_FragCoord.w; float fogFactor = smoothstep(uFogNear, uFogFar, depth); gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor); // #endif \ No newline at end of file diff --git a/src/mol-view/camera/base.ts b/src/mol-view/camera/base.ts index f97a19563..891a8ec69 100644 --- a/src/mol-view/camera/base.ts +++ b/src/mol-view/camera/base.ts @@ -6,25 +6,22 @@ import { Mat4, Vec3, Vec4 } from 'mol-math/linear-algebra' import { cameraProject, cameraUnproject, cameraLookAt, Viewport } from './util'; +import { Object3D, createObject3D } from 'mol-gl/object3d'; -export interface Camera { - view: Mat4, - projection: Mat4, - projectionView: Mat4, - inverseProjectionView: Mat4, - - viewport: Viewport, - position: Vec3, - direction: Vec3, - up: Vec3, +export interface Camera extends Object3D { + readonly projection: Mat4, + readonly projectionView: Mat4, + readonly inverseProjectionView: Mat4, + readonly viewport: Viewport, near: number, far: number, + fogNear: number, + fogFar: number, translate: (v: Vec3) => void, reset: () => void, lookAt: (target: Vec3) => void, - update: () => void, project: (out: Vec4, point: Vec3) => Vec4, unproject: (out: Vec3, point: Vec3) => Vec3 } @@ -36,6 +33,8 @@ export const DefaultCameraProps = { viewport: Viewport.create(-1, -1, 1, 1), near: 0.1, far: 10000, + fogNear: 0.1, + fogFar: 10000, } export type CameraProps = Partial<typeof DefaultCameraProps> @@ -43,11 +42,12 @@ export namespace Camera { export function create(props?: CameraProps): Camera { const p = { ...DefaultCameraProps, ...props }; + const { view, position, direction, up } = createObject3D() + Vec3.copy(position, p.position) + Vec3.copy(direction, p.direction) + Vec3.copy(up, p.up) + const projection = Mat4.identity() - const view = Mat4.identity() - const position = Vec3.clone(p.position) - const direction = Vec3.clone(p.direction) - const up = Vec3.clone(p.up) const viewport = Viewport.clone(p.viewport) const projectionView = Mat4.identity() const inverseProjectionView = Mat4.identity() @@ -94,11 +94,14 @@ export namespace Camera { direction, up, - get far() { return p.far }, - set far(value: number) { p.far = value }, - 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, diff --git a/src/mol-view/camera/util.ts b/src/mol-view/camera/util.ts index a657c6fef..11c77e70d 100644 --- a/src/mol-view/camera/util.ts +++ b/src/mol-view/camera/util.ts @@ -20,10 +20,16 @@ export namespace Viewport { export function clone(viewport: Viewport): Viewport { return { ...viewport } } - export function copy(target: Viewport, source: Viewport): Viewport { return Object.assign(target, source) } + export function set(viewport: Viewport, x: number, y: number, width: number, height: number): Viewport { + viewport.x = x + viewport.y = y + viewport.width = width + viewport.height = height + return viewport + } } const tmpVec3 = Vec3.zero() diff --git a/src/mol-view/controls/trackball.ts b/src/mol-view/controls/trackball.ts index 4f05c8446..554d81f0a 100644 --- a/src/mol-view/controls/trackball.ts +++ b/src/mol-view/controls/trackball.ts @@ -12,6 +12,7 @@ import { Quat, Vec2, Vec3, EPSILON } from 'mol-math/linear-algebra'; import { cameraLookAt, Viewport } from '../camera/util'; import InputObserver, { DragInput, WheelInput, ButtonsFlag, PinchInput } from 'mol-util/input/input-observer'; +import { Object3D } from 'mol-gl/object3d'; export const DefaultTrackballControlsProps = { noScroll: true, @@ -29,12 +30,6 @@ export const DefaultTrackballControlsProps = { } export type TrackballControlsProps = Partial<typeof DefaultTrackballControlsProps> -interface Object { - position: Vec3, - direction: Vec3, - up: Vec3, -} - interface TrackballControls { viewport: Viewport target: Vec3 @@ -50,7 +45,7 @@ interface TrackballControls { } namespace TrackballControls { - export function create (input: InputObserver, object: Object, props: TrackballControlsProps = {}): TrackballControls { + export function create (input: InputObserver, object: Object3D, props: TrackballControlsProps = {}): TrackballControls { const p = { ...DefaultTrackballControlsProps, ...props } const viewport: Viewport = { x: 0, y: 0, width: 0, height: 0 } diff --git a/src/mol-view/viewer.ts b/src/mol-view/viewer.ts index 54163e3a9..e8696d4b1 100644 --- a/src/mol-view/viewer.ts +++ b/src/mol-view/viewer.ts @@ -111,10 +111,7 @@ namespace Viewer { far: 10000, position: Vec3.create(0, 0, 50) }) - - const controls = TrackballControls.create(input, camera, { - - }) + // camera.lookAt(Vec3.create(0, 0, 0)) const gl = getWebGLContext(canvas, { alpha: false, @@ -128,6 +125,8 @@ namespace Viewer { const ctx = createContext(gl) const scene = Scene.create(ctx) + // const controls = TrackballControls.create(input, scene, {}) + const controls = TrackballControls.create(input, camera, {}) const renderer = Renderer.create(ctx, camera) const pickScale = 1 / 4 @@ -140,13 +139,53 @@ namespace Viewer { let pickDirty = true let drawPending = false const prevProjectionView = Mat4.zero() + const prevSceneView = Mat4.zero() + + 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) { + // const p = scene.boundingSphere.center + // 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) + // console.log(targetDistance, controls.target, camera.position) + 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; + + //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) + + switch (variant) { + case 'pickObject': objectPickTarget.bind(); break; + case 'pickInstance': instancePickTarget.bind(); break; + case 'pickElement': elementPickTarget.bind(); break; + case 'draw': + ctx.unbindFramebuffer(); + renderer.setViewport(0, 0, canvas.width, canvas.height); + break; + } let didRender = false controls.update() camera.update() - if (force || !Mat4.areEqual(camera.projectionView, prevProjectionView, EPSILON.Value)) { + scene.update() + 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) + Mat4.copy(prevSceneView, scene.view) renderer.render(scene, variant) if (variant === 'draw') { pickDirty = true @@ -158,9 +197,6 @@ namespace Viewer { } function draw(force?: boolean) { - ctx.unbindFramebuffer() - const viewport = { x: 0, y: 0, width: canvas.width, height: canvas.height } - renderer.setViewport(viewport) if (render('draw', force)) { didDraw.next(performance.now() - startTime) } @@ -179,13 +215,8 @@ namespace Viewer { } function pick() { - objectPickTarget.bind() render('pickObject', pickDirty) - - instancePickTarget.bind() render('pickInstance', pickDirty) - - elementPickTarget.bind() render('pickElement', pickDirty) pickDirty = false @@ -238,7 +269,7 @@ namespace Viewer { if (oldRO) { SetUtils.difference(newRO, oldRO).forEach(o => scene.add(o)) SetUtils.difference(oldRO, newRO).forEach(o => scene.remove(o)) - scene.update() + // scene.update() } else { repr.renderObjects.forEach(o => scene.add(o)) } @@ -253,7 +284,10 @@ namespace Viewer { reprCount.next(reprMap.size) } }, - update: () => scene.update(), + update: () => { + scene.forEach((r, o) => r.update()) + scene.unsetBoundingSphere() + }, clear: () => { reprMap.clear() scene.clear() @@ -300,10 +334,9 @@ namespace Viewer { function handleResize() { resizeCanvas(canvas, container) - const viewport = { x: 0, y: 0, width: canvas.width, height: canvas.height } - renderer.setViewport(viewport) - Viewport.copy(camera.viewport, viewport) - Viewport.copy(controls.viewport, viewport) + renderer.setViewport(0, 0, canvas.width, canvas.height) + Viewport.set(camera.viewport, 0, 0, canvas.width, canvas.height) + Viewport.set(controls.viewport, 0, 0, canvas.width, canvas.height) const pickWidth = Math.round(canvas.width * pickScale) const pickHeight = Math.round(canvas.height * pickScale) -- GitLab