!1657 增强:灯光增加配置

Merge pull request !1657 from 林三/light_config
pull/1691/head
林三 3 years ago committed by ChenX
parent ac7aa6b1c8
commit 981c76b766

@ -1,8 +1,14 @@
import { app } from '../../ApplicationServices/Application'; import { app } from '../../ApplicationServices/Application';
import { EntityUpdateWrap } from '../../Common/EntityUpdateWrap';
import { PointLight } from '../../DatabaseServices/Lights/PointLight'; import { PointLight } from '../../DatabaseServices/Lights/PointLight';
import { Command } from '../../Editor/CommandMachine'; import { Command } from '../../Editor/CommandMachine';
import { JigUtils } from '../../Editor/JigUtils'; import { JigUtils } from '../../Editor/JigUtils';
import { PromptStatus } from '../../Editor/PromptResult'; import { PromptStatus } from '../../Editor/PromptResult';
import { BoardModalType } from '../../UI/Components/Board/BoardModal';
import { ModalState } from '../../UI/Components/Modal/ModalInterface';
import { LightStore, PointLightStore } from '../../UI/Store/RightPanelStore/LightStore';
import { SpotLightModel } from '../../UI/Store/RightPanelStore/SpotLightMOdel';
export class DrawPointLight implements Command export class DrawPointLight implements Command
{ {
async exec() async exec()
@ -40,6 +46,24 @@ export class DrawPointLight2 implements Command
async exec() async exec()
{ {
let light = JigUtils.Draw(new PointLight()); let light = JigUtils.Draw(new PointLight());
let lightStore = LightStore.GetInstance();
lightStore.IsDrawLight = true;
lightStore.InitLightData(light);
let configStore = PointLightStore.GetInstance();
app.Editor.ModalManage.RenderModal(SpotLightModel, { store: lightStore, LightType: BoardModalType.PointLight, configStore: configStore, isNotModify: true });
setTimeout(() =>
{
app.Editor.UpdateScreen();//保证灯光被画出来
}, 30);
let state = await app.Editor.ModalManage.Wait();
if (state.Status !== ModalState.Ok) return;
EntityUpdateWrap(light, () =>
{
light.CaseShadow = lightStore.lightData.CaseShadow;
});
let ptRes = await app.Editor.GetPoint({ let ptRes = await app.Editor.GetPoint({
Msg: "选择点光源位置", Msg: "选择点光源位置",

@ -1,9 +1,14 @@
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { EntityUpdateWrap } from "../../Common/EntityUpdateWrap";
import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight"; import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { JigUtils } from "../../Editor/JigUtils"; import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { midPoint } from "../../Geometry/GeUtils"; import { midPoint } from "../../Geometry/GeUtils";
import { BoardModalType } from "../../UI/Components/Board/BoardModal";
import { ModalState } from "../../UI/Components/Modal/ModalInterface";
import { LightStore, RectAreaLightStore } from "../../UI/Store/RightPanelStore/LightStore";
import { SpotLightModel } from "../../UI/Store/RightPanelStore/SpotLightMOdel";
export class DrawRectAreaLight implements Command export class DrawRectAreaLight implements Command
{ {
@ -13,10 +18,34 @@ export class DrawRectAreaLight implements Command
if (rectRes.Status === PromptStatus.OK) if (rectRes.Status === PromptStatus.OK)
{ {
let light = JigUtils.Draw(new RectAreaLight()); let light = JigUtils.Draw(new RectAreaLight());
light.ApplyMatrix(app.Editor.UCSMatrix);
light.Position = midPoint(rectRes.Point1WCS, rectRes.Point2WCS); EntityUpdateWrap(light, () =>
light.Width = Math.abs(rectRes.Width); {
light.Height = Math.abs(rectRes.Height); light.Width = Math.abs(rectRes.Width);
light.Height = Math.abs(rectRes.Height);
light.ApplyMatrix(app.Editor.UCSMatrix);
light.Position = midPoint(rectRes.Point1WCS, rectRes.Point2WCS);
});
let lightStore = LightStore.GetInstance();
lightStore.IsDrawLight = true;
lightStore.InitLightData(light);
let configStore = RectAreaLightStore.GetInstance();
app.Editor.ModalManage.RenderModal(SpotLightModel, { store: lightStore, LightType: BoardModalType.RectAreaLight, configStore: configStore, isNotModify: true });
setTimeout(() =>
{
app.Editor.UpdateScreen();//保证灯光被画出来
}, 30);
let state = await app.Editor.ModalManage.Wait();
if (state.Status !== ModalState.Ok) return;
EntityUpdateWrap(light, () =>
{
light.CaseShadow = lightStore.lightData.CaseShadow;
light.ShowHelper = lightStore.lightData.ShowHelper;
});
app.Database.Lights.Append(light); app.Database.Lights.Append(light);
} }
} }

@ -1,9 +1,14 @@
import { MathUtils, Matrix4, Vector3 } from "three"; import { MathUtils, Matrix4, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { EntityUpdateWrap } from "../../Common/EntityUpdateWrap";
import { SpotLight } from "../../DatabaseServices/Lights/SpotLight"; import { SpotLight } from "../../DatabaseServices/Lights/SpotLight";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { JigUtils } from "../../Editor/JigUtils"; import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { BoardModalType } from "../../UI/Components/Board/BoardModal";
import { ModalState } from "../../UI/Components/Modal/ModalInterface";
import { LightStore, SpotLightStore } from "../../UI/Store/RightPanelStore/LightStore";
import { SpotLightModel } from "../../UI/Store/RightPanelStore/SpotLightMOdel";
export class DrawSpotLight implements Command export class DrawSpotLight implements Command
{ {
@ -11,18 +16,32 @@ export class DrawSpotLight implements Command
{ {
let mtx = new Matrix4; let mtx = new Matrix4;
let light = JigUtils.Draw(new SpotLight()); let light = JigUtils.Draw(new SpotLight());
let lightStore = LightStore.GetInstance();
lightStore.IsDrawLight = true;
lightStore.InitLightData(light);
let configStore = SpotLightStore.GetInstance();
app.Editor.ModalManage.RenderModal(SpotLightModel, { store: lightStore, LightType: BoardModalType.SpotLight, configStore: configStore, isNotModify: true });
setTimeout(() =>
{
app.Editor.UpdateScreen();//保证灯光被画出来
}, 30);
let state = await app.Editor.ModalManage.Wait();
if (state.Status !== ModalState.Ok) return;
EntityUpdateWrap(light, () =>
{
light.CaseShadow = lightStore.lightData.CaseShadow;
light.ShowHelper = lightStore.lightData.ShowHelper;
});
let ptRes = await app.Editor.GetPoint({ let ptRes = await app.Editor.GetPoint({
Msg: "选择光源位置", Msg: "选择光源位置",
Raycast: true, Callback: p =>
Callback: (p, i) =>
{ {
if (i?.face?.normal) light.Position = p;
{
light.Target = i.face.normal.clone().applyMatrix4(mtx.copy(i.object.matrixWorld).setPosition(0, 0, 0)).multiplyScalar(300).add(p);
light.Position = p.clone().add(i.face.normal.clone().multiplyScalar(10));
}
else
light.Position = p;
} }
}); });
@ -75,6 +94,27 @@ export class DrawSpotLight2 implements Command
async exec() async exec()
{ {
let light = JigUtils.Draw(new SpotLight()); let light = JigUtils.Draw(new SpotLight());
let lightStore = LightStore.GetInstance();
lightStore.IsDrawLight = true;
lightStore.InitLightData(light);
let configStore = SpotLightStore.GetInstance();
app.Editor.ModalManage.RenderModal(SpotLightModel, { store: lightStore, LightType: BoardModalType.SpotLight, configStore: configStore, isNotModify: true });
setTimeout(() =>
{
app.Editor.UpdateScreen();//保证灯光被画出来
}, 30);
let state = await app.Editor.ModalManage.Wait();
if (state.Status !== ModalState.Ok) return;
EntityUpdateWrap(light, () =>
{
light.CaseShadow = lightStore.lightData.CaseShadow;
light.ShowHelper = lightStore.lightData.ShowHelper;
light.ApplyMatrix(app.Editor.UCSMatrix);
});
let ptRes = await app.Editor.GetPoint({ let ptRes = await app.Editor.GetPoint({
Msg: "选择射灯位置", Msg: "选择射灯位置",
Callback: p => this.update(light, p), Callback: p => this.update(light, p),

@ -0,0 +1,10 @@
import { Entity } from "../DatabaseServices/Entity/Entity";
export function EntityUpdateWrap(ent: Entity, exec: Function)
{
let bak = ent.AutoUpdate;
ent.AutoUpdate = false;
exec();
ent.DeferUpdate();
ent.AutoUpdate = bak;
}

@ -24,7 +24,7 @@ export class PointLight extends Light
private _Decay: number = 0.45; private _Decay: number = 0.45;
//PointLightComponent //PointLightComponent
@AutoRecord SourceRadius = 0;//源半径 范围0-300 @AutoRecord SourceRadius = 10;//源半径 范围0-300
@AutoRecord SoftSourceRadius = 0;//软源半径 范围0-300 @AutoRecord SoftSourceRadius = 0;//软源半径 范围0-300
@AutoRecord SourceLength = 0;//源长度 默认0 范围0-1000 @AutoRecord SourceLength = 0;//源长度 默认0 范围0-1000

@ -162,19 +162,15 @@ export class RectAreaLight extends Light
light.color.copy(this.Color); light.color.copy(this.Color);
// light.castShadow = true;//threejs没有支持这个影子 // light.castShadow = true;//threejs没有支持这个影子
if (this._ShowHelper) let help: RectAreaLightHelper;
if (obj.children.length === 1)
{ {
let help: RectAreaLightHelper; help = new RectAreaLightHelper(light, light.color);
if (obj.children.length === 1) obj.add(help);
{
help = new RectAreaLightHelper(light, light.color);
obj.add(help);
}
else
help = obj.children[1] as RectAreaLightHelper;
help.updateMatrixWorld();
} }
else
help = obj.children[1] as RectAreaLightHelper;
help.visible = this._ShowHelper;
} }
protected _ReadFile(file: CADFiler) protected _ReadFile(file: CADFiler)

@ -15,6 +15,7 @@ import { HardwareCompositeEntity } from "../../DatabaseServices/Hardware/Hardwar
import { HardwareTopline } from "../../DatabaseServices/Hardware/HardwareTopline"; import { HardwareTopline } from "../../DatabaseServices/Hardware/HardwareTopline";
import { DirectionalLight } from "../../DatabaseServices/Lights/DirectionalLight"; import { DirectionalLight } from "../../DatabaseServices/Lights/DirectionalLight";
import { Light } from "../../DatabaseServices/Lights/Light"; import { Light } from "../../DatabaseServices/Lights/Light";
import { PointLight } from "../../DatabaseServices/Lights/PointLight";
import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight"; import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight";
import { SpotLight } from "../../DatabaseServices/Lights/SpotLight"; import { SpotLight } from "../../DatabaseServices/Lights/SpotLight";
import { Text } from "../../DatabaseServices/Text/Text"; import { Text } from "../../DatabaseServices/Text/Text";
@ -31,9 +32,10 @@ import { CompositeMatalPanel } from "../../UI/Components/RightPanel/CompositeMet
import { RightTabId } from "../../UI/Components/RightPanel/RightPanel"; import { RightTabId } from "../../UI/Components/RightPanel/RightPanel";
import { ToplineMetalsPanel } from "../../UI/Components/RightPanel/ToplineMetalsPanel"; import { ToplineMetalsPanel } from "../../UI/Components/RightPanel/ToplineMetalsPanel";
import { AppToaster } from "../../UI/Components/Toaster"; import { AppToaster } from "../../UI/Components/Toaster";
import { IConfigStore } from "../../UI/Store/BoardStore";
import { EntityStore } from "../../UI/Store/EntityStore"; import { EntityStore } from "../../UI/Store/EntityStore";
import { compositeMetalsOptionStore, toplineMetalsStore } from "../../UI/Store/RightPanelStore/HardwareStore"; import { compositeMetalsOptionStore, toplineMetalsStore } from "../../UI/Store/RightPanelStore/HardwareStore";
import { LightStore } from "../../UI/Store/RightPanelStore/LightStore"; import { LightStore, PointLightStore, RectAreaLightStore, SpotLightStore } from "../../UI/Store/RightPanelStore/LightStore";
import { RightPanelStore } from "../../UI/Store/RightPanelStore/RightPanelStore"; import { RightPanelStore } from "../../UI/Store/RightPanelStore/RightPanelStore";
import { SpotLightModel } from "../../UI/Store/RightPanelStore/SpotLightMOdel"; import { SpotLightModel } from "../../UI/Store/RightPanelStore/SpotLightMOdel";
import { CommandWrap } from "../CommandMachine"; import { CommandWrap } from "../CommandMachine";
@ -79,6 +81,15 @@ export class DbClickManager extends Singleton
if (pickEnt instanceof Light) if (pickEnt instanceof Light)
{ {
const width = 500;
const height = 500;
let lightStore = LightStore.GetInstance();
lightStore.IsDrawLight = false;
lightStore.InitLightData(pickEnt);
let lightType: BoardModalType;
let configStore: IConfigStore;
if (pickEnt instanceof DirectionalLight) if (pickEnt instanceof DirectionalLight)
{ {
let rightStore = RightPanelStore.GetInstance(); let rightStore = RightPanelStore.GetInstance();
@ -86,17 +97,27 @@ export class DbClickManager extends Singleton
rightStore.m_TabId = RightTabId.Scene; rightStore.m_TabId = RightTabId.Scene;
return; return;
} }
const width = 500; else if (pickEnt instanceof SpotLight)
const height = 500; {
let lightStore = LightStore.GetInstance(); lightType = BoardModalType.SpotLight;
lightStore.InitLightData(pickEnt); configStore = SpotLightStore.GetInstance();
let isPointLight = pickEnt instanceof SpotLight || pickEnt instanceof RectAreaLight; }
else if (pickEnt instanceof RectAreaLight)
{
lightType = BoardModalType.RectAreaLight;
configStore = RectAreaLightStore.GetInstance();
}
else if (pickEnt instanceof PointLight)
{
lightType = BoardModalType.PointLight;
configStore = PointLightStore.GetInstance();
}
let p = app.Viewer.WorldToScreen(pickEnt.Position); let p = app.Viewer.WorldToScreen(pickEnt.Position);
CADModal.ModalOldPosition.left = `${Math.min(p.x + app.Viewer.canvasContainer.offsetLeft + 10, window.innerWidth - width)}px`; CADModal.ModalOldPosition.left = `${Math.min(p.x + app.Viewer.canvasContainer.offsetLeft + 10, window.innerWidth - width)}px`;
CADModal.ModalOldPosition.top = `${Math.min(p.y + app.Viewer.canvasContainer.offsetTop + 10, window.innerHeight - height)}px`; CADModal.ModalOldPosition.top = `${Math.min(p.y + app.Viewer.canvasContainer.offsetTop + 10, window.innerHeight - height)}px`;
app.Editor.ModalManage.RenderModeless(SpotLightModel, app.Editor.ModalManage.RenderModeless(SpotLightModel,
{ store: lightStore, isPointLight: isPointLight }, { position: ModalPosition.Old }); { store: lightStore, configStore: configStore, LightType: lightType }, { position: ModalPosition.Old });
} }
else if (pickEnt instanceof Text) else if (pickEnt instanceof Text)
{ {

@ -5,7 +5,7 @@ import { IUpdateBoardInfosOption } from "../UI/Components/Board/UpdateBoardInfoi
import { EMetalsType, ICompHardwareOption, ICylMetalsOption, IExtMetalsOption, IToplineOption } from "../UI/Components/RightPanel/RightPanelInterface"; import { EMetalsType, ICompHardwareOption, ICylMetalsOption, IExtMetalsOption, IToplineOption } from "../UI/Components/RightPanel/RightPanelInterface";
import { IKuGangDrawOption } from "../UI/Components/Template/TemplateInterface"; import { IKuGangDrawOption } from "../UI/Components/Template/TemplateInterface";
import { ECompareType, IBoardFindOption } from "../UI/Store/BoardFindInterface"; import { ECompareType, IBoardFindOption } from "../UI/Store/BoardFindInterface";
import { BehindBoardOption, BehindHeightPositon, BoardProcessOption, BoardType, BrRelativePos, ClosingStripOption, ComposingType, CurtailType, FaceDirection, IBatchModifyPanelOption, IBoardBatchCurtailOption, LayerBoardOption, LayerNailOption, LinesType, ModifyTextsConfigOption, PointLightOption, RadioType, SideBoardOption, SingleBoardOption, StripType, TBBoardOption, VerticalBoardOption, Viewport2ConfigOption, Viewport3ConfigOption, Viewport4ConfigOption, ViewportConfigOption } from "../UI/Store/BoardInterface"; import { BehindBoardOption, BehindHeightPositon, BoardProcessOption, BoardType, BrRelativePos, ClosingStripOption, ComposingType, CurtailType, FaceDirection, IBatchModifyPanelOption, IBoardBatchCurtailOption, LayerBoardOption, LayerNailOption, LinesType, ModifyTextsConfigOption, PointLightOption, RadioType, RectAreaLightOption, RightPlaneLightOption, SideBoardOption, SingleBoardOption, SpotLightOption, StripType, TBBoardOption, VerticalBoardOption, Viewport2ConfigOption, Viewport3ConfigOption, Viewport4ConfigOption, ViewportConfigOption } from "../UI/Store/BoardInterface";
import { DoorPosType, HandleHorPos, HandleVePos, IDoorConfigOption, IDrawerConfigOption } from "../UI/Store/DoorInterface"; import { DoorPosType, HandleHorPos, HandleVePos, IDoorConfigOption, IDrawerConfigOption } from "../UI/Store/DoorInterface";
import { IHSOption } from "../UI/Store/HSInterface"; import { IHSOption } from "../UI/Store/HSInterface";
import { ELatticeArrayType, ILatticeOption } from "../UI/Store/LatticeInterface"; import { ELatticeArrayType, ILatticeOption } from "../UI/Store/LatticeInterface";
@ -188,22 +188,75 @@ export const DefaultModifyTextsOption: ModifyTextsConfigOption = {
}; };
Object.freeze(DefaultModifyTextsOption); Object.freeze(DefaultModifyTextsOption);
export const DefaultPointLightOption: PointLightOption = { export const DefaultPointLightOption: PointLightOption = {
version: 1, version: 1,
distance: 5000,
intensity: 100,
lightColor: "#FFFFFF", lightColor: "#FFFFFF",
temperature: 6500, temperature: 6500,
indirectLightingIntensity: 1, Intensity: 100,
showHelper: true, IndirectLightingIntensity: 1,
specularScale: 1, SpecularScale: 1,
caseShado: true, SourceRadius: 10,
sourceRadius: 0, SoftSourceRadius: 0,
softSourceRadius: 0, SourceLength: 0,
sourceLength: 0, CaseShadow: true,
}; };
Object.freeze(DefaultPointLightOption); Object.freeze(DefaultPointLightOption);
export const DefaultSpotLightOption: SpotLightOption = {
version: 1,
lightColor: "#FFFFFF",
temperature: 6500,
Intensity: 100,
IndirectLightingIntensity: 1,
SpecularScale: 1,
SourceRadius: 0,
SoftSourceRadius: 0,
SourceLength: 0,
Angle: 40,
InnerConeAngle: 0,
AttenuationRadius: 300,
CaseShadow: true,
ShowHelper: true,
};
Object.freeze(DefaultSpotLightOption);
export const DefaultRectAreaLightOption: RectAreaLightOption = {
version: 1,
lightColor: "#FFFFFF",
temperature: 6500,
Intensity: 100,
IndirectLightingIntensity: 1,
SpecularScale: 1,
AttenuationRadius: 300,
Width: 150,
Height: 150,
BarnDoorAngle: 90,
BarnDoorLength: 20,
CaseShadow: true,
ShowHelper: true,
};
Object.freeze(DefaultRectAreaLightOption);
export const DefaultRightPlaneLightOption: RightPlaneLightOption = {
version: 1,
ShowHemiLight: true,
ShowSunLight: true,
SkyLightColor: "#FFFFFF",
SkyLightIntensity: 1,
SkyLightIndirectLightingIntensity: 1,
SunLightIntensity: 50,
SunLightIndirectLightingIntensity: 1,
SunLightColor: "#FFFFFF",
SunLightTemperature: 6500,
SunLightElevationDeg: 60,
SunLightRotateDeg: 300,
ShowExposure: true,
AutoExposure: false,
ExposureCompensation: 0
};
Object.freeze(DefaultRightPlaneLightOption);
export const DefaultSingleBoardOption: SingleBoardOption = { export const DefaultSingleBoardOption: SingleBoardOption = {
version: 1, version: 1,
name: "层板", name: "层板",

@ -63,6 +63,9 @@ export enum BoardModalType
AutoHoleFaceSetting = "AutoHoleFaceSetting",//自动孔面设置 AutoHoleFaceSetting = "AutoHoleFaceSetting",//自动孔面设置
EditViewSetting = "EditViewSetting",//编辑视口配置 EditViewSetting = "EditViewSetting",//编辑视口配置
PointLight = "PointLight",//点灯光配置 PointLight = "PointLight",//点灯光配置
SpotLight = "SpotLight",//射灯配置
RectAreaLight = "RectAreaLight",//矩形灯配置
RightPlaneLight = "RightPlaneLight",//右侧栏灯光配置
} }
export interface BoardModalProps export interface BoardModalProps
{ {

@ -45,6 +45,7 @@ interface IConfigProps
store: IConfigStore; store: IConfigStore;
isUpdate?: boolean; isUpdate?: boolean;
isExpImp?: boolean; isExpImp?: boolean;
isNotModify?: boolean; //是否显示保存和删除配置按钮
otherConfig?: () => AnyObject; otherConfig?: () => AnyObject;
configurationType?: string; configurationType?: string;
} }
@ -117,6 +118,10 @@ export class UserConfig extends React.Component<IConfigProps, {}>{
if (!this.props.isUpdate) if (!this.props.isUpdate)
{ {
if (confNames.length === 0)
{
await this.handleInitConfig();
}
this.props.store.configName = ""; this.props.store.configName = "";
return; return;
} }
@ -188,22 +193,26 @@ export class UserConfig extends React.Component<IConfigProps, {}>{
></Button>} /> ></Button>} />
} }
/> />
<Button {
text="保存" !this.props.isNotModify && <>
intent={Intent.SUCCESS} <Button
onClick={async () => text="保存"
{ intent={Intent.SUCCESS}
await this.handleSaveConfig(); onClick={async () =>
}} {
/> await this.handleSaveConfig();
<Button }}
text="删除" />
intent={Intent.DANGER} <Button
onClick={async () => text="删除"
{ intent={Intent.DANGER}
await this.handleDeleteConfig(); onClick={async () =>
}} {
/> await this.handleDeleteConfig();
}}
/>
</>
}
{ {
this.props.isExpImp && <> this.props.isExpImp && <>
<PopoverInput <PopoverInput

@ -10,8 +10,10 @@ import { Light } from '../../../DatabaseServices/Lights/Light';
import { CommandWrap } from '../../../Editor/CommandMachine'; import { CommandWrap } from '../../../Editor/CommandMachine';
import { userConfig } from '../../../Editor/UserConfig'; import { userConfig } from '../../../Editor/UserConfig';
import { equalv3 } from '../../../Geometry/GeUtils'; import { equalv3 } from '../../../Geometry/GeUtils';
import { ETime } from '../../Store/RightPanelStore/LightStore'; import { ETime, RightPlaneLightStore } from '../../Store/RightPanelStore/LightStore';
import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore'; import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore';
import { BoardModalType } from '../Board/BoardModal';
import { UserConfig } from '../Board/UserConfig';
import { LightDataCom } from '../Modal/LightModal'; import { LightDataCom } from '../Modal/LightModal';
import { ExposureUI } from './ExposureUI'; import { ExposureUI } from './ExposureUI';
import { SunLightStore } from './SunLightStore'; import { SunLightStore } from './SunLightStore';
@ -23,6 +25,8 @@ export const DefaultDist = { dist: 10000 };
@observer @observer
export class ScenePanel extends React.Component<{ store?: RightPanelStore; }, {}> export class ScenePanel extends React.Component<{ store?: RightPanelStore; }, {}>
{ {
_ConfigStore: RightPlaneLightStore;
UNSAFE_componentWillMount() UNSAFE_componentWillMount()
{ {
this.props.store.lightStore.InitLightData(app.Database.HemisphereLight); this.props.store.lightStore.InitLightData(app.Database.HemisphereLight);
@ -34,6 +38,7 @@ export class ScenePanel extends React.Component<{ store?: RightPanelStore; }, {}
const lightStore = this.props.store.lightStore; const lightStore = this.props.store.lightStore;
lightStore.InitSunLightData(); lightStore.InitSunLightData();
} }
this._ConfigStore = RightPlaneLightStore.GetInstance();
} }
render() render()
{ {
@ -111,6 +116,11 @@ export class ScenePanel extends React.Component<{ store?: RightPanelStore; }, {}
<ExposureUI store={lightStore} /> <ExposureUI store={lightStore} />
</div> </div>
<Divider /> <Divider />
<UserConfig
store={this._ConfigStore}
type={BoardModalType.RightPlaneLight}
isUpdate={false}
/>
</div > </div >
); );
} }

@ -495,8 +495,8 @@ export default class SunLightGui extends Component
<div className='sun-colortemp'> <div className='sun-colortemp'>
<img alt='色温' draggable={false} src={`${ResourcesCDN_HOST}/colortemperature.webp`} /> <img alt='色温' draggable={false} src={`${ResourcesCDN_HOST}/colortemperature.webp`} />
<Slider <Slider
min={1800} min={1700}
max={16000} max={12000}
stepSize={1} stepSize={1}
labelStepSize={1775} labelStepSize={1775}
showTrackFill={false} showTrackFill={false}

@ -1189,4 +1189,11 @@ img {
} }
} }
} }
.bp3-dialog-footer
{
padding: 7px 10px 7px 10px;
border-top: 1px solid #dddddd;
background-color: white;
}
} }

@ -133,22 +133,59 @@ export interface BoardConfigOption extends IBaseOption
export interface LightConfigOption extends IBaseOption export interface LightConfigOption extends IBaseOption
{ {
distance: number; Intensity: number;
intensity: number;
lightColor: string; lightColor: string;
temperature: number; temperature: number;
indirectLightingIntensity: number; IndirectLightingIntensity: number;
showHelper: boolean; SpecularScale: number;
specularScale: number; CaseShadow: boolean;
caseShado: boolean;
} }
export interface PointLightOption extends LightConfigOption export interface PointLightOption extends LightConfigOption
{ {
sourceRadius: number; SourceRadius: number;
softSourceRadius: number; SoftSourceRadius: number;
sourceLength: number; SourceLength: number;
}
export interface SpotLightOption extends LightConfigOption
{
Angle: number;
InnerConeAngle: number;
SourceRadius: number;
SoftSourceRadius: number;
SourceLength: number;
AttenuationRadius: number;
ShowHelper: boolean;
}
export interface RectAreaLightOption extends LightConfigOption
{
Width: number;
Height: number;
BarnDoorAngle: number;
BarnDoorLength: number;
AttenuationRadius: number;
ShowHelper: boolean;
}
export interface RightPlaneLightOption
{
version: number;
ShowHemiLight: boolean;
SkyLightColor: string;
SkyLightIntensity: number;
SkyLightIndirectLightingIntensity: number;
ShowSunLight: boolean;
SunLightIntensity: number;
SunLightIndirectLightingIntensity: number;
SunLightColor: string;
SunLightTemperature: number;
SunLightElevationDeg: number;
SunLightRotateDeg: number;
ShowExposure: boolean;
AutoExposure: boolean;
ExposureCompensation: number;
} }
export interface ModifyTextsConfigOption export interface ModifyTextsConfigOption

@ -1,8 +1,11 @@
import { observable } from "mobx"; import { observable, toJS } from "mobx";
import { DirectionalLight as TDirectionalLight, MathUtils, PointLight as TPointLight, SpotLight as TSpotLight } from 'three'; import { Color, DirectionalLight as TDirectionalLight, MathUtils, Matrix4, PointLight as TPointLight, SpotLight as TSpotLight, Vector3 } from "three";
import { end } from "xaop"; import { end } from "xaop";
import { Entitys2Data } from "../../../Add-on/ExportData";
import { app } from "../../../ApplicationServices/Application"; import { app } from "../../../ApplicationServices/Application";
import { HostApplicationServices } from "../../../ApplicationServices/HostApplicationServices"; import { HostApplicationServices } from "../../../ApplicationServices/HostApplicationServices";
import { EntityUpdateWrap } from "../../../Common/EntityUpdateWrap";
import { safeEval } from "../../../Common/eval";
import { DirLightShadowArea } from "../../../Common/LightUtils"; import { DirLightShadowArea } from "../../../Common/LightUtils";
import { FixedNotZero } from "../../../Common/Utils"; import { FixedNotZero } from "../../../Common/Utils";
import { CommandHistoryRecord } from "../../../DatabaseServices/CommandHistoryRecord"; import { CommandHistoryRecord } from "../../../DatabaseServices/CommandHistoryRecord";
@ -15,9 +18,14 @@ import { RectAreaLight } from "../../../DatabaseServices/Lights/RectAreaLight";
import { SpotLight } from "../../../DatabaseServices/Lights/SpotLight"; import { SpotLight } from "../../../DatabaseServices/Lights/SpotLight";
import { ObjectId } from "../../../DatabaseServices/ObjectId"; import { ObjectId } from "../../../DatabaseServices/ObjectId";
import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecord"; import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecord";
import { CommandWrap } from "../../../Editor/CommandMachine";
import { DefaultPointLightOption, DefaultRectAreaLightOption, DefaultRightPlaneLightOption, DefaultSpotLightOption } from "../../../Editor/DefaultConfig";
import { userConfig } from "../../../Editor/UserConfig";
import { angle, equalv3, ZeroVec } from "../../../Geometry/GeUtils"; import { angle, equalv3, ZeroVec } from "../../../Geometry/GeUtils";
import { IConfigOption } from "../../Components/Board/UserConfig"; import { IConfigOption } from "../../Components/Board/UserConfig";
import { AnyObject } from "../BoardInterface"; import { DefaultDist } from "../../Components/RightPanel/ScenePanel";
import { SunLightStore } from "../../Components/RightPanel/SunLightStore";
import { AnyObject, PointLightOption, RectAreaLightOption, RightPlaneLightOption, SpotLightOption } from "../BoardInterface";
import { IConfigStore } from "../BoardStore"; import { IConfigStore } from "../BoardStore";
export interface LightModalState export interface LightModalState
@ -54,6 +62,8 @@ export interface LightModalState
AttenuationRadius?: string;//射灯衰减半径 AttenuationRadius?: string;//射灯衰减半径
BarnDoorAngle?: string;//挡光板角度 BarnDoorAngle?: string;//挡光板角度
BarnDoorLength?: string;//挡光板长度 BarnDoorLength?: string;//挡光板长度
ShowHelper?: boolean;//灯光助手
CaseShadow?: boolean;//阴影
} }
export enum ETime export enum ETime
{ {
@ -75,6 +85,7 @@ export class LightStore implements IConfigStore
InitConfigs?: () => { [key: string]: IConfigOption<AnyObject>; }; InitConfigs?: () => { [key: string]: IConfigOption<AnyObject>; };
GetOtherConfig?: (conf: any) => AnyObject; GetOtherConfig?: (conf: any) => AnyObject;
HandleImportConfig?: (conf: any) => void; HandleImportConfig?: (conf: any) => void;
@observable IsDrawLight = false; //控制绘制灯时不更新light实体属性
@observable ShowAmbientLight = true; @observable ShowAmbientLight = true;
@observable ShowSunLight = true; @observable ShowSunLight = true;
@observable ShowHemiLight = true; @observable ShowHemiLight = true;
@ -125,7 +136,7 @@ export class LightStore implements IConfigStore
Intensity: app.Database.SunLight.Intensity.toString(), Intensity: app.Database.SunLight.Intensity.toString(),
IndirectLightingIntensity: app.Database.SunLight.IndirectLightingIntensity.toString(), IndirectLightingIntensity: app.Database.SunLight.IndirectLightingIntensity.toString(),
Rotation: equalv3(vec, ZeroVec) ? "0" : FixedNotZero(MathUtils.radToDeg(angle(vec)), 0), Rotation: equalv3(vec, ZeroVec) ? "0" : FixedNotZero(MathUtils.radToDeg(angle(vec)), 0),
Elevation: equalv3(vec, ZeroVec) ? "0" : FixedNotZero(MathUtils.radToDeg(vec.angleTo(vec2)), 0) Elevation: equalv3(vec, ZeroVec) ? "0" : FixedNotZero(MathUtils.radToDeg(vec.angleTo(vec2)), 0),
}); });
} }
InitLightData(light: Light) InitLightData(light: Light)
@ -145,6 +156,8 @@ export class LightStore implements IConfigStore
IndirectLightingIntensity: light.IndirectLightingIntensity.toString(), IndirectLightingIntensity: light.IndirectLightingIntensity.toString(),
SpecularScale: light.SpecularScale.toString(), SpecularScale: light.SpecularScale.toString(),
Temperature: light.Temperature.toString(), Temperature: light.Temperature.toString(),
CaseShadow: light.CaseShadow,
ShowHelper: light.ShowHelper,
}; };
this.pars.length = 0; this.pars.length = 0;
} }
@ -276,3 +289,404 @@ export class LightStore implements IConfigStore
DirLightShadowArea(app.Database.SunLight); DirLightShadowArea(app.Database.SunLight);
} }
} }
export class PointLightStore implements IConfigStore
{
@observable configName = "默认";
SaveConfig()
{
let lightStore = LightStore.GetInstance();
this.m_Option.CaseShadow = lightStore.lightData.CaseShadow;
this.m_Option.Intensity = parseInt(lightStore.lightData.Intensity);
this.m_Option.lightColor = lightStore.lightData.Color;
this.m_Option.temperature = parseInt(lightStore.lightData.Temperature);
this.m_Option.IndirectLightingIntensity = parseInt(lightStore.lightData.IndirectLightingIntensity);
this.m_Option.SpecularScale = parseFloat(lightStore.lightData.SpecularScale);
this.m_Option.SoftSourceRadius = parseInt(lightStore.lightData.SoftSourceRadius);
this.m_Option.SourceLength = parseInt(lightStore.lightData.SourceLength);
this.m_Option.SourceRadius = parseInt(lightStore.lightData.SourceRadius);
//新的配置
let newConfig: IConfigOption = {};
newConfig.option = toJS(this.m_Option);
return newConfig;
};
//板数据
@observable m_Option: PointLightOption = { ...DefaultPointLightOption };
@observable configsNames: string[] = [];
InitOption()
{
Object.assign(this.m_Option, DefaultPointLightOption);
}
InitConfigs()
{
let config: IConfigOption = {};
config.option = toJS(this.m_Option);
let configs: { [key: string]: IConfigOption; } = {};
configs["默认"] = config;
return configs;
}
async UpdateOption(cof: IConfigOption<PointLightOption>)
{
Object.assign(this.m_Option, cof.option);
let lightStore = LightStore.GetInstance();
lightStore.lightData.Intensity = cof.option.Intensity.toString();
lightStore.lightData.Color = cof.option.lightColor;
lightStore.lightData.Temperature = cof.option.temperature.toString();
lightStore.lightData.IndirectLightingIntensity = cof.option.IndirectLightingIntensity.toString();
lightStore.lightData.SpecularScale = cof.option.SpecularScale.toString();
lightStore.lightData.SoftSourceRadius = cof.option.SoftSourceRadius.toString();
lightStore.lightData.SourceLength = cof.option.SourceLength.toString();
lightStore.lightData.SourceRadius = cof.option.SourceRadius.toString();
lightStore.lightData.CaseShadow = cof.option.CaseShadow;
let pointLight = lightStore.currentSelectEnt as PointLight;
if (!lightStore.IsDrawLight)
{
await CommandWrap(() =>
{
this.updatePointLight(pointLight, cof);
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([pointLight])));
}, "应用点光源配置");
pointLight.Update();
}
else
{
this.updatePointLight(pointLight, cof);
app.Viewer.UpdateRender();
}
}
private static _SingleInstance: PointLightStore;
static GetInstance(): PointLightStore
{
if (this._SingleInstance) return this._SingleInstance;
this._SingleInstance = new PointLightStore;
return this._SingleInstance;
}
private updatePointLight(pointLight: PointLight, cof: IConfigOption<PointLightOption>)
{
EntityUpdateWrap(pointLight, () =>
{
pointLight.Intensity = cof.option.Intensity;
pointLight.Color = new Color(cof.option.lightColor);
pointLight.Temperature = cof.option.temperature;
pointLight.IndirectLightingIntensity = cof.option.IndirectLightingIntensity;
pointLight.SpecularScale = cof.option.SpecularScale;
pointLight.SoftSourceRadius = cof.option.SoftSourceRadius;
pointLight.SourceLength = cof.option.SourceLength;
pointLight.SourceRadius = cof.option.SourceRadius;
pointLight.CaseShadow = cof.option.CaseShadow;
});
}
}
export class SpotLightStore implements IConfigStore
{
@observable configName = "默认";
SaveConfig()
{
let lightStore = LightStore.GetInstance();
this.m_Option.CaseShadow = lightStore.lightData.CaseShadow;
this.m_Option.Intensity = parseInt(lightStore.lightData.Intensity);
this.m_Option.lightColor = lightStore.lightData.Color;
this.m_Option.temperature = parseInt(lightStore.lightData.Temperature);
this.m_Option.IndirectLightingIntensity = parseInt(lightStore.lightData.IndirectLightingIntensity);
this.m_Option.SpecularScale = parseFloat(lightStore.lightData.SpecularScale);
this.m_Option.Angle = parseInt(lightStore.lightData.Angle);
this.m_Option.InnerConeAngle = parseInt(lightStore.lightData.InnerConeAngle);
this.m_Option.SoftSourceRadius = parseInt(lightStore.lightData.SoftSourceRadius);
this.m_Option.SourceLength = parseInt(lightStore.lightData.SourceLength);
this.m_Option.SourceRadius = parseInt(lightStore.lightData.SourceRadius);
this.m_Option.AttenuationRadius = parseInt(lightStore.lightData.AttenuationRadius);
this.m_Option.ShowHelper = lightStore.lightData.ShowHelper;
//新的配置
let newConfig: IConfigOption = {};
newConfig.option = toJS(this.m_Option);
return newConfig;
};
@observable m_Option: SpotLightOption = { ...DefaultSpotLightOption };
@observable configsNames: string[] = [];
InitOption()
{
Object.assign(this.m_Option, DefaultSpotLightOption);
}
InitConfigs()
{
let config: IConfigOption = {};
config.option = toJS(this.m_Option);
let configs: { [key: string]: IConfigOption; } = {};
configs["默认"] = config;
return configs;
}
async UpdateOption(cof: IConfigOption<SpotLightOption>)
{
Object.assign(this.m_Option, cof.option);
let lightStore = LightStore.GetInstance();
lightStore.lightData.Intensity = cof.option.Intensity.toString();
lightStore.lightData.Color = cof.option.lightColor;
lightStore.lightData.Temperature = cof.option.temperature.toString();
lightStore.lightData.IndirectLightingIntensity = cof.option.IndirectLightingIntensity.toString();
lightStore.lightData.SpecularScale = cof.option.SpecularScale.toString();
lightStore.lightData.Angle = cof.option.Angle.toString();
lightStore.lightData.InnerConeAngle = cof.option.InnerConeAngle.toString();
lightStore.lightData.SoftSourceRadius = cof.option.SoftSourceRadius.toString();
lightStore.lightData.SourceLength = cof.option.SourceLength.toString();
lightStore.lightData.SourceRadius = cof.option.SourceRadius.toString();
lightStore.lightData.AttenuationRadius = cof.option.AttenuationRadius.toString();
lightStore.lightData.CaseShadow = cof.option.CaseShadow;
lightStore.lightData.ShowHelper = cof.option.ShowHelper;
let spotLight = lightStore.currentSelectEnt as SpotLight;
if (!lightStore.IsDrawLight)
{
await CommandWrap(() =>
{
this.updateSpotLight(spotLight, cof);
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([spotLight])));
}, "应用射灯配置");
}
else
{
this.updateSpotLight(spotLight, cof);
app.Viewer.UpdateRender();
}
}
private static _SingleInstance: SpotLightStore;
static GetInstance(): SpotLightStore
{
if (this._SingleInstance) return this._SingleInstance;
this._SingleInstance = new SpotLightStore;
return this._SingleInstance;
}
private updateSpotLight(spotLight: SpotLight, cof: IConfigOption<SpotLightOption>)
{
EntityUpdateWrap(spotLight, () =>
{
spotLight.Intensity = cof.option.Intensity;
spotLight.Color = new Color(cof.option.lightColor);
spotLight.Temperature = cof.option.temperature;
spotLight.IndirectLightingIntensity = cof.option.IndirectLightingIntensity;
spotLight.SpecularScale = cof.option.SpecularScale;
spotLight.Angle = MathUtils.degToRad(cof.option.Angle);
spotLight.InnerConeAngle = cof.option.InnerConeAngle;
spotLight.SoftSourceRadius = cof.option.SoftSourceRadius;
spotLight.SourceLength = cof.option.SourceLength;
spotLight.SourceRadius = cof.option.SourceRadius;
spotLight.AttenuationRadius = cof.option.AttenuationRadius;
spotLight.CaseShadow = cof.option.CaseShadow;
spotLight.ShowHelper = cof.option.ShowHelper;
});
}
}
export class RectAreaLightStore implements IConfigStore
{
@observable configName = "默认";
SaveConfig()
{
let lightStore = LightStore.GetInstance();
this.m_Option.CaseShadow = lightStore.lightData.CaseShadow;
this.m_Option.Intensity = parseInt(lightStore.lightData.Intensity);
this.m_Option.lightColor = lightStore.lightData.Color;
this.m_Option.temperature = parseInt(lightStore.lightData.Temperature);
this.m_Option.IndirectLightingIntensity = parseInt(lightStore.lightData.IndirectLightingIntensity);
this.m_Option.SpecularScale = parseFloat(lightStore.lightData.SpecularScale);
this.m_Option.Width = parseFloat(lightStore.lightData.Width);
this.m_Option.Height = parseFloat(lightStore.lightData.Height);
this.m_Option.BarnDoorAngle = parseInt(lightStore.lightData.BarnDoorAngle);
this.m_Option.BarnDoorLength = parseInt(lightStore.lightData.BarnDoorLength);
this.m_Option.AttenuationRadius = parseInt(lightStore.lightData.AttenuationRadius);
this.m_Option.ShowHelper = lightStore.lightData.ShowHelper;
//新的配置
let newConfig: IConfigOption = {};
newConfig.option = toJS(this.m_Option);
return newConfig;
};
@observable m_Option: RectAreaLightOption = { ...DefaultRectAreaLightOption };
@observable configsNames: string[] = [];
InitOption()
{
Object.assign(this.m_Option, DefaultRectAreaLightOption);
}
InitConfigs()
{
let config: IConfigOption = {};
config.option = toJS(this.m_Option);
let configs: { [key: string]: IConfigOption; } = {};
configs["默认"] = config;
return configs;
}
async UpdateOption(cof: IConfigOption<RectAreaLightOption>)
{
Object.assign(this.m_Option, cof.option);
let lightStore = LightStore.GetInstance();
lightStore.lightData.Intensity = cof.option.Intensity.toString();
lightStore.lightData.Color = cof.option.lightColor;
lightStore.lightData.Temperature = cof.option.temperature.toString();
lightStore.lightData.IndirectLightingIntensity = cof.option.IndirectLightingIntensity.toString();
lightStore.lightData.SpecularScale = cof.option.SpecularScale.toString();
lightStore.lightData.BarnDoorAngle = cof.option.BarnDoorAngle.toString();
lightStore.lightData.BarnDoorLength = cof.option.BarnDoorLength.toString();
lightStore.lightData.AttenuationRadius = cof.option.AttenuationRadius.toString();
lightStore.lightData.CaseShadow = cof.option.CaseShadow;
lightStore.lightData.ShowHelper = cof.option.ShowHelper;
lightStore.lightData.Height = cof.option.Height.toString();
lightStore.lightData.Width = cof.option.Width.toString();
let rectAreaLight = lightStore.currentSelectEnt as RectAreaLight;
if (!lightStore.IsDrawLight)
{
await CommandWrap(() =>
{
this.updateRectAreaLight(rectAreaLight, cof);
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([rectAreaLight])));
}, "应用矩形光配置");
}
else
{
this.updateRectAreaLight(rectAreaLight, cof);
app.Viewer.UpdateRender();
}
}
private static _SingleInstance: RectAreaLightStore;
static GetInstance(): RectAreaLightStore
{
if (this._SingleInstance) return this._SingleInstance;
this._SingleInstance = new RectAreaLightStore;
return this._SingleInstance;
}
private updateRectAreaLight(rectAreaLight: RectAreaLight, cof: IConfigOption<RectAreaLightOption>)
{
EntityUpdateWrap(rectAreaLight, () =>
{
rectAreaLight.Intensity = cof.option.Intensity;
rectAreaLight.Color = new Color(cof.option.lightColor);
rectAreaLight.Temperature = cof.option.temperature;
rectAreaLight.IndirectLightingIntensity = cof.option.IndirectLightingIntensity;
rectAreaLight.SpecularScale = cof.option.SpecularScale;
rectAreaLight.Width = cof.option.Width;
rectAreaLight.Height = cof.option.Height;
rectAreaLight.BarnDoorAngle = cof.option.BarnDoorAngle;
rectAreaLight.BarnDoorLength = cof.option.BarnDoorLength;
rectAreaLight.AttenuationRadius = cof.option.AttenuationRadius;
rectAreaLight.CaseShadow = cof.option.CaseShadow;
rectAreaLight.ShowHelper = cof.option.ShowHelper;
});
}
}
export class RightPlaneLightStore implements IConfigStore
{
@observable configName = "默认";
SaveConfig()
{
let lightStore = LightStore.GetInstance();
let sunLightStore = SunLightStore.GetInstance();
this.m_Option.ShowHemiLight = lightStore.ShowHemiLight;
this.m_Option.ShowSunLight = lightStore.ShowSunLight;
this.m_Option.SkyLightColor = lightStore.hemisphereLightData.Color;
this.m_Option.SkyLightIntensity = parseInt(lightStore.hemisphereLightData.Intensity);
this.m_Option.SkyLightIndirectLightingIntensity = parseInt(lightStore.hemisphereLightData.IndirectLightingIntensity);
this.m_Option.SunLightIntensity = sunLightStore.sunLightIntensity;
this.m_Option.SunLightIndirectLightingIntensity = sunLightStore.sunLightIndirectLightingIntensity;
this.m_Option.SunLightColor = sunLightStore.sunLightColor;
this.m_Option.SunLightTemperature = sunLightStore.sunLightColorTemperature;
this.m_Option.SunLightElevationDeg = sunLightStore.sunLightElevationDeg;
this.m_Option.SunLightRotateDeg = sunLightStore.sunLightRotateDeg;
this.m_Option.ShowExposure = lightStore.ShowExposure;
this.m_Option.AutoExposure = lightStore.hemisphereLightData.AutoExposure;
this.m_Option.ExposureCompensation = parseInt(lightStore.hemisphereLightData.ExposureCompensation);
//新的配置
let newConfig: IConfigOption = {};
newConfig.option = toJS(this.m_Option);
return newConfig;
};
@observable m_Option: RightPlaneLightOption = { ...DefaultRightPlaneLightOption };
@observable configsNames: string[] = [];
InitOption()
{
Object.assign(this.m_Option, DefaultRightPlaneLightOption);
}
InitConfigs()
{
let config: IConfigOption = {};
config.option = toJS(this.m_Option);
let configs: { [key: string]: IConfigOption; } = {};
configs["默认"] = config;
return configs;
}
async UpdateOption(cof: IConfigOption<RightPlaneLightOption>)
{
Object.assign(this.m_Option, cof.option);
let lightStore = LightStore.GetInstance();
let sunLightStore = SunLightStore.GetInstance();
lightStore.ShowHemiLight = cof.option.ShowHemiLight;
lightStore.ShowSunLight = cof.option.ShowSunLight;
lightStore.hemisphereLightData.Color = cof.option.SkyLightColor;
lightStore.hemisphereLightData.Intensity = cof.option.SkyLightIntensity.toString();
lightStore.hemisphereLightData.IndirectLightingIntensity = cof.option.SkyLightIndirectLightingIntensity.toString();
sunLightStore.sunLightIntensity = cof.option.SunLightIntensity;
sunLightStore.sunLightIndirectLightingIntensity = cof.option.SunLightIndirectLightingIntensity;
sunLightStore.sunLightColor = cof.option.SunLightColor;
sunLightStore.sunLightColorTemperature = cof.option.SunLightTemperature;
sunLightStore.sunLightElevationDeg = cof.option.SunLightElevationDeg;
sunLightStore.sunLightRotateDeg = cof.option.SunLightRotateDeg;
lightStore.ShowExposure = cof.option.ShowExposure;
lightStore.hemisphereLightData.AutoExposure = cof.option.AutoExposure;
lightStore.hemisphereLightData.ExposureCompensation = cof.option.ExposureCompensation.toString();
let sunLight = app.Database.SunLight;
let skyLight = app.Database.HemisphereLight;
let pos: Vector3;
let elevation = MathUtils.degToRad(safeEval(cof.option.SunLightElevationDeg.toString()));
let rotate = MathUtils.degToRad(safeEval(cof.option.SunLightRotateDeg.toString()));
pos = new Vector3(DefaultDist.dist * Math.cos(elevation), 0, DefaultDist.dist * Math.sin(elevation));
pos.applyMatrix4(new Matrix4().makeRotationZ(rotate)).add(app.Database.SunLight.Target);
await CommandWrap(() =>
{
skyLight.Visible = cof.option.ShowHemiLight;
sunLight.Visible = cof.option.ShowSunLight;
skyLight.Color = new Color(cof.option.SkyLightColor);
skyLight.Intensity = cof.option.SkyLightIntensity;
skyLight.IndirectLightingIntensity = cof.option.SkyLightIndirectLightingIntensity;
sunLight.Intensity = cof.option.SunLightIntensity;
sunLight.IndirectLightingIntensity = cof.option.SunLightIndirectLightingIntensity;
sunLight.Color = new Color(cof.option.SunLightColor);
sunLight.Temperature = cof.option.SunLightTemperature;
sunLight.Position = pos;
LightStore.GetInstance().UpdateDirLightShadowArea();
app.Viewer.UpdateRender();
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([sunLight, skyLight])));
}, "应用配置");
sunLight.Update();
skyLight.Update();
}
private static _SingleInstance: RightPlaneLightStore;
static GetInstance(): RightPlaneLightStore
{
if (this._SingleInstance) return this._SingleInstance;
this._SingleInstance = new RightPlaneLightStore;
return this._SingleInstance;
}
}

