소스 검색

ICamera transform fixes.

master
Palash Bansal 2 년 전
부모
커밋
3a95ae2cf6
No account linked to committer's email address

+ 6
- 2
src/assetmanager/AssetManager.ts 파일 보기

if (!(camera as PerspectiveCamera).isPerspectiveCamera || !camera.parent) { if (!(camera as PerspectiveCamera).isPerspectiveCamera || !camera.parent) {
iCameraCommons.upgradeCamera.call(camera) iCameraCommons.upgradeCamera.call(camera)
} else { } else {
const newCamera: ICamera = (camera as any).iCamera ?? new PerspectiveCamera2('', this.viewer.canvas).copy(camera)
const newCamera: ICamera = (camera as any).iCamera ?? new PerspectiveCamera2('', this.viewer.canvas)
if (camera === newCamera) continue if (camera === newCamera) continue
camera.parent.children.splice(camera.parent.children.indexOf(camera), 1, newCamera)
newCamera.parent = camera.parent as any
newCamera.copy(camera as any)
camera.parent = null
;(newCamera as any).uuid = camera.uuid ;(newCamera as any).uuid = camera.uuid
newCamera.userData.uuid = camera.uuid newCamera.userData.uuid = camera.uuid
;(camera as any).iCamera = newCamera ;(camera as any).iCamera = newCamera
camera.parent.children.splice(camera.parent.children.indexOf(camera), 1, newCamera)
// console.log('replacing camera', camera, newCamera)
} }
} }



+ 1
- 0
src/core/ICamera.ts 파일 보기



__lastScale?: Vector3, __lastScale?: Vector3,
__isMainCamera?: boolean, __isMainCamera?: boolean,
__cameraSetup?: boolean,


// [key: string]: any // commented for noe // [key: string]: any // commented for noe
} }

+ 8
- 1
src/core/camera/PerspectiveCamera2.ts 파일 보기

import {Camera, Event, IUniform, Object3D, PerspectiveCamera, Vector3} from 'three' import {Camera, Event, IUniform, Object3D, PerspectiveCamera, Vector3} from 'three'
import {generateUiConfig, uiInput, UiObjectConfig, uiSlider, uiVector} from 'uiconfig.js'
import {generateUiConfig, uiInput, UiObjectConfig, uiSlider, uiToggle, uiVector} from 'uiconfig.js'
import {onChange, onChange2, onChange3, serialize} from 'ts-browser-helpers' import {onChange, onChange2, onChange3, serialize} from 'ts-browser-helpers'
import type {ICamera, ICameraEvent, ICameraUserData, TCameraControlsMode} from '../ICamera' import type {ICamera, ICameraEvent, ICameraUserData, TCameraControlsMode} from '../ICamera'
import {ICameraSetDirtyOptions} from '../ICamera' import {ICameraSetDirtyOptions} from '../ICamera'
import {ThreeSerialization} from '../../utils' import {ThreeSerialization} from '../../utils'
import {iCameraCommons} from '../object/iCameraCommons' import {iCameraCommons} from '../object/iCameraCommons'
import {bindToValue} from '../../three/utils/decorators' import {bindToValue} from '../../three/utils/decorators'
import {makeICameraCommonUiConfig} from '../object/IObjectUi'


