Ver código fonte

Add DeviceOrientationControls2, FirstPersonControls2, OrbitControls2, PointerLockControls2, RGBM to linear conversion functions on cpu.

master
Palash Bansal 2 anos atrás
pai
commit
6d6d7e52f0
Nenhuma conta vinculada ao e-mail do autor do commit

+ 6
- 6
package-lock.json Ver arquivo

@@ -1,12 +1,12 @@
{
"name": "threepipe",
"version": "0.0.22",
"version": "0.0.23",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "threepipe",
"version": "0.0.22",
"version": "0.0.23",
"license": "Apache-2.0",
"dependencies": {
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1020/package.tgz",
@@ -41,7 +41,7 @@
"rollup-plugin-glsl": "^1.3.0",
"rollup-plugin-license": "^3.0.1",
"rollup-plugin-postcss": "^4.0.2",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2020/package.tgz",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2021/package.tgz",
"tslib": "^2.5.0",
"typedoc": "^0.25.7",
"typescript": "^5.3.3",
@@ -10464,9 +10464,9 @@
}
},
"node_modules/three": {
"version": "0.152.2020",
"resolved": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2020/package.tgz",
"integrity": "sha512-XpB018kSE/FZG5xmh6XG22lXTS9bParloATQ952tZaY3p7PsdiP3skXR49GYiLjG2Lui46wA18aq5aXJ9oabGA==",
"version": "0.152.2021",
"resolved": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2021/package.tgz",
"integrity": "sha512-va2FQU/ES07GLdflqysT82rh8x+cwx0sCYB8w+JGjDCAcwYDYqvjWafWzWP0UrDR8JM+8HoCLwh+rHtGU5Eoug==",
"dev": true,
"license": "MIT"
},

+ 1
- 1
package.json Ver arquivo

@@ -1,6 +1,6 @@
{
"name": "threepipe",
"version": "0.0.22",
"version": "0.0.23",
"description": "A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.",
"main": "dist/index.js",
"module": "dist/index.mjs",

+ 182
- 0
src/three/controls/DeviceOrientationControls2.ts Ver arquivo

@@ -0,0 +1,182 @@
import {Euler, EulerOrder, EventDispatcher, MathUtils, Object3D, Quaternion, Vector3} from 'three'
import {IEvent, now, serialize} from 'ts-browser-helpers'
import {uiPanelContainer, uiSlider} from 'uiconfig.js'
import {ICameraControls} from '../../core'

// eslint-disable-next-line @typescript-eslint/naming-convention
const _zee = new Vector3(0, 0, 1)
// eslint-disable-next-line @typescript-eslint/naming-convention
const _euler = new Euler()
// eslint-disable-next-line @typescript-eslint/naming-convention
const _q0 = new Quaternion()
// eslint-disable-next-line @typescript-eslint/naming-convention
const _q1 = new Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)) // - PI/2 around the x-axis
// eslint-disable-next-line @typescript-eslint/naming-convention
const _q2 = new Quaternion() // - PI/2 around the x-axis

// eslint-disable-next-line @typescript-eslint/naming-convention
const _changeEvent: IEvent<'change'> = {type: 'change'}

const EPS = 0.000001

