| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- import {ColorRepresentation, Object3D, SpotLight, Vector3} from 'three'
- import {LineGeometry} from 'three/examples/jsm/lines/LineGeometry.js'
- import {LineSegments2} from 'three/examples/jsm/lines/LineSegments2.js'
- import {LineSegmentsGeometry} from 'three/examples/jsm/lines/LineSegmentsGeometry.js'
- import {onChange} from 'ts-browser-helpers'
- import {ALightHelperWidget} from './ALightHelperWidget'
- import {IUiConfigContainer, uiSlider} from 'uiconfig.js'
- import {LineMaterial2} from '../../core'
-
- export class SpotLightHelper2 extends ALightHelperWidget {
- color: ColorRepresentation | undefined
- cone: LineSegments2
- light: (SpotLight & IUiConfigContainer) | undefined
- @onChange(SpotLightHelper2.prototype.update)
- material: LineMaterial2
- @onChange(SpotLightHelper2.prototype.update)
- @uiSlider(undefined, [0.1, 20], 0.01)
- lineWidth = 5
-
- constructor(light: SpotLight, size?: number, color?: ColorRepresentation) {
- super(light)
-
- this.color = color
-
- if (size === undefined) size = 0.5
-
- let geometry = new LineSegmentsGeometry()
- const positions = [
- 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 1,
- 0, 0, 0, -1, 0, 1,
- 0, 0, 0, 0, 1, 1,
- 0, 0, 0, 0, -1, 1,
- ]
-
- for (let i = 0, j = 1, l = 32; i < l; i++, j++) {
-
- const p1 = i / l * Math.PI * 2
- const p2 = j / l * Math.PI * 2
-
- positions.push(
- Math.cos(p1), Math.sin(p1), 1,
- Math.cos(p2), Math.sin(p2), 1
- )
-
- }
- geometry.setPositions(positions)
-
- this.material = new LineMaterial2({
- color: 0xff0000,
- linewidth: 0.005, // in world units with size attenuation, pixels otherwise
- vertexColors: false,
-
- dashed: false,
- alphaToCoverage: true,
-
- toneMapped: false,
- transparent: true,
- depthTest: false,
- depthWrite: false,
- })
-
- this.cone = new LineSegments2(geometry, this.material)
- this.add(this.cone)
-
- geometry = new LineGeometry()
- geometry.setPositions([0, 0, 0, 0, 0, 1])
-
- this.update()
-
- this.traverse(o => {
- o.userData.__keepShadowDef = true
- o.castShadow = false
- o.receiveShadow = false
- })
- }
-
- dispose() {
-
- this.cone.geometry.dispose()
- this.cone.material.dispose()
-
- super.dispose()
- }
-
- private _v1 = new Vector3()
-
- update() {
-
- if (!this.light || !this.cone) return
-
- this.light.updateWorldMatrix(true, false)
- this.light.target.updateWorldMatrix(true, false)
-
- const coneLength = this.light.distance ? this.light.distance : 1000
- const coneWidth = coneLength * Math.tan(this.light.angle)
-
- this.cone.scale.set(coneWidth, coneWidth, coneLength)
-
- this._v1.setFromMatrixPosition(this.light.target.matrixWorld)
-
- this.cone.lookAt(this._v1)
-
- this.material.color.set(this.color ?? this.light.color)
- this.material.linewidth = this.lineWidth * 0.001
-
- super.update()
- }
-
- static Check(light: Object3D) {
- return (light as SpotLight).isSpotLight
- }
-
- static Create(light: Object3D) {
- return new SpotLightHelper2(light as SpotLight)
- }
-
- }
|