瀏覽代碼

Reject promise on error in PopmotionPlugin, add clampMin, clampMax to OrbitControls, fix near far calculation.

master
Palash Bansal 2 年之前
父節點
當前提交
249c1d292a
沒有連結到貢獻者的電子郵件帳戶。
共有 4 個檔案被更改,包括 39 行新增10 行删除
  1. 6
    3
      README.md
  2. 14
    2
      src/core/object/RootScene.ts
  3. 13
    3
      src/plugins/animation/PopmotionPlugin.ts
  4. 6
    2
      src/three/controls/OrbitControls3.ts

+ 6
- 3
README.md 查看文件

cube.setDirty() cube.setDirty()
}, },
onComplete: () => isMovedUp = !isMovedUp, 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 // or stop the animation
// anim.stop() // anim.stop()
await popmotion.animateAsync({ // Also await for the animation. await popmotion.animateAsync({ // Also await for the animation.
from: '#' + cube.material.color.getHexString(), from: '#' + cube.material.color.getHexString(),
to: '#' + new Color().setHSL(Math.random(), 1, 0.5).getHexString(), to: '#' + new Color().setHSL(Math.random(), 1, 0.5).getHexString(),
duration: 500,
duration: 1000, // 1s
onUpdate: (v) => { onUpdate: (v) => {
cube.material.color.set(v) cube.material.color.set(v)
cube.material.setDirty() cube.material.setDirty()

+ 14
- 2
src/core/object/RootScene.ts 查看文件

const pos = camera.getWorldPosition(new Vector3()).sub(bbox.getCenter(new Vector3())) const pos = camera.getWorldPosition(new Vector3()).sub(bbox.getCenter(new Vector3()))
const radius = 1.5 * bbox.getSize(new Vector3()).length() / 2. const radius = 1.5 * bbox.getSize(new Vector3()).length() / 2.
const dist = pos.length() 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.near = near
camera.far = far camera.far = far

// todo try using minimum of all 6 endpoints of bbox.

// camera.near = 3 // camera.near = 3
// camera.far = 20 // camera.far = 20
} }

+ 13
- 3
src/plugins/animation/PopmotionPlugin.ts 查看文件

}, },
} }
this.animations[uuid] = a this.animations[uuid] = a
a.promise = new Promise<void>((resolve) => {
a.promise = new Promise<void>((resolve, reject) => {
const opts: AnimationOptions<V> = { const opts: AnimationOptions<V> = {
driver: this.defaultDriver, driver: this.defaultDriver,
...options, ...options,
onComplete: ()=>{ onComplete: ()=>{
options.onComplete?.()
try {
options.onComplete && options.onComplete()
} catch (e: any) {
reject(e)
return
}
resolve() resolve()
}, },
onStop: ()=>{ onStop: ()=>{
options.onStop?.()
try {
options.onStop && options.onStop()
} catch (e: any) {
reject(e)
return
}
resolve() resolve()
}, },
} }

+ 6
- 2
src/three/controls/OrbitControls3.ts 查看文件

import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js' 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 {serialize} from 'ts-browser-helpers'
import {ICameraControls} from '../../core' import {ICameraControls} from '../../core'
import {Vector3} from 'three'


export type TOrbitControlsEvents = 'change' | 'end' | 'start' export type TOrbitControlsEvents = 'change' | 'end' | 'start'
@uiPanelContainer('Orbit Controls') @uiPanelContainer('Orbit Controls')
@uiInput() @serialize() maxPolarAngle = Math.PI @uiInput() @serialize() maxPolarAngle = Math.PI


@uiInput() @serialize() minAzimuthAngle = -10000 // should be -Infinity but this breaks the UI @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() // @uiToggle()
@serialize() screenSpacePanning = true @serialize() screenSpacePanning = true

Loading…
取消
儲存