@uiPanelContainer('Device Orientation Controls')
export class DeviceOrientationControls2 extends EventDispatcher implements ICameraControls<'change'> {
object: Object3D
enabled = false // do not serialize this as it signifies weather this is active.
deviceOrientation?: DeviceOrientationEvent
screenOrientation?: ScreenOrientation
lastOrder: EulerOrder = 'XYZ'
@serialize()
@uiSlider('Damping', [0, 1], 0.01)
dampingFactor = 0.05
lastQuaternion = new Quaternion()

constructor(object: Object3D) {

super()

if (window.isSecureContext === false) {

console.error('DeviceOrientationControls2: DeviceOrientationEvent is only available in secure contexts (https)')

}

this.object = object

this.lastOrder = this.object.rotation.order
this.object.rotation.reorder('YXZ')

// this.enabled = true

this.connect()

}

onDeviceOrientationChangeEvent = (event: DeviceOrientationEvent) => {
this.deviceOrientation = event
}

onScreenOrientationChangeEvent = () => {
this.screenOrientation = screen.orientation
}

private _initQuaternion = new Quaternion()
private _initQuaternionInvert = new Quaternion()
private _initQuaternionDest = new Quaternion()
connect() {

this.onScreenOrientationChangeEvent() // run once on load

// iOS 13+

if (window.DeviceOrientationEvent !== undefined && typeof (window.DeviceOrientationEvent as any).requestPermission === 'function') {

(window.DeviceOrientationEvent as any).requestPermission().then((response: string)=>{

if (response == 'granted') {

window.addEventListener('orientationchange', this.onScreenOrientationChangeEvent)
window.addEventListener('deviceorientation', this.onDeviceOrientationChangeEvent)

}

}).catch((error: any)=>{

console.error('DeviceOrientationControls2: Unable to use DeviceOrientation API:', error)

})

} else {

window.addEventListener('orientationchange', this.onScreenOrientationChangeEvent)
window.addEventListener('deviceorientation', this.onDeviceOrientationChangeEvent)

}

this.enabled = true
this._initQuaternion.copy(this.object.quaternion)
this._initQuaternionInvert.copy(this.object.quaternion).invert()

}

disconnect() {

window.removeEventListener('orientationchange', this.onScreenOrientationChangeEvent)
window.removeEventListener('deviceorientation', this.onDeviceOrientationChangeEvent)
this._initQuaternion.identity()
this._initQuaternionInvert.identity()
this._initQuaternionDest = new Quaternion() // need to set a new instance here.
this.object.rotation.reorder(this.lastOrder)
this.lastOrder = 'XYZ'

this.enabled = false

}

update() {

if (!this.enabled) return

const device = this.deviceOrientation

if (device) {

const alpha = device.alpha !== null ? MathUtils.degToRad(device.alpha) : 0 // Z

const beta = device.beta !== null ? MathUtils.degToRad(device.beta) : 0 // X'

const gamma = device.gamma !== null ? MathUtils.degToRad(device.gamma) : 0 // Y''

const orient = this.screenOrientation ? MathUtils.degToRad(this.screenOrientation.angle) : 0 // O

this.setObjectQuaternion(alpha, beta, gamma, orient)

if (8 * (1 - this.lastQuaternion.dot(this.object.quaternion)) > EPS) {

this.lastQuaternion.copy(this.object.quaternion)
this.dispatchEvent(_changeEvent)

}

}

}

dispose() {

this.disconnect()

}

private _lastTime = -1

// The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''
setObjectQuaternion(alpha: number, beta: number, gamma: number, orient: number): void {
// if(_lastTime < 0)
const time = now() / 1000

_euler.set(beta, alpha, -gamma, 'YXZ') // 'ZXY' for the device, but 'YXZ' for us

_q2.setFromEuler(_euler) // orient the device

_q2.multiply(_q1) // camera looks out the back of the device, not the top

_q2.multiply(_q0.setFromAxisAngle(_zee, -orient)) // adjust for screen orientation

if (!(this._initQuaternionDest as any).__init) {
this._initQuaternionDest.copy(_q2).invert()
;(this._initQuaternionDest as any).__init = true
}

_q2.premultiply(this._initQuaternionDest)

const mTime = 1 / 60
// this.object.quaternion.multiply(this._initQuaternionInvert)
this.object.quaternion.slerp(_q2, this.dampingFactor / (Math.min(1, time - this._lastTime) / mTime))
// this.object.quaternion.multiply(this._initQuaternion)
// console.log(time - this._lastTime, mTime)

this._lastTime = time
}

}

+ 349
- 0
src/three/controls/FirstPersonControls2.ts Ver arquivo

@@ -0,0 +1,349 @@
import {MathUtils, Object3D, Spherical, Vector3} from 'three'
import {IEvent, now, serialize, SimpleEventDispatcher} from 'ts-browser-helpers'
import {uiFolderContainer, uiInput, uiToggle} from 'uiconfig.js'

