From ddb2c37be20eb1d56fe4ec309d3eb4ac67a15c80 Mon Sep 17 00:00:00 2001 From: ChenX Date: Tue, 7 Sep 2021 07:39:05 +0000 Subject: [PATCH] =?UTF-8?q?!1625=20=E5=8A=9F=E8=83=BD:=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E7=81=AF=E5=85=89=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Geometry/orbit.test.ts | 22 +-- src/Add-on/ExportData.tsx | 156 ++++++++++++++++-- .../Lights/DirectionalLight.ts | 20 ++- .../Lights/HemisphereLight.ts | 2 +- src/DatabaseServices/Lights/Light.ts | 2 + src/Geometry/GeUtils.ts | 5 - src/UI/DynamicPrompt/DynamicInputManage.ts | 29 +--- 7 files changed, 186 insertions(+), 50 deletions(-) diff --git a/__test__/Geometry/orbit.test.ts b/__test__/Geometry/orbit.test.ts index 94ccf4111..c4511bbda 100644 --- a/__test__/Geometry/orbit.test.ts +++ b/__test__/Geometry/orbit.test.ts @@ -1,4 +1,4 @@ -import * as THREE from 'three'; +import { Vector3 } from 'three'; import { equaln, equalv3 } from '../../src/Geometry/GeUtils'; import { Orbit } from '../../src/Geometry/Orbit'; @@ -7,7 +7,7 @@ test("", () => //构造一个控制类. let orb = new Orbit(); - let dir = new THREE.Vector3(0, 1, 0); + let dir = new Vector3(0, 1, 0); orb.SetFromDirection(dir); @@ -16,7 +16,7 @@ test("", () => //试着还原 orb.UpdateDirection(dir); - expect(equalv3(dir, new THREE.Vector3(0, 1, 0))).toBe(true); + expect(equalv3(dir, new Vector3(0, 1, 0))).toBe(true); //试试新的 dir.set(1, 0, 0); @@ -26,7 +26,7 @@ test("", () => //试着还原 orb.UpdateDirection(dir); - expect(equalv3(dir, new THREE.Vector3(1, 0, 0))).toBe(true); + expect(equalv3(dir, new Vector3(1, 0, 0))).toBe(true); //试试新的 dir.set(0.5, 0.5, 0).normalize(); @@ -60,21 +60,21 @@ test("", () => let newDir = orb.UpdateDirection(); - let up = Orbit.ComputUpDirection(new THREE.Vector3(0, 0, 1)); - expect(equalv3(up, new THREE.Vector3(0, 1, 0))).toBe(true); + let up = Orbit.ComputUpDirection(new Vector3(0, 0, 1)); + expect(equalv3(up, new Vector3(0, 1, 0))).toBe(true); - Orbit.ComputUpDirection(new THREE.Vector3(0, 0, -1), up); - Orbit.ComputUpDirection(new THREE.Vector3(0, 0, 1), up); - Orbit.ComputUpDirection(new THREE.Vector3(1, 0, 0), up); + Orbit.ComputUpDirection(new Vector3(0, 0, -1), up); + Orbit.ComputUpDirection(new Vector3(0, 0, 1), up); + Orbit.ComputUpDirection(new Vector3(1, 0, 0), up); let newD = orb.UpdateDirection(); - expect(equalv3(newD, new THREE.Vector3(0, 0, -1))).toBe(true); + expect(equalv3(newD, new Vector3(0, 0, -1))).toBe(true); }); test("测试求向量", () => { - let dir = new THREE.Vector3(0, 0, 1); + let dir = new Vector3(0, 0, 1); let up = Orbit.ComputUpDirection(dir); expect(up).toMatchSnapshot(); diff --git a/src/Add-on/ExportData.tsx b/src/Add-on/ExportData.tsx index c5d5f6fab..eb8642d46 100644 --- a/src/Add-on/ExportData.tsx +++ b/src/Add-on/ExportData.tsx @@ -1,6 +1,6 @@ import { Button, Card, Classes, Intent } from '@blueprintjs/core'; import * as React from 'react'; -import { Vector3 } from 'three'; +import { MathUtils, Vector3 } from 'three'; import { OBJExporter } from 'three/examples/jsm/exporters/OBJExporter'; import { begin } from 'xaop'; import { app } from "../ApplicationServices/Application"; @@ -23,6 +23,11 @@ import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { Region } from "../DatabaseServices/Entity/Region"; import { HardwareCompositeEntity } from '../DatabaseServices/Hardware/HardwareCompositeEntity'; import { HardwareTopline } from '../DatabaseServices/Hardware/HardwareTopline'; +import { DirectionalLight } from "../DatabaseServices/Lights/DirectionalLight"; +import { HemisphereLight } from '../DatabaseServices/Lights/HemisphereLight'; +import { PointLight } from '../DatabaseServices/Lights/PointLight'; +import { RectAreaLight } from '../DatabaseServices/Lights/RectAreaLight'; +import { SpotLight } from '../DatabaseServices/Lights/SpotLight'; import { PhysicalMaterialRecord } from "../DatabaseServices/PhysicalMaterialRecord"; import { Shape } from "../DatabaseServices/Shape"; import { TextureTableRecord } from "../DatabaseServices/Texture"; @@ -35,6 +40,7 @@ import { ModalPosition } from '../UI/Components/Modal/ModalInterface'; import { TopPanelStore } from '../UI/Store/TopPanelStore'; import { Hole } from './../DatabaseServices/3DSolid/Hole'; import { CompositeEntity } from './../DatabaseServices/Entity/CompositeEntity'; + export class ExportDataModal extends React.Component<{ msg: string; }, {}>{ private removeFuncs: Function[] = []; //移除注入 private Close() @@ -131,6 +137,16 @@ export function Entitys2Data(ents: Entity[]): Data d.Entitys.push(ConvertRevolve2Data(e)); else if (e instanceof EntityRef) d.Entitys.push(ConveEntityRef2Data(e)); + else if (e instanceof DirectionalLight) + d.Entitys.push(ConverDirectionalLight2Data(e)); + else if (e instanceof PointLight) + d.Entitys.push(ConverPointLight2Data(e)); + else if (e instanceof SpotLight) + d.Entitys.push(ConverSpotLight2Data(e)); + else if (e instanceof RectAreaLight) + d.Entitys.push(ConverRectAreaLight2Data(e)); + else if (e instanceof HemisphereLight) + d.Entitys.push(ConverHemisphereLight2Data(e)); else continue; @@ -161,7 +177,7 @@ export function Entitys2Data(ents: Entity[]): Data function Curve2Data(cu: Curve, AligenToWCS = true): Object { - let cud: any = { }; + let cud: any = {}; if (cu instanceof Polyline) { cud.Type = "Polyline"; @@ -185,7 +201,7 @@ function Curve2Data(cu: Curve, AligenToWCS = true): Object function ConvertBoard2Data(br: ExtrudeSolid): Object { - let ed: any = { }; + let ed: any = {}; ed.Id = br.Id?.Index ?? 0; ed.OCS = br.OCSNoClone.toArray(); ed.Thickness = br.Thickness; @@ -211,7 +227,7 @@ function ConvertBoard2Data(br: ExtrudeSolid): Object function ConverSweep2Data(e: SweepSolid) { - let ed: any = { }; + let ed: any = {}; ed.Id = e.Id?.Index ?? 0; ed.Type = "Sweep"; ed.OCS = e.OCS.toArray(); @@ -231,7 +247,7 @@ function ConveRegion2Data(e: Region) { e = e.Clone(); - let reg: any = { }; + let reg: any = {}; reg.Type = "Region"; let ocsInv = e.OCSInv; @@ -244,7 +260,7 @@ function ConveRegion2Data(e: Region) function ConveEntityRef2Data(e: EntityRef) { - let ref: any = { }; + let ref: any = {}; ref.Id = e.Id?.Index ?? 0; ref.Type = "Ref"; ref.Url = e.Url; @@ -258,7 +274,7 @@ function ConveEntityRef2Data(e: EntityRef) function ConverShape2Data(e: Shape) { - let d = { } as any; + let d = {} as any; d.Contour = Curve2Data(e.Outline.Curve); d.Holes = e.Holes.map(c => Curve2Data(c.Curve)); return d; @@ -266,7 +282,7 @@ function ConverShape2Data(e: Shape) export function ConverMaterialData(material: PhysicalMaterialRecord) { - let d: any = { }; + let d: any = {}; d.Id = material.Id?.Index ?? 0; d.color = material.color; d.transparent = material.transparent; @@ -287,7 +303,7 @@ export function ConverMaterialData(material: PhysicalMaterialRecord) function ConvertHole2Data(h: Hole) { - let ed: any = { }; + let ed: any = {}; ed.Id = h.Id?.Index ?? 0; ed.OCS = h.OCS.toArray(); ed.Thickness = h.Height; @@ -308,7 +324,7 @@ function ConvertHole2Data(h: Hole) function ConvertRevolve2Data(h: RevolveSolid) { - let ed: any = { }; + let ed: any = {}; ed.Id = h.Id?.Index ?? 0; ed.OCS = h.OCS.toArray(); ed.Type = "Revolve"; @@ -334,6 +350,126 @@ function CompositeEntity2Data(comp: CompositeEntity) return data; } +function ConverDirectionalLight2Data(light: DirectionalLight) +{ + let ed: any = {}; + ed.Id = light.Id?.Index ?? 0; + ed.Type = "DirectionalLight"; + ed.LightSourceAngle = light.LightSourceAngle; + ed.LightSourceSoftAngle = light.LightSourceSoftAngle; + + ed.Color = light.Color.toArray(); + ed.Intensity = light.Intensity; + ed.Temperature = light.Temperature; + ed.IndirectLightingIntensity = light.IndirectLightingIntensity; + ed.CaseShadow = light.CaseShadow; + + // ed.SpecularScale = light.SpecularScale; 默认为0 + + //阳光照射方向 + let rotateV = light.Position.sub(light.Target).normalize(); + ed.theta = Math.atan2(rotateV.y, rotateV.x) * MathUtils.RAD2DEG; + ed.phi = Math.asin(rotateV.z) * MathUtils.RAD2DEG; + + return ed; +} + +function ConverPointLight2Data(light: PointLight) +{ + let ed: any = {}; + ed.Id = light.Id?.Index ?? 0; + ed.Type = "PointLight"; + + ed.Color = light.Color.toArray(); + ed.Intensity = light.Intensity; + ed.Temperature = light.Temperature; + + ed.SourceRadius = light.SourceRadius; + ed.SoftSourceRadius = light.SoftSourceRadius; + ed.SourceLength = light.SourceLength; + + ed.AttenuationRadius = light.AttenuationRadius; + + ed.IndirectLightingIntensity = light.IndirectLightingIntensity; + ed.CaseShadow = light.CaseShadow; + + ed.SpecularScale = light.SpecularScale; + return ed; +} + +function ConverSpotLight2Data(light: SpotLight) +{ + let ed: any = {}; + ed.Id = light.Id?.Index ?? 0; + ed.Type = "SpotLight"; + + ed.Color = light.Color.toArray(); + ed.Intensity = light.Intensity; + ed.Temperature = light.Temperature; + + ed.SourceRadius = light.SourceRadius; + ed.SoftSourceRadius = light.SoftSourceRadius; + ed.SourceLength = light.SourceLength; + + ed.AttenuationRadius = light.AttenuationRadius; + + ed.InnerConeAngle = light.InnerConeAngle; + ed.OuterConeAngle = light.OuterConeAngle; + + ed.IndirectLightingIntensity = light.IndirectLightingIntensity; + ed.CaseShadow = light.CaseShadow; + + ed.SpecularScale = light.SpecularScale; + return ed; +} + +function ConverRectAreaLight2Data(light: RectAreaLight) +{ + let ed: any = {}; + ed.Id = light.Id?.Index ?? 0; + ed.Type = "RectAreaLight"; + + ed.Color = light.Color.toArray(); + ed.Intensity = light.Intensity; + ed.Temperature = light.Temperature; + + ed.AttenuationRadius = light.AttenuationRadius; + + ed.BarnDoorAngle = light.BarnDoorAngle; + ed.BarnDoorLength = light.BarnDoorLength; + ed.SourceTexture = light.SourceTexture; + + ed.IndirectLightingIntensity = light.IndirectLightingIntensity; + ed.CaseShadow = light.CaseShadow; + + ed.SpecularScale = light.SpecularScale; + return ed; +} + + +function ConverHemisphereLight2Data(light: HemisphereLight) +{ + let ed: any = {}; + ed.Id = light.Id?.Index ?? 0; + ed.Type = "HemisphereLight"; + + //立方体贴图 默认 不变 + + ed.Color = light.Color.toArray(); + ed.Intensity = light.Intensity; + + // light.GroundColor 底色(默认黑色) + + // ed.Temperature = light.Temperature; + + // ed.IndirectLightingIntensity = light.IndirectLightingIntensity; + // ed.CaseShadow = light.CaseShadow; + + // ed.SpecularScale = light.SpecularScale; + return ed; +} + + //OBJ文件 const objExport = new OBJExporter; function GetOBJFileData(en: Entity): string diff --git a/src/DatabaseServices/Lights/DirectionalLight.ts b/src/DatabaseServices/Lights/DirectionalLight.ts index a6ffaf8b7..c501922eb 100644 --- a/src/DatabaseServices/Lights/DirectionalLight.ts +++ b/src/DatabaseServices/Lights/DirectionalLight.ts @@ -1,4 +1,4 @@ -import { DirectionalLight as TDirectionalLight, DirectionalLightHelper, Group, Matrix4, Object3D, Vector2, Vector3 } from "three"; +import { DirectionalLight as TDirectionalLight, DirectionalLightHelper, Group, MathUtils, Matrix3, Matrix4, Object3D, Vector2, Vector3 } from "three"; import { HostApplicationServices } from "../../ApplicationServices/HostApplicationServices"; import { UpdateDraw } from "../../Common/Status"; import { equalv3 } from "../../Geometry/GeUtils"; @@ -29,6 +29,24 @@ export class DirectionalLight extends Light this.SpecularScale = 0;//高光度范围 默认0 关闭太阳光反射 } + /** + * @param theta 身体旋转 角度(deg) + * @param phi 头部旋转 角度(deg) + */ + SetRotate(thetaDeg: number, phiDeg: number) + { + let phi = (180 - phiDeg) * MathUtils.DEG2RAD; + + let v = new Vector3(Math.cos(phi), 0, Math.sin(phi)); + + let r = new Matrix3().rotate(MathUtils.DEG2RAD * thetaDeg); + + v.applyMatrix3(r); + + this.WriteAllObjectRecord(); + this._Target.setFromMatrixPosition(this._Matrix).sub(v); + } + get Target() { return this._Target.clone(); } set Target(p: Vector3) { diff --git a/src/DatabaseServices/Lights/HemisphereLight.ts b/src/DatabaseServices/Lights/HemisphereLight.ts index bc18c2e76..f71bb8c80 100644 --- a/src/DatabaseServices/Lights/HemisphereLight.ts +++ b/src/DatabaseServices/Lights/HemisphereLight.ts @@ -7,7 +7,7 @@ import { Light } from "./Light"; @Factory export class HemisphereLight extends Light { - private _GroundColor = new Color(); //底色在UE中没有这个属性 + private _GroundColor = new Color(); //UE有这个属性 但是默认是黑的 protected _Intensity = 0.5; get GroundColor() { return this._GroundColor; } diff --git a/src/DatabaseServices/Lights/Light.ts b/src/DatabaseServices/Lights/Light.ts index 3985eb4c1..743d96fe1 100644 --- a/src/DatabaseServices/Lights/Light.ts +++ b/src/DatabaseServices/Lights/Light.ts @@ -32,6 +32,8 @@ export class Light extends Entity return CADObject.prototype.Clone.call(this); } + get CaseShadow() { return this._CaseShadow; } + get Position() { return super.Position; diff --git a/src/Geometry/GeUtils.ts b/src/Geometry/GeUtils.ts index 73f735879..4e370e4a8 100644 --- a/src/Geometry/GeUtils.ts +++ b/src/Geometry/GeUtils.ts @@ -85,9 +85,6 @@ export function equalv2(v1: P2, v2: P2, fuzz = 1e-8) /** * 按照极坐标的方式移动一个点 - * - * @export - * @template * @param {T} v 向量(2d,3d) * @param {number} an 角度 * @param {number} dis 距离 @@ -110,11 +107,9 @@ export function angle(v: Vector3 | Vector2): number /** * 求两个向量的夹角,顺时针为负,逆时针为正 - * * @param {Vector3} v1 * @param {Vector3} v2 * @param {Vector3} [ref] 参考向量,如果为世界坐标系则为0,0,1 - * @returns */ export function angleTo(v1: Vector3, v2: Vector3, ref: Vector3 = ZAxis): number { diff --git a/src/UI/DynamicPrompt/DynamicInputManage.ts b/src/UI/DynamicPrompt/DynamicInputManage.ts index 49027cef5..917f5c8ae 100644 --- a/src/UI/DynamicPrompt/DynamicInputManage.ts +++ b/src/UI/DynamicPrompt/DynamicInputManage.ts @@ -36,7 +36,7 @@ export class DynamicInputManage this.RegisterEvent(); - //TODO 销毁 + //对象在app生命周期内始终存在 不需要销毁 autorun(() => { this.container.style.display = @@ -49,7 +49,6 @@ export class DynamicInputManage static GetManage() { if (!this.manage) this.manage = new DynamicInputManage(); - window["mg"] = this.manage; return this.manage; } // ----------------------单例接口End---------------------- @@ -59,29 +58,15 @@ export class DynamicInputManage { this._IsInputing = v; this.container.style.pointerEvents = v ? "auto" : "none"; - this.inputCollection.forEach(el => - { + for (let el of this.inputCollection) el.inputEl.style.pointerEvents = v ? "auto" : "none"; - }); - } - get IsInputing() - { - return this._IsInputing; - } - get IsLockIng() - { - return this.inputCollection.some(i => i.IsLock); } + get IsInputing() { return this._IsInputing; } + get IsLockIng() { return this.inputCollection.some(i => i.IsLock); } //获得容器节点 - get Container(): HTMLElement - { - return this.container; - } - get InputCollection() - { - return this.inputCollection; - } + get Container(): HTMLElement { return this.container; } + get InputCollection() { return this.inputCollection; } //当用户尝试改变坐标时,可以触发这个更新动态输入 Focus() { @@ -109,7 +94,7 @@ export class DynamicInputManage //注册事件 private RegisterEvent() { - window.addEventListener("keydown", (e) => { this.HandleDynamicInput(e); }); + window.addEventListener("keydown", this.HandleDynamicInput); } //操作输入框,切换及确认 private HandleDynamicInput = (e: KeyboardEvent) =>