mylingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
163 lines (140 loc) • 4.81 kB
text/typescript
import { Color, RectAreaLight } from "three"
import { RectAreaLightHelper } from "three/examples/jsm/helpers/RectAreaLightHelper"
import IAreaLight, {
areaLightDefaults,
areaLightSchema
} from "../../interface/IAreaLight"
import { lazy } from "@lincode/utils"
import ObjectManager from "../core/ObjectManager"
import mainCamera from "../../engine/mainCamera"
import scene from "../../engine/scene"
import { scaleDown } from "../../engine/constants"
import { onTransformControls } from "../../events/onTransformControls"
import { Reactive } from "@lincode/reactivity"
import { getSelectionTarget } from "../../states/useSelectionTarget"
import { getCameraRendered } from "../../states/useCameraRendered"
import { getEditorModeComputed } from "../../states/useEditorModeComputed"
import Nullable from "../../interface/utils/Nullable"
const lazyInit = lazy(async () => {
const { RectAreaLightUniformsLib } = await import(
"three/examples/jsm/lights/RectAreaLightUniformsLib"
)
RectAreaLightUniformsLib.init()
})
export default class AreaLight extends ObjectManager implements IAreaLight {
public static componentName = "areaLight"
public static defaults = areaLightDefaults
public static schema = areaLightSchema
private light?: RectAreaLight
public constructor() {
super()
lazyInit().then(() => {
if (this.done) return
const light = (this.light = new RectAreaLight(
this._color,
this._intensity,
this.width * this.scaleX * scaleDown,
this.height * this.scaleY * scaleDown
))
this.object3d.add(light)
this.then(() => light.dispose())
this.createEffect(() => {
if (
getEditorModeComputed() !== "scale" ||
getSelectionTarget() !== this
)
return
const handle = onTransformControls(() => {
const { x, y } = this.outerObject3d.scale
this.scaleX = x
this.scaleY = y
})
return () => {
handle.cancel()
}
}, [getEditorModeComputed, getSelectionTarget])
this.createEffect(() => {
if (
getCameraRendered() !== mainCamera ||
!this.helperState.get()
)
return
const helper = new RectAreaLightHelper(light)
scene.add(helper)
return () => {
helper.dispose()
scene.remove(helper)
}
}, [getCameraRendered, this.helperState.get])
})
}
public shadowResolution: Nullable<number>
public shadowBias: Nullable<number>
public override get castShadow() {
return false
}
public override set castShadow(_) {}
private helperState = new Reactive(true)
public get helper() {
return this.helperState.get()
}
public set helper(val) {
this.helperState.set(val)
}
private _color?: string
public get color() {
return this._color ?? "#ffffff"
}
public set color(val) {
this._color = val
this.light && (this.light.color = new Color(val))
}
private _intensity?: number
public get intensity() {
return this._intensity ?? 1
}
public set intensity(val) {
this._intensity = val
this.light && (this.light.intensity = val)
}
private _width?: number
public override get width() {
return this._width ?? 100
}
public override set width(val) {
this._width = val
this.light && (this.light.width = val * this.scaleX * scaleDown)
}
private _height?: number
public override get height() {
return this._height ?? 100
}
public override set height(val) {
this._height = val
this.light && (this.light.height = val * this.scaleY * scaleDown)
}
private _scaleX?: number
public override get scaleX() {
return this._scaleX ?? 1
}
public override set scaleX(val) {
this._scaleX = val
this.light && (this.light.width = val * this.width * scaleDown)
}
private _scaleY?: number
public override get scaleY() {
return this._scaleY ?? 1
}
public override set scaleY(val) {
this._scaleY = val
this.light && (this.light.height = val * this.height * scaleDown)
}
public override get depth() {
return 0
}
public override set depth(_) {}
public override get scaleZ() {
return 0
}
public override set scaleZ(_) {}
}