// eslint-disable-next-line @typescript-eslint/naming-convention
const _lookDirection = new Vector3()
// eslint-disable-next-line @typescript-eslint/naming-convention
const _spherical = new Spherical()
// eslint-disable-next-line @typescript-eslint/naming-convention
const _target = new Vector3()

// eslint-disable-next-line @typescript-eslint/naming-convention
const _changeEvent: IEvent<'change'> = {type: 'change'}

@uiFolderContainer('First Person Controls')
export class FirstPersonControls2 extends SimpleEventDispatcher<'change'> {
readonly object: Object3D
readonly domElement: HTMLElement | Document

// API
@serialize() @uiToggle() enabled = true
@serialize() @uiToggle() enableKeys = true

@serialize() @uiInput() movementSpeed = 1.0
@serialize() @uiInput()lookSpeed = 0.005

@serialize() @uiToggle() lookVertical = true
@serialize() @uiToggle() autoForward = false

@serialize() @uiToggle() activeLook = true

@serialize() @uiToggle() heightSpeed = false
@serialize() @uiInput()heightCoef = 1.0
@serialize() @uiInput()heightMin = 0.0
@serialize() @uiInput()heightMax = 1.0

@serialize() @uiToggle() constrainVertical = false
@serialize() @uiInput() verticalMin = 0
@serialize() @uiInput() verticalMax = Math.PI

@serialize() @uiToggle() mouseDragOn = false

// internals

autoSpeedFactor = 0.0

pointerX = 0
pointerY = 0

moveForward = false
moveBackward = false
moveLeft = false
moveRight = false
moveUp = false
moveDown = false

viewHalfX = 0
viewHalfY = 0

// private variables

// eslint-disable-next-line @typescript-eslint/naming-convention
private lat = 0
// eslint-disable-next-line @typescript-eslint/naming-convention
private lon = 0

constructor(object: Object3D, domElement: HTMLElement|Document) {
super()

this.object = object
this.domElement = domElement

this.onPointerMove = this.onPointerMove.bind(this)
this.onPointerDown = this.onPointerDown.bind(this)
this.onPointerUp = this.onPointerUp.bind(this)
this.onKeyDown = this.onKeyDown.bind(this)
this.onKeyUp = this.onKeyUp.bind(this)
this.onContextMenu = this.onContextMenu.bind(this)

this.domElement.addEventListener('contextmenu', this.onContextMenu)
;(this.domElement as HTMLElement).addEventListener('pointermove', this.onPointerMove)
;(this.domElement as HTMLElement).addEventListener('pointerdown', this.onPointerDown)
;(this.domElement as HTMLElement).addEventListener('pointerup', this.onPointerUp)

window.addEventListener('keydown', this.onKeyDown)
window.addEventListener('keyup', this.onKeyUp)

this.handleResize()

this.setOrientation()

}

setOrientation() {

const quaternion = this.object.quaternion

_lookDirection.set(0, 0, -1).applyQuaternion(quaternion)
_spherical.setFromVector3(_lookDirection)

this.lat = 90 - MathUtils.radToDeg(_spherical.phi)
this.lon = MathUtils.radToDeg(_spherical.theta)

}

handleResize() {

if (this.domElement === document) {

this.viewHalfX = window.innerWidth / 2
this.viewHalfY = window.innerHeight / 2

} else {

this.viewHalfX = (this.domElement as HTMLElement).offsetWidth / 2
this.viewHalfY = (this.domElement as HTMLElement).offsetHeight / 2

}

}

onPointerDown(event: PointerEvent) {

if (this.domElement !== document) {

(this.domElement as HTMLElement).focus()

}

if (this.activeLook) {

switch (event.button) {

case 0: this.moveForward = true; break
case 2: this.moveBackward = true; break
default: break

}

}

this.mouseDragOn = true

}

onPointerUp(event: PointerEvent) {

if (this.activeLook) {

switch (event.button) {

case 0: this.moveForward = false; break
case 2: this.moveBackward = false; break
default: break

}

}

this.mouseDragOn = false

}

onPointerMove(event: PointerEvent) {

if (this.domElement === document) {

this.pointerX = event.pageX - this.viewHalfX
this.pointerY = event.pageY - this.viewHalfY

} else {

this.pointerX = event.pageX - (this.domElement as HTMLElement).offsetLeft - this.viewHalfX
this.pointerY = event.pageY - (this.domElement as HTMLElement).offsetTop - this.viewHalfY

}

}

onKeyDown(event: KeyboardEvent) {
if (!this.enableKeys) return

switch (event.code) {

case 'ArrowUp':
case 'KeyW': this.moveForward = true; break

case 'ArrowLeft':
case 'KeyA': this.moveLeft = true; break

case 'ArrowDown':
case 'KeyS': this.moveBackward = true; break

case 'ArrowRight':
case 'KeyD': this.moveRight = true; break

case 'KeyR': this.moveUp = true; break
case 'KeyF': this.moveDown = true; break

default: break

}

}

onKeyUp(event: KeyboardEvent) {
if (!this.enableKeys) return

switch (event.code) {

case 'ArrowUp':
case 'KeyW': this.moveForward = false; break

case 'ArrowLeft':
case 'KeyA': this.moveLeft = false; break

case 'ArrowDown':
case 'KeyS': this.moveBackward = false; break

case 'ArrowRight':
case 'KeyD': this.moveRight = false; break

case 'KeyR': this.moveUp = false; break
case 'KeyF': this.moveDown = false; break

default: break

}

}

lookAt(x: number|Vector3, y?: number, z?: number) {

if ((x as Vector3).isVector3) {

_target.copy(x as Vector3)

} else {

if (y === undefined || z === undefined) console.error('FirstPersonControls2.lookAt: y and z parameters are required')
else _target.set(x as number, y, z)

}

this.object.lookAt(_target)

this.setOrientation()

return this

}

// eslint-disable-next-line @typescript-eslint/naming-convention
private targetPosition = new Vector3()

private _lastTime = -1 // in ms

update() {
const time = now() // in ms
const delta = (this._lastTime < 0 ? 16 : Math.min(time - this._lastTime, 1000)) / 1000 // in secs
this._lastTime = time
// console.log(delta)

if (!this.enabled) return

if (this.heightSpeed) {

const y = MathUtils.clamp(this.object.position.y, this.heightMin, this.heightMax)
const heightDelta = y - this.heightMin

this.autoSpeedFactor = delta * (heightDelta * this.heightCoef)

} else {

this.autoSpeedFactor = 0.0

}

const actualMoveSpeed = delta * this.movementSpeed

if (this.moveForward || this.autoForward && !this.moveBackward) this.object.translateZ(-(actualMoveSpeed + this.autoSpeedFactor))
if (this.moveBackward) this.object.translateZ(actualMoveSpeed)

if (this.moveLeft) this.object.translateX(-actualMoveSpeed)
if (this.moveRight) this.object.translateX(actualMoveSpeed)

if (this.moveUp) this.object.translateY(actualMoveSpeed)
if (this.moveDown) this.object.translateY(-actualMoveSpeed)

let actualLookSpeed = delta * this.lookSpeed

if (!this.activeLook) {

actualLookSpeed = 0

}

let verticalLookRatio = 1

if (this.constrainVertical) {

verticalLookRatio = Math.PI / (this.verticalMax - this.verticalMin)

}

this.lon -= this.pointerX * actualLookSpeed
if (this.lookVertical) this.lat -= this.pointerY * actualLookSpeed * verticalLookRatio

this.lat = Math.max(-85, Math.min(85, this.lat))

let phi = MathUtils.degToRad(90 - this.lat)
const theta = MathUtils.degToRad(this.lon)

if (this.constrainVertical) {

phi = MathUtils.mapLinear(phi, 0, Math.PI, this.verticalMin, this.verticalMax)

}

const position = this.object.position

this.targetPosition.setFromSphericalCoords(1, phi, theta).add(position)

this.object.lookAt(this.targetPosition)
this.dispatchEvent(_changeEvent)

}

dispose() {

this.domElement.removeEventListener('contextmenu', this.onContextMenu)
;(this.domElement as HTMLElement).removeEventListener('pointerdown', this.onPointerDown)
;(this.domElement as HTMLElement).removeEventListener('pointermove', this.onPointerMove)
;(this.domElement as HTMLElement).removeEventListener('pointerup', this.onPointerUp)

window.removeEventListener('keydown', this.onKeyDown)
window.removeEventListener('keyup', this.onKeyUp)

}

onContextMenu(event: Event) {
if (!this.enableKeys) return

event.preventDefault()

}

}


