diff --git a/src/DatabaseServices/Lights/AmbientLight.ts b/src/DatabaseServices/Lights/AmbientLight.ts index b1853d990..c44fa57ba 100644 --- a/src/DatabaseServices/Lights/AmbientLight.ts +++ b/src/DatabaseServices/Lights/AmbientLight.ts @@ -7,6 +7,7 @@ import { Light } from "./Light"; export class AmbientLight extends Light { protected _Intensity = 0.9; + protected _OpenLight = true;//开灯 protected InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D { let light = new TAmbientLight(this.Color, this._Intensity); diff --git a/src/DatabaseServices/Lights/DirectionalLight.ts b/src/DatabaseServices/Lights/DirectionalLight.ts index c4f55fe28..a5b1ae68a 100644 --- a/src/DatabaseServices/Lights/DirectionalLight.ts +++ b/src/DatabaseServices/Lights/DirectionalLight.ts @@ -24,6 +24,7 @@ export class DirectionalLight extends Light OnlyRenderType = true; private _Target = new Vector3(); protected _ShowHelper = false; + protected _OpenLight = true;//开灯 constructor() { diff --git a/src/DatabaseServices/Lights/HemisphereLight.ts b/src/DatabaseServices/Lights/HemisphereLight.ts index e8ab1f8bb..9e97568a2 100644 --- a/src/DatabaseServices/Lights/HemisphereLight.ts +++ b/src/DatabaseServices/Lights/HemisphereLight.ts @@ -12,6 +12,7 @@ export class HemisphereLight extends Light protected _Intensity = 1; @AutoRecord AutoExposure = false;//自动曝光 @AutoRecord ExposureCompensation = 1;//默认为1 + protected _OpenLight = true;//开灯 get GroundColor() { return this._GroundColor; } diff --git a/src/DatabaseServices/Lights/Light.ts b/src/DatabaseServices/Lights/Light.ts index a0fcd92ba..59637c05f 100644 --- a/src/DatabaseServices/Lights/Light.ts +++ b/src/DatabaseServices/Lights/Light.ts @@ -27,6 +27,8 @@ export class Light extends Entity @AutoRecord SpecularScale = 1;//高光度范围 默认1 (物理) protected _CaseShadow = true;//投射阴影 + protected _OpenLight = Light.DefaultOpenLight;//开灯 + static DefaultOpenLight = false; Clone() { @@ -43,6 +45,15 @@ export class Light extends Entity this.Update(); } + get OpenLight() { return this._OpenLight; } + + set OpenLight(v: boolean) + { + if (v === this._OpenLight) return; + this._OpenLight = v; + this.Update(); + } + //因为有set 所以必须11对应 get Position() { @@ -103,6 +114,7 @@ export class Light extends Entity { en.intensity = this.WebIntensity; en.color = this._LightColor; + en.visible = this.OpenLight; } get Intensity() { diff --git a/src/DatabaseServices/Lights/PointLight.ts b/src/DatabaseServices/Lights/PointLight.ts index 9d034e145..8225318ae 100644 --- a/src/DatabaseServices/Lights/PointLight.ts +++ b/src/DatabaseServices/Lights/PointLight.ts @@ -1,10 +1,11 @@ -import { Light as TLight, Mesh, MeshBasicMaterial, Object3D, PointLight as TPointLight, SphereGeometry } from 'three'; +import { Group, Mesh, MeshBasicMaterial, Object3D, PointLight as TPointLight, SphereGeometry } from 'three'; import { HostApplicationServices } from '../../ApplicationServices/HostApplicationServices'; import { RenderType } from '../../GraphicsSystem/RenderType'; import { AutoRecord } from '../AutoRecord'; import { Factory } from '../CADFactory'; import { CADFiler } from '../CADFiler'; import { Light } from './Light'; +import { PointLightHelper } from './PointLightHelper'; /** * 点光源 @@ -31,6 +32,7 @@ export class PointLight extends Light //LocalLightComponent //Radius:number 没设置这个 @AutoRecord AttenuationRadius = 300; //衰减半径 10-1000 + protected _ShowHelper = true; constructor() { @@ -68,6 +70,7 @@ export class PointLight extends Light protected InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D { + let lightGroup = new Group(); let ptLight = new TPointLight(this._LightColor, this.WebIntensity, this._Distance, this._Decay); ptLight.castShadow = HostApplicationServices.UseShadow; @@ -77,14 +80,29 @@ export class PointLight extends Light let lightGeo = new SphereGeometry(50); let geoMat = new MeshBasicMaterial({ color: this._LightColor }); ptLight.add(new Mesh(lightGeo, geoMat)); - return ptLight; + + let helper = new PointLightHelper(ptLight.distance / 4, this.Color); + + lightGroup.add(ptLight, helper); + lightGroup.matrixAutoUpdate = false; + lightGroup.matrix.copy(this._Matrix); + lightGroup.updateMatrixWorld(true); + this.UpdateDrawObject(renderType, lightGroup); + return lightGroup; } - UpdateDrawObject(type: RenderType, en: TLight) + UpdateDrawObject(type: RenderType, en: Object3D) { - super.UpdateDrawObject(type, en); - let ptLight = en as TPointLight; + let ptLight = en.children[0] as TPointLight; + super.UpdateDrawObject(type, ptLight); + ptLight.distance = this._Distance; ptLight.decay = this._Decay; + + let helper = en.children[1] as PointLightHelper; + helper.visible = this._ShowHelper; + if (this._ShowHelper) + helper.color = this.Color; + helper.update(); } diff --git a/src/DatabaseServices/Lights/PointLightHelper.ts b/src/DatabaseServices/Lights/PointLightHelper.ts new file mode 100644 index 000000000..bb33bcdcc --- /dev/null +++ b/src/DatabaseServices/Lights/PointLightHelper.ts @@ -0,0 +1,96 @@ + +import { BufferGeometry, Color, CylinderBufferGeometry, Float32BufferAttribute, LineBasicMaterial, LineSegments, MathUtils, Matrix4, Mesh, MeshBasicMaterial, Object3D, PointLight, SphereBufferGeometry, Vector3 } from 'three'; + +export class PointLightHelper extends Object3D +{ + light: PointLight; + color: Color | string | number; + material: LineBasicMaterial; + cone: LineSegments[]; + mesh: Mesh[]; + constructor(distance: number, color?: Color | string | number) + { + + const geometry = new BufferGeometry(); + const positions = []; + 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) * distance, Math.sin(p1) * distance, 0, + Math.cos(p2) * distance, Math.sin(p2) * distance, 0 + ); + + } + geometry.setAttribute('position', new Float32BufferAttribute(positions, 3)); + + super(); + this.color = color; + this.matrixAutoUpdate = false; + this.material = new LineBasicMaterial({ fog: false });; + + this.cone = []; + this.mesh = []; + + this.cone[0] = new LineSegments(geometry, this.material[0]); + this.cone[1] = this.cone[0].clone(); + + let moveMatInv = new Matrix4().getInverse(this.matrix); + let roMat = new Matrix4().makeRotationAxis(new Vector3(0, 1, 0), MathUtils.degToRad(60)); + let mtx = this.matrix.clone().multiply(roMat).multiply(moveMatInv); + + this.cone[1].applyMatrix4(mtx); + this.cone[2] = this.cone[1].clone(); + this.cone[2].applyMatrix4(mtx); + + let cylinderRoMat = new Matrix4().makeRotationAxis(new Vector3(1, 0, 0), MathUtils.degToRad(90)); + let cylinderMtx = this.matrix.clone().multiply(cylinderRoMat).multiply(moveMatInv); + + let cylinderGeometry = new CylinderBufferGeometry(40, 40, 80, 32); //灯泡圆柱 + this.mesh[0] = new Mesh(cylinderGeometry, new MeshBasicMaterial({ color: 0xFFEAAD })); + this.mesh[0].applyMatrix4(cylinderMtx); + this.mesh[0].position.add(new Vector3(0, 0, 50)); + this.mesh[0].updateMatrix(); + + let sphereBufferGeometry = new SphereBufferGeometry(75, 32, 32); //灯泡球体 + this.mesh[1] = new Mesh(sphereBufferGeometry, this.material); + this.mesh[1].position.sub(new Vector3(0, 0, 30)); + this.mesh[1].updateMatrix(); + + this.add(this.cone[0], this.cone[1], this.cone[2], this.mesh[0], this.mesh[1]); + } + + dispose() + { + this.material.dispose(); + + this.cone[0].geometry.dispose(); + //@ts-ignore + this.cone[0].material.dispose(); + + this.cone[1].geometry.dispose(); + //@ts-ignore + this.cone[1].material.dispose(); + + this.cone[2].geometry.dispose(); + //@ts-ignore + this.cone[2].material.dispose(); + + this.mesh[0].geometry.dispose(); + //@ts-ignore + this.mesh[0].material.dispose(); + + this.mesh[1].geometry.dispose(); + //@ts-ignore + this.mesh[1].material.dispose(); + } + + update() + { + //@ts-ignore + this.mesh[1].material.color.set(this.color).multiplyScalar(0.9); + } +} diff --git a/src/DatabaseServices/Lights/RectAreaLight.ts b/src/DatabaseServices/Lights/RectAreaLight.ts index c2f523cdc..79e7c2f4d 100644 --- a/src/DatabaseServices/Lights/RectAreaLight.ts +++ b/src/DatabaseServices/Lights/RectAreaLight.ts @@ -29,7 +29,6 @@ export class RectAreaLight extends Light @AutoRecord BarnDoorLength: number = 20;//0-100 挡光板长度 @AutoRecord SourceTexture: ObjectId;//Texture 源纹理 默认无 可以追加一张贴图 protected _ShowHelper = true; - get Target() { return this._Target.clone(); diff --git a/src/Editor/LightsMenu.tsx b/src/Editor/LightsMenu.tsx index 0676c1f22..c3ed712a0 100644 --- a/src/Editor/LightsMenu.tsx +++ b/src/Editor/LightsMenu.tsx @@ -1,5 +1,6 @@ import { Button, Menu, MenuItem, Popover } from "@blueprintjs/core"; +import { observable } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import { app } from "../ApplicationServices/Application"; @@ -7,6 +8,7 @@ import { Entity } from "../DatabaseServices/Entity/Entity"; import { Light } from "../DatabaseServices/Lights/Light"; import { DownPanelStore, LightDataModeType, LightsData } from "../UI/Store/DownPanelStore"; import { CommandWrap } from "./CommandMachine"; +import { userConfig } from "./UserConfig"; /** * 底部状态栏的灯光助手按钮. @@ -14,20 +16,21 @@ import { CommandWrap } from "./CommandMachine"; @observer export class LightsMenu extends React.Component<{ GetLightType: (ent: Entity) => string; }> { - public state = { - isOpenMenu: false, - }; + @observable isOpenMenu = false; + render() { return (