Sfoglia il codice sorgente

ICamera transform fixes.

master
Palash Bansal 2 anni fa
parent
commit
3a95ae2cf6
Nessun account collegato all'indirizzo email del committer

+ 6
- 2
src/assetmanager/AssetManager.ts Vedi File

@@ -157,12 +157,16 @@ export class AssetManager extends EventDispatcher<BaseEvent&{data: ImportResult}
if (!(camera as PerspectiveCamera).isPerspectiveCamera || !camera.parent) {
iCameraCommons.upgradeCamera.call(camera)
} 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
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.userData.uuid = camera.uuid
;(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 Vedi File

@@ -17,6 +17,7 @@ export interface ICameraUserData extends IObject3DUserData {

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

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

+ 8
- 1
src/core/camera/PerspectiveCamera2.ts Vedi File

@@ -1,5 +1,5 @@
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 type {ICamera, ICameraEvent, ICameraUserData, TCameraControlsMode} from '../ICamera'
import {ICameraSetDirtyOptions} from '../ICamera'
@@ -9,6 +9,7 @@ import {IObject3D} from '../IObject'
import {ThreeSerialization} from '../../utils'
import {iCameraCommons} from '../object/iCameraCommons'
import {bindToValue} from '../../three/utils/decorators'
import {makeICameraCommonUiConfig} from '../object/IObjectUi'

// todo: maybe change domElement to some wrapper/base class of viewer
export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
@@ -54,8 +55,13 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
@uiVector('Target')
@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()
@onChange2(PerspectiveCamera2.prototype.refreshAspect)
@uiToggle('Auto Aspect')
autoAspect: boolean

/**
@@ -357,6 +363,7 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
children: ['', 'orbit', ...this._controlsCtors.keys()].map(v=>({label: v === '' ? 'none' : v, value:v})),
onChange: () => this.refreshCameraControls(),
}),
()=>makeICameraCommonUiConfig.call(this, this.uiConfig),
]

uiConfig: UiObjectConfig = {

+ 46
- 41
src/core/object/IObjectUi.ts Vedi File

@@ -3,6 +3,51 @@ import {IUiConfigContainer, UiObjectConfig} from 'uiconfig.js'
import {ICamera} from '../ICamera'
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 {
if (!this) return {}
if (this.uiConfig) return this.uiConfig
@@ -167,47 +212,7 @@ export function makeIObject3DUiConfig(this: IObject3D, isMesh?:boolean): UiObjec
}
// todo: if we are replacing all the cameras in the scene, is this even required?
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)
}


+ 2
- 2
src/core/object/RootScene.ts Vedi File

@@ -90,9 +90,9 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I
cam.removeEventListener('cameraUpdate', this._mainCameraUpdate)
}
if (camera) {
camera.activateMain(undefined, true)
camera.addEventListener('cameraUpdate', this._mainCameraUpdate)
this._mainCamera = camera
camera.addEventListener('cameraUpdate', this._mainCameraUpdate)
camera.activateMain(undefined, true)
} else {
this._mainCamera = null
}

+ 13
- 4
src/core/object/iCameraCommons.ts Vedi File

@@ -77,24 +77,33 @@ export const iCameraCommons = {
return this
}
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)
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()))
}
this.setDirty()
this.updateMatrixWorld(true)
this.updateProjectionMatrix()
this.refreshAspect(true)
return this
},

}

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

+ 7
- 3
src/core/object/iObjectCommons.ts Vedi File

@@ -275,10 +275,14 @@ export const iObjectCommons = {
function(this: IObject3D, source: IObject3D, ...args): IObject3D {
const 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
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'] =>
function(this: IObject3D, ...args): IObject3D {

+ 7
- 0
src/viewer/ThreeViewer.ts Vedi File

@@ -980,6 +980,13 @@ export class ThreeViewer extends EventDispatcher<IViewerEvent, IViewerEventTypes
return
}
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')
this._scene.mainCamera = event.camera || undefined // event.camera should have been upgraded when added to the scene.
}

Loading…
Annulla
Salva