+ 91
- 0
src/three/controls/OrbitControls2.ts Ver arquivo

@@ -0,0 +1,91 @@
import {Camera, PerspectiveCamera, Vector3} from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'

const offset2 = new Vector3()
const targetDeltaX = new Vector3()
const targetDeltaY = new Vector3()
const targetDeltaZ = new Vector3()
const targetDelta = new Vector3()
const panOffset2 = new Vector3()
let scaleOffset = 1
const upVec = new Vector3(0, 1, 0)

export class OrbitControls2 extends OrbitControls {

throttleUpdate = 60
constructor(object: Camera, domElement: HTMLElement) {
super(object, domElement)
const sup = this.update
this.update = ()=>this._update(sup)
}

readonly targetOffset = new Vector3(0, 0, 0)

private _update(sup: ()=>boolean): boolean {

this.target.add(this.targetOffset)

offset2.copy(this.object.position).sub(this.target)

scaleOffset = offset2.length()

panOffset2.copy(this.target)

const ret = sup()

panOffset2.sub(this.target) // get the panOffset of this frame from OrbitControls

// if (panOffset2.length() > 0.0001)
// console.log(panOffset2.toArray())

// console.log(offset2.clone().normalize().cross(upVec))

offset2.copy(this.object.position).sub(this.target)

// panOffset2.multiplyScalar(-1)

// panOffset3.x = panOffset3.z
// console.log(panOffset3.z)

scaleOffset /= offset2.length()

this.target.add(panOffset2)

this.object.position.copy(this.target).add(offset2)

offset2.normalize()

targetDeltaX.crossVectors(upVec, offset2).normalize()
targetDeltaY.crossVectors(offset2, targetDeltaX).normalize()
targetDeltaZ.crossVectors(targetDeltaX, targetDeltaY).normalize().negate()

if (targetDeltaX.length() > 0.1) // check if not 0
this.object.up.crossVectors(offset2.clone().normalize(), targetDeltaX)

if (this.enablePan) {
targetDelta.set(0, 0, 0)
.addScaledVector(targetDeltaX, panOffset2.x)
.addScaledVector(targetDeltaY, panOffset2.y)
.addScaledVector(targetDeltaZ, panOffset2.z)
this.targetOffset.add(targetDelta)
this.targetOffset.multiplyScalar(1. / scaleOffset)
}

targetDelta.set(0, 0, 0)
.addScaledVector(targetDeltaX, -this.targetOffset.x)
.addScaledVector(targetDeltaY, -this.targetOffset.y)
.addScaledVector(targetDeltaZ, -this.targetOffset.z)

// console.log(targetDelta)
this.object.lookAt(targetDelta.add(this.target))

this.object.updateMatrixWorld()
if ((this.object as PerspectiveCamera).isCamera) {
(this.object as PerspectiveCamera).updateProjectionMatrix()
}

this.target.sub(this.targetOffset)

return ret
}
}