// todo: maybe change domElement to some wrapper/base class of viewer // todo: maybe change domElement to some wrapper/base class of viewer
export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera { export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
@uiVector('Target') @uiVector('Target')
@serialize() readonly target: Vector3 = new Vector3(0, 0, 0) @serialize() readonly target: Vector3 = new Vector3(0, 0, 0)


/**
* Automatically manage aspect ratio based on window/canvas size.
* Defaults to `true` if {@link domElement}(canvas) is set.
*/
@serialize() @serialize()
@onChange2(PerspectiveCamera2.prototype.refreshAspect) @onChange2(PerspectiveCamera2.prototype.refreshAspect)
@uiToggle('Auto Aspect')
autoAspect: boolean autoAspect: boolean


/** /**
children: ['', 'orbit', ...this._controlsCtors.keys()].map(v=>({label: v === '' ? 'none' : v, value:v})), children: ['', 'orbit', ...this._controlsCtors.keys()].map(v=>({label: v === '' ? 'none' : v, value:v})),
onChange: () => this.refreshCameraControls(), onChange: () => this.refreshCameraControls(),
}), }),
()=>makeICameraCommonUiConfig.call(this, this.uiConfig),
] ]


uiConfig: UiObjectConfig = { uiConfig: UiObjectConfig = {

+ 46
- 41
src/core/object/IObjectUi.ts 파일 보기

import {ICamera} from '../ICamera' import {ICamera} from '../ICamera'
import {Vector3} from 'three' import {Vector3} from 'three'


export function makeICameraCommonUiConfig(this: IObject3D, config: UiObjectConfig): UiObjectConfig[] {
return [
{
type: 'button',
label: 'Set View',
value: ()=>{
// todo: call setView on the camera, which will dispatch the event
(this as ICamera).dispatchEvent({type: 'setView', ui: true, camera: this as ICamera})
config.uiRefresh?.(true, 'postFrame')
console.log('set view', this)
},
},
{
type: 'button',
label: 'Activate main',
hidden: ()=>(this as ICamera)?.isMainCamera,
value: ()=>{
// todo: call activateMain on the camera, which will dispatch the event
(this as ICamera).dispatchEvent({type: 'activateMain', ui: true, camera: this as ICamera})
config.uiRefresh?.(true, 'postFrame')
},
},
{
type: 'button',
label: 'Deactivate main',
hidden: ()=>!(this as ICamera)?.isMainCamera,
value: ()=>{
// todo: call activateMain on the camera, which will dispatch the event
(this as ICamera).dispatchEvent({type: 'activateMain', ui: true, camera: undefined})
config.uiRefresh?.(true, 'postFrame')
},
},
{
type: 'checkbox',
label: 'Auto LookAt Target',
getValue: ()=>(this as ICamera).userData.autoLookAtTarget ?? false,
setValue: (v)=>{
(this as ICamera).userData.autoLookAtTarget = v
config.uiRefresh?.(true, 'postFrame')
},
},
]
}


export function makeIObject3DUiConfig(this: IObject3D, isMesh?:boolean): UiObjectConfig { export function makeIObject3DUiConfig(this: IObject3D, isMesh?:boolean): UiObjectConfig {
if (!this) return {} if (!this) return {}
if (this.uiConfig) return this.uiConfig if (this.uiConfig) return this.uiConfig
} }
// todo: if we are replacing all the cameras in the scene, is this even required? // todo: if we are replacing all the cameras in the scene, is this even required?
if (this.isCamera) { if (this.isCamera) {
// todo: move to make camera ui function?
const ui: UiObjectConfig[] = [
{
type: 'button',
label: 'Set View',
value: ()=>{
// todo: call setView on the camera, which will dispatch the event
(this as ICamera).dispatchEvent({type: 'setView', ui: true, camera: this as ICamera})
config.uiRefresh?.(true, 'postFrame')
},
},
{
type: 'button',
label: 'Activate main',
hidden: ()=>(this as ICamera)?.isMainCamera,
value: ()=>{
// todo: call activateMain on the camera, which will dispatch the event
(this as ICamera).dispatchEvent({type: 'activateMain', ui: true, camera: this as ICamera})
config.uiRefresh?.(true, 'postFrame')
},
},
{
type: 'button',
label: 'Deactivate main',
hidden: ()=>!(this as ICamera)?.isMainCamera,
value: ()=>{
// todo: call activateMain on the camera, which will dispatch the event
(this as ICamera).dispatchEvent({type: 'activateMain', ui: true, camera: undefined})
config.uiRefresh?.(true, 'postFrame')
},
},
{
type: 'checkbox',
label: 'Auto LookAt Target',
getValue: ()=>(this as ICamera).userData.autoLookAtTarget ?? false,
setValue: (v)=>{
(this as ICamera).userData.autoLookAtTarget = v
config.uiRefresh?.(true, 'postFrame')
},
},
]
const ui: UiObjectConfig[] = makeICameraCommonUiConfig.call(this as ICamera, config)
;(config.children as UiObjectConfig[]).push(...ui) ;(config.children as UiObjectConfig[]).push(...ui)
} }



+ 2
- 2
src/core/object/RootScene.ts 파일 보기

cam.removeEventListener('cameraUpdate', this._mainCameraUpdate) cam.removeEventListener('cameraUpdate', this._mainCameraUpdate)
} }
if (camera) { if (camera) {
camera.activateMain(undefined, true)
camera.addEventListener('cameraUpdate', this._mainCameraUpdate)
this._mainCamera = camera this._mainCamera = camera
camera.addEventListener('cameraUpdate', this._mainCameraUpdate)
camera.activateMain(undefined, true)
} else { } else {
this._mainCamera = null this._mainCamera = null
} }

+ 13
- 4
src/core/object/iCameraCommons.ts 파일 보기

return this return this
} }
superCopy.call(this, camera, recursive, ...args) superCopy.call(this, camera, recursive, ...args)
this.position.copy(this.worldToLocal(camera.getWorldPosition(new Vector3())))
// moved to setView in ThreeViewer
// const worldPos = camera.getWorldPosition(this.position)
// camera.getWorldQuaternion(this.quaternion)
// if (this.parent) {
// this.position.copy(this.parent.worldToLocal(worldPos))
// this.quaternion.premultiply(this.parent.quaternion.clone().invert())
// }
if ((<ICamera>camera).target?.isVector3) this.target.copy((<ICamera>camera).target) if ((<ICamera>camera).target?.isVector3) this.target.copy((<ICamera>camera).target)
else { else {
const minDistance = (this.controls as any).minDistance ?? distanceFromTarget ?? 4
const minDistance = (this.controls as any)?.minDistance ?? distanceFromTarget ?? 4
camera.getWorldDirection(this.target).multiplyScalar(minDistance).add(this.getWorldPosition(new Vector3())) camera.getWorldDirection(this.target).multiplyScalar(minDistance).add(this.getWorldPosition(new Vector3()))
} }
this.setDirty()
this.updateMatrixWorld(true)
this.updateProjectionMatrix()
this.refreshAspect(true)
return this return this
}, },


} }


function upgradeCamera(this: ICamera) { function upgradeCamera(this: ICamera) {
if (this.assetType === 'camera') return // already upgraded
if (!this.isCamera) { if (!this.isCamera) {
console.error('Object is not a camera', this) console.error('Object is not a camera', this)
return return
} }
if (this.userData.__cameraSetup) return
this.userData.__cameraSetup = true
iObjectCommons.upgradeObject3D.call(this) iObjectCommons.upgradeObject3D.call(this)
this.copy = iCameraCommons.copy(this.copy) this.copy = iCameraCommons.copy(this.copy)
if (!this.target) this.target = new Vector3() if (!this.target) this.target = new Vector3()

+ 7
- 3
src/core/object/iObjectCommons.ts 파일 보기

function(this: IObject3D, source: IObject3D, ...args): IObject3D { function(this: IObject3D, source: IObject3D, ...args): IObject3D {
const userData = source.userData const userData = source.userData
source.userData = {} source.userData = {}
const t: any = superCopy.call(this, source, ...args)

const selfUserData = this.userData
superCopy.call(this, source, ...args)
this.userData = selfUserData

source.userData = userData source.userData = userData
copyObject3DUserData(this.userData, source) // todo: do same for object.toJSON()
return t
copyObject3DUserData(this.userData, source.userData) // todo: do same for object.toJSON()
return this
}, },
add: (superAdd: IObject3D['add']): IObject3D['add'] => add: (superAdd: IObject3D['add']): IObject3D['add'] =>
function(this: IObject3D, ...args): IObject3D { function(this: IObject3D, ...args): IObject3D {

+ 7
- 0
src/viewer/ThreeViewer.ts 파일 보기

return return
} }
this._scene.mainCamera.copy(event.camera) this._scene.mainCamera.copy(event.camera)
const worldPos = event.camera.getWorldPosition(this._scene.mainCamera.position)
// camera.getWorldQuaternion(this.quaternion) // todo: do if autoLookAtTarget is false
if (this._scene.mainCamera.parent) {
this._scene.mainCamera.position.copy(this._scene.mainCamera.parent.worldToLocal(worldPos))
// this.quaternion.premultiply(this.parent.quaternion.clone().invert())
}
this._scene.mainCamera.setDirty()
} else if (event.type === 'activateMain') } else if (event.type === 'activateMain')
this._scene.mainCamera = event.camera || undefined // event.camera should have been upgraded when added to the scene. this._scene.mainCamera = event.camera || undefined // event.camera should have been upgraded when added to the scene.
} }

Loading…
취소
저장