| @@ -2201,10 +2201,13 @@ const anim = popmotion.animate({ | |||
| cube.setDirty() | |||
| }, | |||
| onComplete: () => isMovedUp = !isMovedUp, | |||
| onStop: () => throw(new Error('Animation stopped')), | |||
| }) | |||
| // await for animation | |||
| await anim.promise; | |||
| // await for animation. This promise will reject only if an exception is thrown in onStop | |||
| await anim.promise.catch((e)=>{ | |||
| console.log(e, 'animation stopped before completion') | |||
| }); | |||
| // or stop the animation | |||
| // anim.stop() | |||
| @@ -2213,7 +2216,7 @@ await anim.promise; | |||
| await popmotion.animateAsync({ // Also await for the animation. | |||
| from: '#' + cube.material.color.getHexString(), | |||
| to: '#' + new Color().setHSL(Math.random(), 1, 0.5).getHexString(), | |||
| duration: 500, | |||
| duration: 1000, // 1s | |||
| onUpdate: (v) => { | |||
| cube.material.color.set(v) | |||
| cube.material.setDirty() | |||
| @@ -386,10 +386,22 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I | |||
| const pos = camera.getWorldPosition(new Vector3()).sub(bbox.getCenter(new Vector3())) | |||
| const radius = 1.5 * bbox.getSize(new Vector3()).length() / 2. | |||
| const dist = pos.length() | |||
| const near = Math.max(camera.userData.minNearPlane ?? 0.2, dist - radius) | |||
| const far = Math.min(Math.max(near + 1, dist + radius), camera.cameraObject.userData.maxFarPlane ?? 1000) | |||
| // new way | |||
| // todo there is still some clipping when you are inside the model like a room. | |||
| const dist1 = -pos.clone().normalize().dot(camera.getWorldDirection(new Vector3())) | |||
| const near = Math.max(camera.userData.minNearPlane ?? 0.2, dist1 * (dist - radius)) | |||
| const far = Math.min(Math.max(near + 1, dist1 * (dist + radius)), camera.userData.maxFarPlane ?? 1000) | |||
| // old way, has issues when panning very far from the camera target | |||
| // const near = Math.max(camera.userData.minNearPlane ?? 0.2, dist - radius) | |||
| // const far = Math.min(Math.max(near + 1, dist + radius), camera.userData.maxFarPlane ?? 1000) | |||
| camera.near = near | |||
| camera.far = far | |||
| // todo try using minimum of all 6 endpoints of bbox. | |||
| // camera.near = 3 | |||
| // camera.far = 20 | |||
| } | |||
| @@ -131,16 +131,26 @@ export class PopmotionPlugin extends AViewerPluginSync<''> { | |||
| }, | |||
| } | |||
| this.animations[uuid] = a | |||
| a.promise = new Promise<void>((resolve) => { | |||
| a.promise = new Promise<void>((resolve, reject) => { | |||
| const opts: AnimationOptions<V> = { | |||
| driver: this.defaultDriver, | |||
| ...options, | |||
| onComplete: ()=>{ | |||
| options.onComplete?.() | |||
| try { | |||
| options.onComplete && options.onComplete() | |||
| } catch (e: any) { | |||
| reject(e) | |||
| return | |||
| } | |||
| resolve() | |||
| }, | |||
| onStop: ()=>{ | |||
| options.onStop?.() | |||
| try { | |||
| options.onStop && options.onStop() | |||
| } catch (e: any) { | |||
| reject(e) | |||
| return | |||
| } | |||
| resolve() | |||
| }, | |||
| } | |||
| @@ -1,7 +1,8 @@ | |||
| import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js' | |||
| import {IUiConfigContainer, uiInput, UiObjectConfig, uiPanelContainer, uiToggle} from 'uiconfig.js' | |||
| import {IUiConfigContainer, uiInput, UiObjectConfig, uiPanelContainer, uiToggle, uiVector} from 'uiconfig.js' | |||
| import {serialize} from 'ts-browser-helpers' | |||
| import {ICameraControls} from '../../core' | |||
| import {Vector3} from 'three' | |||
| export type TOrbitControlsEvents = 'change' | 'end' | 'start' | |||
| @uiPanelContainer('Orbit Controls') | |||
| @@ -41,7 +42,10 @@ export class OrbitControls3 extends OrbitControls implements IUiConfigContainer, | |||
| @uiInput() @serialize() maxPolarAngle = Math.PI | |||
| @uiInput() @serialize() minAzimuthAngle = -10000 // should be -Infinity but this breaks the UI | |||
| @uiInput() @serialize() maxAzimuthAngle = 10000 | |||
| @uiInput() @serialize() maxAzimuthAngle = 10000 // should be Infinity but this breaks the UI | |||
| @uiVector() @serialize() clampMin = new Vector3(-10000, -10000, -10000) // should be -Infinity but this breaks the UI | |||
| @uiVector() @serialize() clampMax = new Vector3(10000, 10000, 10000) // should be Infinity but this breaks the UI | |||
| // @uiToggle() | |||
| @serialize() screenSpacePanning = true | |||