+ 191
- 0
src/three/controls/PointerLockControls2.ts Ver arquivo

@@ -0,0 +1,191 @@
import {Euler, EventDispatcher, Object3D, Vector3} from 'three'
import {IEvent, serialize} from 'ts-browser-helpers'
import {uiInput, uiPanelContainer, uiToggle} from 'uiconfig.js'
import {ICameraControls} from '../../core'

// eslint-disable-next-line @typescript-eslint/naming-convention
const _euler = new Euler(0, 0, 0, 'YXZ')
// eslint-disable-next-line @typescript-eslint/naming-convention
const _vector = new Vector3()

export type TPointerLockEvents = 'change'|'lock'|'unlock'
// eslint-disable-next-line @typescript-eslint/naming-convention
const _changeEvent: IEvent<TPointerLockEvents> = {type: 'change'}
// eslint-disable-next-line @typescript-eslint/naming-convention
const _lockEvent: IEvent<TPointerLockEvents> = {type: 'lock'}
// eslint-disable-next-line @typescript-eslint/naming-convention
const _unlockEvent: IEvent<TPointerLockEvents> = {type: 'unlock'}

// eslint-disable-next-line @typescript-eslint/naming-convention
const _PI_2 = Math.PI / 2

@uiPanelContainer('Pointer Lock Controls')
export class PointerLockControls2 extends EventDispatcher implements ICameraControls<TPointerLockEvents> {
readonly domElement: HTMLElement
readonly object: Object3D
isLocked = false

@uiToggle() @serialize() enabled = true

// Set to constrain the pitch of the camera
// Range is 0 to Math.PI radians
@uiInput() @serialize() minPolarAngle = 0 // radians
@uiInput() @serialize() maxPolarAngle = Math.PI // radians

@uiInput() @serialize() pointerSpeed = 1.0

@uiToggle() @serialize() autoLockOnClick = true

constructor(camera: Object3D, domElement: HTMLElement) {

super()

this.domElement = domElement
this.object = camera
this.onElementClick = this.onElementClick.bind(this)
this.onMouseMove = this.onMouseMove.bind(this)
this.onPointerlockChange = this.onPointerlockChange.bind(this)
this.onPointerlockError = this.onPointerlockError.bind(this)

this.connect()
}


onElementClick(event: Event) {

if (this.isLocked) return
if (!this.autoLockOnClick) return

event.preventDefault()

this.lock()
}

private _movementX = 0
private _movementY = 0

onMouseMove(event: MouseEvent) {

if (!this.isLocked) return

this._movementX += event.movementX || (event as any).mozMovementX || (event as any).webkitMovementX || 0
this._movementY += event.movementY || (event as any).mozMovementY || (event as any).webkitMovementY || 0

}

onPointerlockChange() {

if (this.domElement.ownerDocument.pointerLockElement === this.domElement) {

this.dispatchEvent(_lockEvent)

this.isLocked = true

} else {

this.dispatchEvent(_unlockEvent)

this.isLocked = false

}

}

onPointerlockError() {

console.error('THREE.PointerLockControls: Unable to use Pointer Lock API')

}

connect() {

this.domElement.ownerDocument.addEventListener('mousemove', this.onMouseMove)
this.domElement.ownerDocument.addEventListener('pointerlockchange', this.onPointerlockChange)
this.domElement.ownerDocument.addEventListener('pointerlockerror', this.onPointerlockError)
this.domElement.addEventListener('click', this.onElementClick)

}

disconnect() {

this.domElement.ownerDocument.removeEventListener('mousemove', this.onMouseMove)
this.domElement.ownerDocument.removeEventListener('pointerlockchange', this.onPointerlockChange)
this.domElement.ownerDocument.removeEventListener('pointerlockerror', this.onPointerlockError)
this.domElement.removeEventListener('click', this.onElementClick)

}

dispose() {

this.disconnect()

}

// getObject() { // retaining this method for backward compatibility
//
// return this.object
//
// }


private _forwardDirection = new Vector3(0, 0, -1)
getDirection(v: Vector3) {

return v.copy(this._forwardDirection).applyQuaternion(this.object.quaternion)

}

moveForward(distance: number) {

// move forward parallel to the xz-plane
// assumes camera.up is y-up

_vector.setFromMatrixColumn(this.object.matrix, 0)

_vector.crossVectors(this.object.up, _vector)

this.object.position.addScaledVector(_vector, distance)

}

moveRight(distance: number) {

_vector.setFromMatrixColumn(this.object.matrix, 0)

this.object.position.addScaledVector(_vector, distance)

}

lock() {

this.domElement.requestPointerLock()

}

unlock() {

this.domElement.ownerDocument.exitPointerLock()

}

update() {

if (Math.abs(this._movementX) < 0.0001 && Math.abs(this._movementY) < 0.0001) return

_euler.setFromQuaternion(this.object.quaternion)

_euler.y -= this._movementX * 0.002 * this.pointerSpeed
_euler.x -= this._movementY * 0.002 * this.pointerSpeed

this._movementX = 0
this._movementY = 0

_euler.x = Math.max(_PI_2 - this.maxPolarAngle, Math.min(_PI_2 - this.minPolarAngle, _euler.x))

this.object.quaternion.setFromEuler(_euler)

this.dispatchEvent(_changeEvent)

}

}