@ -4,9 +4,11 @@ import { observer } from "mobx-react";
import React from "react"; import React from "react";
import { ColorResult, SketchPicker } from "react-color"; import { ColorResult, SketchPicker } from "react-color";
import { Color, MathUtils } from "three"; import { Color, MathUtils } from "three";
import { begin } from "xaop";
import { Entitys2Data } from "../../../Add-on/ExportData"; import { Entitys2Data } from "../../../Add-on/ExportData";
import { app } from "../../../ApplicationServices/Application"; import { app } from "../../../ApplicationServices/Application";
import { ResourcesCDN_HOST } from "../../../Common/HostUrl"; import { ResourcesCDN_HOST } from "../../../Common/HostUrl";
import { KeyBoard } from "../../../Common/KeyEnum";
import { FixedNotZero } from "../../../Common/Utils"; import { FixedNotZero } from "../../../Common/Utils";
import { DirectionalLight } from "../../../DatabaseServices/Lights/DirectionalLight"; import { DirectionalLight } from "../../../DatabaseServices/Lights/DirectionalLight";
import { Light } from "../../../DatabaseServices/Lights/Light"; import { Light } from "../../../DatabaseServices/Lights/Light";
@ -16,16 +18,42 @@ import { commandMachine, CommandWrap } from "../../../Editor/CommandMachine";
import { CommandState } from "../../../Editor/CommandState"; import { CommandState } from "../../../Editor/CommandState";
import { PromptStatus } from "../../../Editor/PromptResult"; import { PromptStatus } from "../../../Editor/PromptResult";
import { userConfig } from "../../../Editor/UserConfig"; import { userConfig } from "../../../Editor/UserConfig";
import { BoardModalType } from "../../Components/Board/BoardModal";
import { UserConfig } from "../../Components/Board/UserConfig";
import { ModalState } from "../../Components/Modal/ModalInterface";
import { AppToaster } from "../../Components/Toaster"; import { AppToaster } from "../../Components/Toaster";
import { IConfigStore } from "../BoardStore";
import { LightStore } from "./LightStore"; import { LightStore } from "./LightStore";
@observer @observer
export class SpotLightModel extends React.Component<{ store: LightStore; isPointLight: boolean; }, {}> export class SpotLightModel extends React.Component<{ store: LightStore; configStore: IConfigStore; LightType: BoardModalType; isNotModify?: boolean; }, {}>
{ {
@observable _Target: string = this.props.isPointLight ? (this.props.store.currentSelectEnt as SpotLight | RectAreaLight).Target.sub(this.props.store.currentSelectEnt.Position).normalize().ceil().toArray().toString() : ""; @observable _Target: string = this.props.LightType === BoardModalType.PointLight ? "" : (this.props.store.currentSelectEnt as SpotLight | RectAreaLight).Target.sub(this.props.store.currentSelectEnt.Position).normalize().ceil().toArray().toString();
@observable _Position: string = this.props.store.currentSelectEnt.Position.ceil().toArray().toString(); @observable _Position: string = this.props.store.currentSelectEnt.Position.ceil().toArray().toString();
@observable _ShowHelper: boolean = this.props.store.currentSelectEnt.ShowHelper; private removeFuncs: Function[] = []; //移除注入
@observable _CaseShadow: boolean = this.props.store.currentSelectEnt.CaseShadow;
componentDidMount()
{
if (this.props.isNotModify)
this.removeFuncs.push(
begin(app.Editor.ModalManage, app.Editor.ModalManage.OnKeyDown, (e: KeyboardEvent) =>
{
if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space)
{
app.Editor.ModalManage.m_PromisRes({ Status: ModalState.Ok });
app.Editor.ModalManage.Destory();
e.preventDefault();
}
e.stopPropagation();
})
);
}
componentWillUnmount()
{
for (let f of this.removeFuncs)
f();
this.removeFuncs.length = 0;
}
handleSelectTarget = async (light: Light, isDirection?: boolean, isPosition?: boolean) => handleSelectTarget = async (light: Light, isDirection?: boolean, isPosition?: boolean) =>
{ {
@ -90,17 +118,18 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
<div className={Classes.DIALOG_BODY}> <div className={Classes.DIALOG_BODY}>
{ {
!this.props.isPointLight || <div style={{ height: 25 }}> (this.props.LightType === BoardModalType.PointLight) || <div style={{ height: 25 }}>
<Switch <Switch
checked={this._ShowHelper} checked={lightData.ShowHelper}
label="显示灯光助手" label="显示灯光助手"
onChange={e => onChange={e =>
{ {
CommandWrap(() => if (!this.props.isNotModify)
{ CommandWrap(() =>
this._ShowHelper = !this._ShowHelper; {
light.ShowHelper = !light.ShowHelper; light.ShowHelper = !light.ShowHelper;
}, "灯光助手显示/隐藏"); }, "灯光助手显示/隐藏");
lightData.ShowHelper = !lightData.ShowHelper;
}} }}
alignIndicator={Alignment.RIGHT} alignIndicator={Alignment.RIGHT}
/> />
@ -108,21 +137,22 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
} }
<div style={{ height: 25 }}> <div style={{ height: 25 }}>
<Switch <Switch
checked={this._CaseShadow} checked={lightData.CaseShadow}
label="阴影" label="阴影"
onChange={e => onChange={e =>
{ {
CommandWrap(() => if (!this.props.isNotModify)
{ CommandWrap(() =>
this._CaseShadow = !this._CaseShadow; {
light.CaseShadow = !light.CaseShadow; light.CaseShadow = !light.CaseShadow;
}, "阴影显示/隐藏"); }, "阴影显示/隐藏");
lightData.CaseShadow = !lightData.CaseShadow;
}} }}
alignIndicator={Alignment.RIGHT} alignIndicator={Alignment.RIGHT}
/> />
</div> </div>
{ {
!this.props.isPointLight || <div> (this.props.LightType === BoardModalType.PointLight) || <div>
<div> <div>
<Label style={{ float: "left" }}>:</Label> <Label style={{ float: "left" }}>:</Label>
<input <input
@ -135,10 +165,12 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
<Tooltip <Tooltip
content="选择照射方向" content="选择照射方向"
position="top" position="top"
disabled={this.props.isNotModify}
> >
<Button <Button
icon="select" icon="select"
onClick={() => { this.handleSelectTarget(light, true); }} onClick={() => { this.handleSelectTarget(light, true); }}
disabled={this.props.isNotModify}
/> />
</Tooltip> </Tooltip>
</div> </div>
@ -147,11 +179,13 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
<Tooltip <Tooltip
content="同时选择照射方向和位置" content="同时选择照射方向和位置"
position="right" position="right"
disabled={this.props.isNotModify}
> >
<Button <Button
style={{ marginTop: "-29.5px", height: "65px" }} style={{ marginTop: "-29.5px", height: "65px" }}
icon="select" icon="select"
onClick={() => { this.handleSelectTarget(light, true, true); }} onClick={() => { this.handleSelectTarget(light, true, true); }}
disabled={this.props.isNotModify}
/> />
</Tooltip> </Tooltip>
</div> </div>
@ -167,11 +201,12 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
value={this._Position} value={this._Position}
disabled disabled
/> />
<div style={{ position: "absolute", right: this.props.isPointLight ? 48 : 11, marginTop: "-1.5px" }}> <div style={{ position: "absolute", right: !(this.props.LightType === BoardModalType.PointLight) ? 48 : 11, marginTop: "-1.5px" }}>
<Tooltip content="选择位置"> <Tooltip content="选择位置" disabled={this.props.isNotModify}>
<Button <Button
icon="select" icon="select"
onClick={() => { this.handleSelectTarget(light, false, true); }} onClick={() => { this.handleSelectTarget(light, false, true); }}
disabled={this.props.isNotModify}
/> />
</Tooltip> </Tooltip>
</div> </div>
@ -188,37 +223,48 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
color={lightData.Color.toUpperCase()} color={lightData.Color.toUpperCase()}
onChange={(e: ColorResult) => onChange={(e: ColorResult) =>
{ {
const KEY = '修改颜色'; if (!this.props.isNotModify)
if (CommandState.CommandIng)
{ {
if (app.Database.hm.UndoData.CommandName !== KEY) const KEY = '修改颜色';
if (CommandState.CommandIng)
{ {
app.Editor.ModalManage.EndExecingCmd().then(() => if (app.Database.hm.UndoData.CommandName !== KEY)
{ {
AppToaster.show({ app.Editor.ModalManage.EndExecingCmd().then(() =>
message: "命令正在执行中!无法修改天光颜色!", {
timeout: 5000, AppToaster.show({
intent: Intent.DANGER message: "命令正在执行中!无法修改天光颜色!",
timeout: 5000,
intent: Intent.DANGER
});
}); });
}); return;
return; }
}
else
{
commandMachine.CommandStart(KEY);
} }
this.props.store.currentSelectEnt.Color = new Color(e.hex.toString());
app.Viewer.UpdateRender();
this.SyncLight();
} }
else else
{ {
commandMachine.CommandStart(KEY); this.props.store.currentSelectEnt.Color = new Color(e.hex.toString());
app.Viewer.UpdateRender();
} }
this.props.store.currentSelectEnt.Color = new Color(e.hex.toString());
lightData.Color = e.hex; lightData.Color = e.hex;
app.Viewer.UpdateRender();
this.SyncLight();
}} }}
onChangeComplete={() => onChangeComplete={() =>
{ {
const KEY = '修改颜色'; if (!this.props.isNotModify)
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
{ {
commandMachine.CommandEnd(); const KEY = '修改颜色';
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
{
commandMachine.CommandEnd();
}
} }
}} }}
/> />
@ -247,8 +293,8 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
<div className='sun-colortemp'> <div className='sun-colortemp'>
<img alt='色温' draggable={false} src={`${ResourcesCDN_HOST}/colortemperature.webp`} /> <img alt='色温' draggable={false} src={`${ResourcesCDN_HOST}/colortemperature.webp`} />
<Slider <Slider
min={1800} min={1700}
max={16000} max={12000}
stepSize={1} stepSize={1}
labelStepSize={1775} labelStepSize={1775}
showTrackFill={false} showTrackFill={false}
@ -256,38 +302,46 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
value={parseInt(this.props.store.lightData.Temperature)} value={parseInt(this.props.store.lightData.Temperature)}
onChange={async (val) => onChange={async (val) =>
{ {
const KEY = "修改射灯色温"; if (!this.props.isNotModify)
if (CommandState.CommandIng)
{ {
if (app.Database.hm.UndoData.CommandName !== KEY) const KEY = "修改射灯色温";
if (CommandState.CommandIng)
{ {
await app.Editor.ModalManage.EndExecingCmd(); if (app.Database.hm.UndoData.CommandName !== KEY)
AppToaster.show({ {
message: "命令正在执行中!无法修改射灯色温!", await app.Editor.ModalManage.EndExecingCmd();
timeout: 5000, AppToaster.show({
intent: Intent.DANGER, message: "命令正在执行中!无法修改射灯色温!",
}); timeout: 5000,
return; intent: Intent.DANGER,
});
return;
}
}
else
{
commandMachine.CommandStart(KEY);
} }
this.props.store.currentSelectEnt.Temperature = val;
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([this.props.store.currentSelectEnt])));
} }
else else
{ {
commandMachine.CommandStart(KEY); this.props.store.currentSelectEnt.Temperature = val;
app.Viewer.UpdateRender();
} }
this.props.store.currentSelectEnt.Temperature = val;
this.props.store.lightData.Temperature = val.toString(); this.props.store.lightData.Temperature = val.toString();
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([this.props.store.currentSelectEnt])));
}} }}
onRelease={() => onRelease={() =>
{ {
const KEY = "修改射灯色温"; if (!this.props.isNotModify)
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY) {
commandMachine.CommandEnd(); const KEY = "修改射灯色温";
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
commandMachine.CommandEnd();
}
}} }}
/> />
</div> </div>
</Popover> </Popover>
@ -346,10 +400,34 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
min={min} min={min}
isFloat={isFloat} isFloat={isFloat}
noLim={noLim} noLim={noLim}
isNotModify={this.props.isNotModify}
/>; />;
}) })
} }
</div> </div>
<div className={Classes.DIALOG_FOOTER}>
<div className="foot_left">
<UserConfig
store={this.props.configStore}
type={this.props.LightType}
isUpdate={false}
isNotModify={this.props.isNotModify}
/>
</div>
{
this.props.isNotModify && <div className="foot_right">
<Button
intent="success"
text="确定"
onClick={() =>
{
app.Editor.ModalManage.m_PromisRes({ Status: ModalState.Ok });
app.Editor.ModalManage.Destory();
}}
/>
</div>
}
</div>
</div> </div>
</div > </div >
); );
@ -357,9 +435,9 @@ export class SpotLightModel extends React.Component<{ store: LightStore; isPoint
} }
@observer @observer
export class InputAndSlider extends React.Component<{ pars: string[], store: LightStore; max: number; isFloat: boolean; min: number; noLim: boolean; }, {}> export class InputAndSlider extends React.Component<{ pars: string[], store: LightStore; max: number; isFloat: boolean; min: number; noLim: boolean; isNotModify: boolean; }, {}>
{ {
@observable _InputEl = React.createRef<NumericInput>(); OldData: number = 0;
SetValue(value: string) SetValue(value: string)
{ {
@ -415,13 +493,45 @@ export class InputAndSlider extends React.Component<{ pars: string[], store: Lig
this.props.store.currentSelectEnt[this.props.pars[0]] = parseInt(value); this.props.store.currentSelectEnt[this.props.pars[0]] = parseInt(value);
break; break;
} }
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([this.props.store.currentSelectEnt])));
this.props.store.currentSelectEnt.Update(); this.props.store.currentSelectEnt.Update();
app.Editor.UpdateScreen(); app.Editor.UpdateScreen();
} }
private SyncLight()
SetLightData(value: string)
{ {
if (userConfig.synchronousEnable) switch (this.props.pars[0])
app.WebSocket.Send(JSON.stringify(Entitys2Data([this.props.store.currentSelectEnt]))); {
case "InnerConeAngle":
this.props.store.lightData.InnerConeAngle = value;
this.props.store.currentSelectEnt[this.props.pars[0]] = parseInt(value);
if (parseInt(value) > parseInt(this.props.store.lightData.Angle))
{
this.props.store.lightData.Angle = value;
this.props.store.currentSelectEnt["Angle"] = MathUtils.degToRad(parseInt(value));
}
this.props.store.currentSelectEnt.Update();
break;
case "Angle":
this.props.store.lightData.Angle = value;
this.props.store.currentSelectEnt["Angle"] = MathUtils.degToRad(parseInt(value));
if (parseInt(value) < parseInt(this.props.store.lightData.InnerConeAngle))
{
this.props.store.lightData.InnerConeAngle = value;
this.props.store.currentSelectEnt["InnerConeAngle"] = parseInt(value);
}
break;
case "SpecularScale":
this.props.store.lightData.SpecularScale = value;
this.props.store.currentSelectEnt.SpecularScale = parseFloat(value);
break;
default:
this.props.store.lightData[this.props.pars[0]] = value;
this.props.store.currentSelectEnt[this.props.pars[0]] = parseInt(value);
break;
}
app.Viewer.UpdateRender();
} }
render() render()
@ -433,26 +543,54 @@ export class InputAndSlider extends React.Component<{ pars: string[], store: Lig
<NumericInput <NumericInput
min={this.props.min} min={this.props.min}
max={this.props.noLim ? 10e6 : this.props.max} max={this.props.noLim ? 10e6 : this.props.max}
ref={this._InputEl}
buttonPosition={"none"} buttonPosition={"none"}
value={this.props.store.lightData[this.props.pars[0]]} value={this.props.store.lightData[this.props.pars[0]]}
allowNumericCharactersOnly
onKeyDown={(e) => onKeyDown={(e) =>
{ {
e.stopPropagation(); e.stopPropagation();
}} }}
onValueChange={(num) => onValueChange={(num, value, e) =>
{ {
if (isNaN(num) || num < this.props.min || num > (this.props.noLim ? 10e6 : this.props.max)) return; if (this.props.isFloat) // 处理小数点 Data赋值不上传
this.SetValue(FixedNotZero(num, 1)); if (num >= this.props.min && num < this.props.max && value === num + ".")
this.SyncLight(); {
app.Viewer.UpdateRender(); this.props.store.lightData[this.props.pars[0]] = num + ".";
return;
}
if (isNaN(num) || num > (this.props.noLim ? 10e6 : this.props.max)) return;
if (num < this.props.min)
{
this.props.store.lightData[this.props.pars[0]] = num;
this.OldData = this.props.store.lightData[this.props.pars[0]];
return;
}
this.props.isNotModify ? this.SetLightData(FixedNotZero(num, 1)) : this.SetValue(FixedNotZero(num, 1));
}} }}
onBlur={() => onBlur={(e) =>
{ {
const KEY = '修改灯光' + this.props.pars[1];; if (this.props.isFloat) // 去掉小数点
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY) if (e.currentTarget.value[e.currentTarget.value.length - 1] === ".")
{
this.props.store.lightData[this.props.pars[0]] = 0;
}
if (this.props.store.lightData[this.props.pars[0]] < this.props.min)
{ {
commandMachine.CommandEnd(); if (this.OldData = this.props.store.currentSelectEnt[this.props.pars[0]])
{
this.props.store.lightData[this.props.pars[0]] = this.props.store.currentSelectEnt[this.props.pars[0]];
return;
}
this.props.isNotModify ? this.SetLightData(FixedNotZero(this.props.min, 1)) : this.SetValue(FixedNotZero(this.props.min, 1));
}
if (!this.props.isNotModify)
{
const KEY = '修改灯光' + this.props.pars[1];
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
{
commandMachine.CommandEnd();
}
} }
}} }}
onFocus={(e) => onFocus={(e) =>
@ -467,16 +605,17 @@ export class InputAndSlider extends React.Component<{ pars: string[], store: Lig
value={parseFloat(this.props.store.lightData[this.props.pars[0]]) >= this.props.max ? this.props.max : parseFloat(this.props.store.lightData[this.props.pars[0]])} value={parseFloat(this.props.store.lightData[this.props.pars[0]]) >= this.props.max ? this.props.max : parseFloat(this.props.store.lightData[this.props.pars[0]])}
onChange={(e) => onChange={(e) =>
{ {
this.SetValue((FixedNotZero(e, this.props.isFloat ? 1 : 0))); this.props.isNotModify ? this.SetLightData((FixedNotZero(e, this.props.isFloat ? 1 : 0))) : this.SetValue((FixedNotZero(e, this.props.isFloat ? 1 : 0)));
this.SyncLight();
app.Viewer.UpdateRender();
}} }}
onRelease={() => onRelease={() =>
{ {
const KEY = '修改灯光' + this.props.pars[1]; if (!this.props.isNotModify)
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
{ {
commandMachine.CommandEnd(); const KEY = '修改灯光' + this.props.pars[1];
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
{
commandMachine.CommandEnd();
}
} }
}} }}
/> />

Loading…
Cancel
Save