+ 4
- 0
src/three/index.ts Ver arquivo

@@ -1,6 +1,10 @@
export {OrbitControls3, type TOrbitControlsEvents} from './controls/OrbitControls3'
export {TransformControls2} from './controls/TransformControls2'
export {TransformControls, TransformControlsGizmo, TransformControlsPlane} from './controls/TransformControls'
export {FirstPersonControls2} from './controls/FirstPersonControls2'
export {PointerLockControls2, type TPointerLockEvents} from './controls/PointerLockControls2'
export {DeviceOrientationControls2} from './controls/DeviceOrientationControls2'
export {OrbitControls2} from './controls/OrbitControls2'
export {Box3B} from './math/Box3B'
export * from './utils/index'
export * from './widgets/index'

+ 26
- 0
src/utils/color-encodings.ts Ver arquivo

@@ -0,0 +1,26 @@
import {Color, Vector4} from 'three'
// todo: move these to ts-browser-helpers maybe

// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
export function vRGBMToLinear(value: Vector4, maxRange: number): Vector4 {
value.multiplyScalar(value.w * maxRange)
value.w = 1.0
return value
}

export function cRGBMToLinear(value: Vector4, maxRange: number): Color {
vRGBMToLinear(value, maxRange)
return new Color(value.x, value.y, value.z)
}

export function vLinearToRGBM(value: Vector4, maxRange: number): Vector4 {
const maxRGB = Math.max(value.x, Math.max(value.y, value.z))
let M = Math.max(Math.min(maxRGB / maxRange, 1.0), 0.0)
M = Math.ceil(M * 255.0) / 255.0
value.divideScalar(M * maxRange)
value.w = M
return value
}
export function cLinearToRGBM(value: Color, maxRange: number): Vector4 {
return vLinearToRGBM(new Vector4(value.r, value.g, value.b, 1.0), maxRange)
}

+ 2
- 0
src/utils/index.ts Ver arquivo

@@ -9,5 +9,7 @@ export {shaderReplaceString} from './shader-helpers'
export {makeGLBFile} from './gltf'
export {animateCameraToViewLinear, animateCameraToViewSpherical, sphericalFromCameraView} from './camera-anim'
export {animateAsync, animateTarget, EasingFunctions, makeSetterFor, animate, lerp, lerpAngle} from './animation'
export {cLinearToRGBM, vLinearToRGBM, cRGBMToLinear, vRGBMToLinear} from './color-encodings'
export {CanvasSnapshot, type CanvasSnapshotOptions, type CanvasSnapshotRect} from './canvas-snapshot'
export type {Easing, KeyframeOptions, AnimationOptions, EasingFunctionType, AnimateResult} from './animation'


+ 1
- 1
src/viewer/version.ts Ver arquivo

@@ -1 +1 @@
export const VERSION = '0.0.22'
export const VERSION = '0.0.23'

Carregando…
Cancelar
Salvar