!1667 功能:使用射线投射来确定绘制点

pull/1682/head
ChenX 3 years ago
parent 01cbafff96
commit 262d320e1d

@ -1,4 +1,4 @@
import { MathUtils, Vector3 } from "three";
import { MathUtils, Matrix4, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application";
import { SpotLight } from "../../DatabaseServices/Lights/SpotLight";
import { Command } from "../../Editor/CommandMachine";
@ -10,14 +10,26 @@ export class DrawSpotLight implements Command
{
async exec()
{
let mtx = new Matrix4;
let light = JigUtils.Draw(new SpotLight());
let ptRes = await app.Editor.GetPoint({
Msg: "选择光源位置"
Msg: "选择光源位置",
Raycast: true,
Callback: (p, i) =>
{
if (i?.face?.normal)
{
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;
}
});
if (ptRes.Status === PromptStatus.Cancel)
return;
let light = JigUtils.Draw(new SpotLight());
light.ApplyMatrix(app.Editor.UCSMatrix);
light.Position = ptRes.Point;
@ -43,6 +55,20 @@ export class DrawSpotLight implements Command
light.Target = v.add(ptRes.Point);
app.Database.Lights.Append(light);
}
else if (anRes.Status === PromptStatus.None)
{
let i = ptRes.intersection;
let p = ptRes.Point;
if (i)
{
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;
app.Database.Lights.Append(light);
}
}
}
export class DrawSpotLight2 implements Command
@ -53,7 +79,8 @@ export class DrawSpotLight2 implements Command
light.ApplyMatrix(app.Editor.UCSMatrix);
let ptRes = await app.Editor.GetPoint({
Msg: "选择射灯位置",
Callback: p => this.update(light, p)
Callback: p => this.update(light, p),
Raycast: true,
});
if (ptRes.Status === PromptStatus.OK)

@ -0,0 +1,104 @@
import { Matrix4, Vector3 } from "three";
import { app } from "../ApplicationServices/Application";
import { Line } from "../DatabaseServices/Entity/Line";
import { Command } from "../Editor/CommandMachine";
import { JigUtils } from "../Editor/JigUtils";
import { PromptStatus } from "../Editor/PromptResult";
import { AxisSnapMode } from "../Editor/SnapServices";
import { CursorMode } from "../GraphicsSystem/Cursor";
import { HotCMD } from "../Hot/HotCommand";
@HotCMD
export class MoveX implements Command
{
async exec()
{
let bakSnapMode = app.Editor.GetPointServices.snapServices.AxisSnapMode;
app.Editor.GetPointServices.snapServices.AxisSnapMode = AxisSnapMode.None;
let ssRes = await app.Editor.GetSelection({ UseSelect: true });
if (ssRes.Status !== PromptStatus.OK) return;
let ents = ssRes.SelectSet.SelectEntityList;
let x = new Vector3().setFromMatrixColumn(ents[0].OCSNoClone, 0);
let pos = ents[0].Position;
let cloneEnts = ents.map(e => { let clone = JigUtils.Draw(e); e.DrawObject.visible = false; return clone; });
let xscale = x.clone().multiplyScalar(1e6);
let jigLine = new Line(pos.clone().add(xscale), pos.clone().sub(xscale));
jigLine.ColorIndex = 8;
JigUtils.Draw(jigLine);
let mouseP = new Vector3;
let bakLength = app.Viewer.PreViewer.Cursor.CrossLineLength;
app.Viewer.PreViewer.Cursor.CrossLineLength = 10;
let sign: number = 1;
let moveMtx = new Matrix4;
let dRes = await app.Editor.GetDistance({
BasePoint: pos,
DisableRubberBand: true,
CalcDistance: (baseP, curP) =>
{
// app.Viewer.PreViewer.Cursor.Mode = CursorMode.Cross;
if (app.Editor.GetPointServices.IsSnap)
mouseP.copy(curP);
else
{
//参考直线的最近点捕捉
mouseP.copy(app.Editor.MouseCtrl._CurMousePointVCS);
app.CameraControls.cameraNormal.setFromMatrixColumn(app.Viewer.Camera.matrixWorld, 2);
app.CameraControls.cameraNormal.crossVectors(app.CameraControls.cameraNormal, x);
app.CameraControls.cameraNormal.crossVectors(x, app.CameraControls.cameraNormal);
app.Viewer.ScreenToWorld(mouseP, app.CameraControls.cameraNormal, pos);
}
mouseP.sub(pos);
let d = x.dot(mouseP);
moveMtx.setPosition(mouseP.copy(x).multiplyScalar(d));
for (let i = 0; i < ents.length; i++)
{
let pree = ents[i];
let e = cloneEnts[i];
e.OCSNoClone.copy(pree.OCSNoClone);
e.ApplyMatrix(moveMtx);
}
sign = Math.sign(d);
return Math.abs(d);
}
});
for (let e of ents)
e.DrawObject.visible = true;
app.Viewer.PreViewer.Cursor.CrossLineLength = bakLength;
app.Viewer.PreViewer.Cursor.Mode = CursorMode.None;
app.Editor.GetPointServices.snapServices.AxisSnapMode = bakSnapMode;
if (dRes.Status === PromptStatus.OK)
{
let d = dRes.Distance * sign;
moveMtx.setPosition(mouseP.copy(x).multiplyScalar(d));
for (let e of ents)
e.ApplyMatrix(moveMtx);
}
}
}
/**
* todo:dyn
* ( )
* ()
*
*
* (Shift)
*/

@ -1666,7 +1666,7 @@ export class ExtrudeSolid extends Entity
//避免Jig实体更新,导致性能暴跌.
if (!this.Id) return;
this.__CacheKnifVersion__ = { };
this.__CacheKnifVersion__ = {};
let knifs: ExtrudeSolid[] = [];
this.GetRelevanceKnifes(knifs);

@ -108,6 +108,7 @@ export class Light extends Entity
{
return this._Intensity;
}
set Intensity(v: number)
{
if (equaln(v, this._Intensity, 0.01)) return;
@ -115,6 +116,7 @@ export class Light extends Entity
this._Intensity = v;
this.Update();
}
get WebIntensity()
{
return this._Intensity;

@ -305,6 +305,7 @@ export class CameraControls
/**
*
*/
cameraNormal = new Vector3;
onMouseWheel = (event: WheelEvent) =>
{
event.preventDefault();
@ -312,15 +313,11 @@ export class CameraControls
let pt = new Vector3(event.offsetX, event.offsetY, 0);
this.Viewer.ScreenToWorld(pt, new Vector3().setFromMatrixColumn(this.Viewer.Camera.matrixWorld, 2));
this.Viewer.ScreenToWorld(pt, this.cameraNormal.setFromMatrixColumn(this.Viewer.Camera.matrixWorld, 2));
if (event.deltaY < 0)
{
this.Viewer.Zoom(userConfig.viewSize.zoomSpeed, pt);
}
else if (event.deltaY > 0)
{
this.Viewer.Zoom(2 - userConfig.viewSize.zoomSpeed, pt);
}
};
//在微软输入法下,Control+Space切换输入法时,event.code = 229.
//所以必须使用event.code来得到正确的键盘按钮.

@ -145,6 +145,7 @@ import { Fbx } from "../Add-on/loadfbx";
import { LookOverBoardInfos } from "../Add-on/LookOverBoardInfos/LookOverBoardInfos";
import { MirrorCommand } from "../Add-on/Mirror";
import { Command_Move } from "../Add-on/Move";
import { MoveX as Command_MoveX } from "../Add-on/MoveAxis";
import { Command_M0, Command_PackageMove } from "../Add-on/MoveToWCS0";
import { Command_ExportObj } from "../Add-on/Obj/Command_ExportObj";
import { Command_ExportObjAndMtl } from "../Add-on/Obj/Command_ExportObjMtl";
@ -294,6 +295,8 @@ export function registerCommand()
commandMachine.RegisterCommand(CommandNames.Convert2Polyline, new Command_Conver2Polyline());
commandMachine.RegisterCommand(CommandNames.Move, new Command_Move());
commandMachine.RegisterCommand("mx", new Command_MoveX());
commandMachine.RegisterCommand(CommandNames.Z0, new Command_EntitytMoveToZ0());
commandMachine.RegisterCommand(CommandNames.M0, new Command_M0());
commandMachine.RegisterCommand(CommandNames.PackageGroupMove0, new Command_PackageMove());

@ -92,8 +92,8 @@ export class DbClickManager extends Singleton
lightStore.InitLightData(pickEnt);
let isPointLight = pickEnt instanceof SpotLight || pickEnt instanceof RectAreaLight;
let p = app.Viewer.WorldToScreen(pickEnt.Position);
CADModal.ModalOldPosition.left = `${Math.min(p.x + app.Viewer.DomEl.offsetLeft + 10, window.innerWidth - width)}px`;
CADModal.ModalOldPosition.top = `${Math.min(p.y + app.Viewer.DomEl.offsetTop + 10, window.innerHeight - height)}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`;
app.Editor.ModalManage.RenderModeless(SpotLightModel,
{ store: lightStore, isPointLight: isPointLight }, { position: ModalPosition.Old });

@ -15,7 +15,7 @@ export class GetDistanceServices
async Start(prompt?: GetDistendPrompt): Promise<PromptDistendResult>
{
prompt = prompt || { };
prompt = prompt || {};
let dynInput = this.initDynInput(prompt);
this.removeCalls.push(InitKeyWord(prompt));
app.Editor.InputState |= InputState.GetDist;
@ -64,7 +64,7 @@ export class GetDistanceServices
Msg: "请输入距离或者点取距离:",
KeyWordList: prompt.KeyWordList,
BasePoint: p1,
AllowDrawRubberBand: true,
AllowDrawRubberBand: prompt.DisableRubberBand ? false : true,
NotShowDynPrompt: true,
DisabledBasePointSupportSnap: prompt.DisabledBasePointSupportSnap,
Callback: (p) =>
@ -73,7 +73,7 @@ export class GetDistanceServices
app.Viewer.WorldToScreen(midp);
dynInput.SetPostion(app.Editor.MouseCtrl._CurMousePointVCS);
dynInput.ValuePostion = midp;
// dynInput.ValuePostion = midp;
if (prompt.CalcDistance)
dynInput.Value = prompt.CalcDistance(p1, p);

@ -1,5 +1,5 @@
import hotkeys from 'hotkeys-js-ext';
import { BufferGeometry, Line, Vector3 } from 'three';
import { BufferGeometry, Intersection, Light, Line, Vector3 } from 'three';
import * as xaop from 'xaop';
import { end } from 'xaop';
import { app } from '../ApplicationServices/Application';
@ -18,6 +18,7 @@ import { DownPanelStore } from '../UI/Store/DownPanelStore';
import { EditorService } from './Editor';
import { InitKeyWord, IsKeyword } from './InitKeyword';
import { ObjectSnapMode } from './ObjectSnapMode';
import { GenerateRaycaster, Raycast } from './PointPick';
import { GetPointPrompt } from "./PromptOptions";
import { PromptPointResult, PromptStatus } from './PromptResult';
import { SnapMenuKW, SNAPMODE } from './ShowSnapMenu';
@ -159,11 +160,21 @@ export class GetPointServices implements EditorService
private curPoint: Vector3;
private curPointIsSnap = false;
get IsSnap() { return this.curPointIsSnap; }
private lastPoint: Vector3;
intersection: Intersection;
//更新当前点事件,统一使用该方法注入其他服务的更新(aop在此方法中注入)
UpdateCurPointEvent()
{
let wcs = app.Editor.MouseCtrl._CurMousePointWCS;
if (this._prompt.Raycast)
{
let raycaster = GenerateRaycaster(app.Editor.MouseCtrl._CurMousePointVCS, app.Viewer);
this.intersection = Raycast(raycaster, app.Viewer.VisibleObjects, { filterFunction: (obj, ent) => { return ent && ent.Id && !ent.Id.IsErase && !(ent instanceof Light); } });
if (this.intersection?.point)
app.Editor.MouseCtrl._CurMousePointWCS.copy(this.intersection.point);
}
let snapP = this.snapServices.GetSnapPoint();
if (snapP)
{
@ -216,7 +227,7 @@ export class GetPointServices implements EditorService
{
if (this.curPoint)
{
prompt.Callback(this.curPoint);
prompt.Callback(this.curPoint, this.intersection);
app.Editor.UpdateScreen();
}
}
@ -456,6 +467,7 @@ export class GetPointServices implements EditorService
retValue.Status = PromptStatus.OK;
retValue.Point = p;
retValue.intersection = this.intersection;
retValue.SnaoMode = snapMode;

@ -194,8 +194,8 @@ export class GripDragServices implements EditorService
DragTo(ptRes.Point, snapIndexMap);
app.Editor.UCSMatrix = oldUcs;
app.Viewer.OutlinePass.selectedObjects = oldSelect;
app.Editor.transCtrl.Enable = oldEnable;
app.Editor.SelectCtrl.UpdateView();
this.UpdateSnapPoint();
this.UpdateSnapDraw();
}, "drag");

@ -1,8 +1,8 @@
import { Intersection, Object3D, OrthographicCamera, Raycaster, Vector2, Vector3 } from 'three';
import { equaln } from '../Geometry/GeUtils';
import { IViewer } from '../GraphicsSystem/IView';
import { SelectBox, SelectType } from './SelectBox';
import { CheckFilter, Filter } from './SelectFilter';
import { equaln } from '../Geometry/GeUtils';
import { userConfig } from './UserConfig';
/**
@ -113,14 +113,18 @@ export function Raycast(ray: Raycaster, objectCol: Object3D[], filter?: Filter):
o.raycast(ray, intersects);
});
if (intersects.length > 0)
if (!pick
|| pick.distance > intersects[0].distance
|| (equaln(pick.distance, intersects[0].distance)
&& pick.object.id < intersects[0].object.id))
{
for (let i of intersects)
{
pick = intersects[0];
pick.object = obj;
if (!pick
|| pick.distance > i.distance
|| (equaln(pick.distance, i.distance) && pick.object.id < i.object.id))
{
pick = i;
pick.object = obj;
}
}
}
}
return pick;
}

@ -1,8 +1,8 @@
import { Vector3 } from 'three';
import { Intersection, Vector3 } from 'three';
import { KeyWord } from '../Common/InputState';
import { PromptEntityResult, PromptSsgetResult } from './PromptResult';
import { Filter } from './SelectFilter';
import { SelectType } from './SelectBox';
import { KeyWord } from '../Common/InputState';
import { Filter } from './SelectFilter';
export interface PromptOptions
{
@ -29,7 +29,7 @@ export interface GetPointPrompt extends PromptOptions
//相对坐标参考基点
RelativeBasePoint?: Vector3;
//当鼠标移动时,回调该函数.
Callback?: (pt: Vector3) => void;
Callback?: (pt: Vector3, intersection: Intersection) => void;
//绘制橡皮筋(必须指定基点)
AllowDrawRubberBand?: Boolean;
//不显示动态提示
@ -43,12 +43,14 @@ export interface GetPointPrompt extends PromptOptions
//禁用捕捉
DisabledSnap?: boolean;
DisabledBasePointSupportSnap?: boolean;
Raycast?: boolean;
}
export interface GetDistendPrompt extends PromptOptions
{
BasePoint?: Vector3;
DisabledBasePointSupportSnap?: boolean;
DisableRubberBand?: boolean;
Callback?: (dist: number, pt?: Vector3) => void;
CalcDistance?: (ptBase: Vector3, pt: Vector3) => number;
Default?: number;

@ -1,4 +1,4 @@
import { Object3D, Vector3 } from 'three';
import { Intersection, Object3D, Vector3 } from 'three';
import { Entity } from '../DatabaseServices/Entity/Entity';
import { ObjectSnapMode } from './ObjectSnapMode';
import { SelectSet } from './SelectSet';
@ -38,6 +38,7 @@ export class PromptResult
export class PromptPointResult extends PromptResult
{
SnaoMode: ObjectSnapMode;
intersection: Intersection;
private _point: Vector3;
/**
*

@ -25,8 +25,10 @@ import { SelectPick } from './SelectPick';
*/
export enum AxisSnapMode
{
None = 0,//禁用
Polar = 1,//极轴
Ortho = 2,//正交
Custom = 3,//
}
//捕捉轴
@ -73,19 +75,20 @@ export class SnapServices
SnapPoint: Vector3;//捕捉到的点
AxisSnapBasePoint: Vector3;//当捕捉模式为轴线捕捉时,返回轴线的基点
SnapModeEnable: ObjectSnapMode = ObjectSnapMode.All;
private m_SnapMode: ObjectSnapMode = ObjectSnapMode.None;
private m_DynPrompt: PromptBlock;
private m_HasBasePoint: boolean = false;
private m_IsZAxis = false;
private m_SupportSnapPoints: SupportSnapPoint[] = [];//辅助捕捉点WCS
private m_UCS: Matrix4;
CustomAxis: Vector3[] = [];//自定义捕捉轴
private _SnapMode: ObjectSnapMode = ObjectSnapMode.None;
private _DynPrompt: PromptBlock;
private _HasBasePoint: boolean = false;
private _IsZAxis = false;
private _SupportSnapPoints: SupportSnapPoint[] = [];//辅助捕捉点WCS
private _UCS: Matrix4;
/** 切线捕捉时使用的基点 */
TanBasePoint: Vector3;
//开始捕捉
Start(prompt: GetPointPrompt)
{
this.m_UCS = app.Editor.UCSMatrix;
this._UCS = app.Editor.UCSMatrix;
this.InitDynPrompt();
this.InitCrossCursor();
@ -96,7 +99,7 @@ export class SnapServices
if (prompt.BasePoint && !prompt.DisabledBasePointSupportSnap)
{
this.m_SupportSnapPoints.push({
this._SupportSnapPoints.push({
Point: prompt.BasePoint.clone(),
Entitys: [],
});
@ -116,49 +119,49 @@ export class SnapServices
}
if (ents.length > 0)
this.m_SupportSnapPoints.push({
this._SupportSnapPoints.push({
Point: prompt.BasePoint.clone(),
Entitys: ents,
});
//#endregion
this.UpdateCrossCursor();
this.m_HasBasePoint = true;
this._HasBasePoint = true;
}
else
this.m_HasBasePoint = false;
this._HasBasePoint = false;
}
//结束捕捉服务
Stop()
{
//如果重新捕捉,那么清除添加捕捉点的计时器(放弃添加捕捉点)
if (this.m_DelaySupportSnapId)
if (this._DelaySupportSnapId)
{
clearTimeout(this.m_DelaySupportSnapId);
this.m_DelaySupportSnapId = undefined;
clearTimeout(this._DelaySupportSnapId);
this._DelaySupportSnapId = undefined;
}
this.TanBasePoint = undefined;
this.m_SupportSnapPoints.length = 0;
this._SupportSnapPoints.length = 0;
this.SnapPoint = undefined;
this.m_SupportExtLinePts.length = 0;
this._SupportExtLinePts.length = 0;
this.m_DynPrompt.Visible = false;
this._DynPrompt.Visible = false;
this.UpdateCursort();
}
get SnapMode()
{
return this.m_SnapMode;
return this._SnapMode;
}
set SnapMode(mode)
{
if (mode !== this.m_SnapMode)
if (mode !== this._SnapMode)
{
this.m_SnapMode = mode;
this._SnapMode = mode;
this.UpdateSquareCursorMode(mode);
}
}
@ -188,7 +191,7 @@ export class SnapServices
}
//延迟添加辅助的捕捉点
private m_DelaySupportSnapId;
private _DelaySupportSnapId;
/**
* .
@ -204,8 +207,8 @@ export class SnapServices
*/
private GetEntitySnapPoint()
{
this.m_SupportExtLinePts.length = 0;
this.m_SnapMode = ObjectSnapMode.None;
this._SupportExtLinePts.length = 0;
this._SnapMode = ObjectSnapMode.None;
if (this.Disabled)
return;
@ -215,13 +218,13 @@ export class SnapServices
let vcsP = app.Editor.MouseCtrl._CurMousePointVCS.setZ(0);
let wcsP = app.Editor.MouseCtrl._CurMousePointWCS;
let baseP = this.m_HasBasePoint ? this.m_SupportSnapPoints[0].Point : undefined;
let baseP = this._HasBasePoint ? this._SupportSnapPoints[0].Point : undefined;
//如果重新捕捉,那么清除添加捕捉点的计时器(放弃添加捕捉点)
if (this.m_DelaySupportSnapId)
if (this._DelaySupportSnapId)
{
clearTimeout(this.m_DelaySupportSnapId);
this.m_DelaySupportSnapId = undefined;
clearTimeout(this._DelaySupportSnapId);
this._DelaySupportSnapId = undefined;
}
//获得显示图形和圆心列表
@ -244,7 +247,7 @@ export class SnapServices
}
let sel = new SelectPick(app.Viewer, vcsP, this.SnapSize);//直接用这个,不需要用box,射线追踪没有性能损耗
let selectEns: Entity[] = [];
// let selectEns: Entity[] = [];
// 由于绘制的实体可能有多个分裂,所以代码会重复的去选择,当前注释的代码已经避免这种情况,不过性能并不会提高.所以取消这个代码
// console.time("all");
@ -275,12 +278,12 @@ export class SnapServices
});
// console.timeEnd("all");
selectEns.push(...sel.SelectEntityList);
let selectEns = sel.SelectEntityList;
let viewXform = new Matrix3().setFromMatrix4(app.Viewer.Camera.matrix);
//如果只有切线捕捉
if (this.SnapModeEnable === ObjectSnapMode.Tan && !this.m_HasBasePoint)
if (this.SnapModeEnable === ObjectSnapMode.Tan && !this._HasBasePoint)
for (let e of selectEns)
{
if (e instanceof Circle || e instanceof Arc)
@ -322,24 +325,24 @@ export class SnapServices
if (snapData.Point)
{
//辅助捕捉点控制
this.m_DelaySupportSnapId = setTimeout(
this._DelaySupportSnapId = setTimeout(
() =>
{
let fIndex = this.m_SupportSnapPoints.findIndex(p => equalv3(p.Point, snapData.Point));
let fIndex = this._SupportSnapPoints.findIndex(p => equalv3(p.Point, snapData.Point));
if (fIndex !== -1)
{
if (!(fIndex === 0 && this.m_HasBasePoint))//基点不移除
this.m_SupportSnapPoints.splice(fIndex, 1);
if (!(fIndex === 0 && this._HasBasePoint))//基点不移除
this._SupportSnapPoints.splice(fIndex, 1);
}
else
{
this.m_SupportSnapPoints.push(snapData);
if (this.m_SupportSnapPoints.length > 7)
this._SupportSnapPoints.push(snapData);
if (this._SupportSnapPoints.length > 7)
{
if (this.m_HasBasePoint)
this.m_SupportSnapPoints.splice(1, 1);
if (this._HasBasePoint)
this._SupportSnapPoints.splice(1, 1);
else
this.m_SupportSnapPoints.shift();
this._SupportSnapPoints.shift();
}
}
this.UpdateCrossCursor();
@ -471,6 +474,7 @@ export class SnapServices
*/
private AxisSnap(supportSnapPt: SupportSnapPoint, isFirst = false): SnapAxis
{
if (this.AxisSnapMode === AxisSnapMode.None) return;
if (equalv3(supportSnapPt.Point, app.Editor.MouseCtrl._CurMousePointWCS))
return;
@ -482,6 +486,11 @@ export class SnapServices
if (isFirst)
allowMouseDistSq = Infinity;
}
else if (this.AxisSnapMode === AxisSnapMode.Custom)
{
axisVecs = this.CustomAxis;
allowMouseDistSq = Infinity;
}
let nowVCS = app.Editor.MouseCtrl._CurMousePointVCS;
@ -491,7 +500,7 @@ export class SnapServices
let type: ObjectSnapMode = ObjectSnapMode.Axis;
let isZAxis = false;
let roM = new Matrix4().extractRotation(this.m_UCS);
let roM = new Matrix4().extractRotation(this._UCS);
//切线和垂线的辅助点不需要极轴捕捉
if (supportSnapPt.Entitys.length === 1
@ -550,7 +559,7 @@ export class SnapServices
{
let p = app.Viewer.ScreenToWorld(
nowVCS.clone(),
new Vector3().setFromMatrixColumn(es.Entity.OCS, 2),
new Vector3().setFromMatrixColumn(es.Entity.OCSNoClone, 2),
es.Entity.Center
);
@ -586,12 +595,12 @@ export class SnapServices
//轴线列表
let snapAxisList: SnapAxis[] = [];
for (let i = 0, l = this.m_SupportSnapPoints.length; i < l; i++)
for (let i = 0, l = this._SupportSnapPoints.length; i < l; i++)
{
let snap = this.AxisSnap(this.m_SupportSnapPoints[i], i === 0);
let snap = this.AxisSnap(this._SupportSnapPoints[i], i === 0);
if (snap)
{
snap.BasePoint = this.m_SupportSnapPoints[i].Point;
snap.BasePoint = this._SupportSnapPoints[i].Point;
snapAxisList.push(snap);
}
}
@ -723,7 +732,7 @@ export class SnapServices
if (this.SnapMode === ObjectSnapMode.Axis)
{
this.m_IsZAxis = snapAxis.IsZAxis;
this._IsZAxis = snapAxis.IsZAxis;
this.AxisSnapBasePoint = snapAxisList[0].BasePoint;
}
@ -768,9 +777,9 @@ export class SnapServices
for (let i = 0; i < 7; i++)
{
let l = this.m_CrossCursor[i];
if (this.m_SupportSnapPoints[i])
if (this._SupportSnapPoints[i])
{
l.position.copy(this.m_SupportSnapPoints[i].Point);
l.position.copy(this._SupportSnapPoints[i].Point);
preView.WorldToViewPoint(l.position);
l.updateMatrix();
l.visible = true;
@ -797,7 +806,7 @@ export class SnapServices
{
this.UpdateObjectPosition(
this.m_SquareCursor,
this.SnapPoint && this.m_SupportExtLinePts.length === 0
this.SnapPoint && this._SupportExtLinePts.length === 0
);
}
@ -858,7 +867,7 @@ export class SnapServices
{
this.UpdateObjectPosition(
this.m_ObliqueCrossCursor,
this.m_SupportExtLinePts.length > 0
this._SupportExtLinePts.length > 0
);
}
@ -879,7 +888,7 @@ export class SnapServices
{
this.UpdateObjectPosition(
this.m_ObliqueOutline,
this.m_SupportExtLinePts.length > 2
this._SupportExtLinePts.length > 2
);
}
@ -896,7 +905,7 @@ export class SnapServices
//延伸线辅助显示
private m_SupportExtLine: Line;
m_SupportExtLinePts: Vector3[] = [];
_SupportExtLinePts: Vector3[] = [];
private InitSupportExtLine()
{
if (!this.m_SupportExtLine)
@ -912,12 +921,12 @@ export class SnapServices
}
private UpdateSupportExtLine()
{
if (this.m_SupportExtLinePts.length > 0)
if (this._SupportExtLinePts.length > 0)
{
this.m_SupportExtLine.visible = true;
let geo = this.m_SupportExtLine.geometry as BufferGeometry;
BufferGeometryUtils.UpdatePts(geo, this.m_SupportExtLinePts, true);
geo.drawRange.count = this.m_SupportExtLinePts.length;
BufferGeometryUtils.UpdatePts(geo, this._SupportExtLinePts, true);
geo.drawRange.count = this._SupportExtLinePts.length;
this.m_SupportExtLine.computeLineDistances();
}
@ -958,77 +967,77 @@ export class SnapServices
if (reverse)
pts.reverse();
this.m_SupportExtLinePts.push(...pts);
this._SupportExtLinePts.push(...pts);
}
InitDynPrompt()
{
if (!this.m_DynPrompt)
if (!this._DynPrompt)
{
this.m_DynPrompt = new PromptBlock(DynamicInputManage.GetManage());
this.m_DynPrompt.Visible = false;
this._DynPrompt = new PromptBlock(DynamicInputManage.GetManage());
this._DynPrompt.Visible = false;
}
}
UpdateDynPrompt()
{
if (this.SnapMode === ObjectSnapMode.Axis && this.m_SupportExtLinePts.length > 1)
if (this.SnapMode === ObjectSnapMode.Axis && this._SupportExtLinePts.length > 1)
{
this.m_DynPrompt.Visible = true;
if (this.m_IsZAxis)
this.m_DynPrompt.UpdatePrompt("Z轴");
this._DynPrompt.Visible = true;
if (this._IsZAxis)
this._DynPrompt.UpdatePrompt("Z轴");
else
this.m_DynPrompt.UpdatePrompt("极轴");
this._DynPrompt.UpdatePrompt("极轴");
let vps = this.m_SupportExtLinePts.map(p => app.Viewer.PreViewer.ViewerPointToScreenPoint(p.clone()));
let vps = this._SupportExtLinePts.map(p => app.Viewer.PreViewer.ViewerPointToScreenPoint(p.clone()));
this.m_DynPrompt.SetPostion(midPoint(vps[0], vps[1]));
this._DynPrompt.SetPostion(midPoint(vps[0], vps[1]));
}
else if (this.m_SupportExtLinePts.length === 4)
else if (this._SupportExtLinePts.length === 4)
{
this.m_DynPrompt.Visible = true;
this.m_DynPrompt.SetPostion(app.Viewer.WorldToScreen(this.SnapPoint.clone()).add(new Vector3(0, 100)));
this.m_DynPrompt.UpdatePrompt("轴线交点");
this._DynPrompt.Visible = true;
this._DynPrompt.SetPostion(app.Viewer.WorldToScreen(this.SnapPoint.clone()).add(new Vector3(0, 100)));
this._DynPrompt.UpdatePrompt("轴线交点");
}
else if (this.SnapMode !== ObjectSnapMode.Node && this.SnapPoint)
{
this.m_DynPrompt.Visible = true;
this.m_DynPrompt.SetPostion(
this._DynPrompt.Visible = true;
this._DynPrompt.SetPostion(
app.Viewer.WorldToScreen(this.SnapPoint.clone())
.add(new Vector3(0, 100))
);
switch (this.SnapMode)
{
case ObjectSnapMode.End:
this.m_DynPrompt.UpdatePrompt("端点");
this._DynPrompt.UpdatePrompt("端点");
break;
case ObjectSnapMode.Per:
this.m_DynPrompt.UpdatePrompt("垂足");
this._DynPrompt.UpdatePrompt("垂足");
break;
case ObjectSnapMode.Mid:
this.m_DynPrompt.UpdatePrompt("中点");
this._DynPrompt.UpdatePrompt("中点");
break;
case ObjectSnapMode.Cen:
this.m_DynPrompt.UpdatePrompt("圆心");
this._DynPrompt.UpdatePrompt("圆心");
break;
case ObjectSnapMode.Nea:
this.m_DynPrompt.UpdatePrompt("最近点");
this._DynPrompt.UpdatePrompt("最近点");
break;
case ObjectSnapMode.Ext:
this.m_DynPrompt.UpdatePrompt("延伸");
this._DynPrompt.UpdatePrompt("延伸");
break;
case ObjectSnapMode.Tan:
this.m_DynPrompt.UpdatePrompt("切线");
this._DynPrompt.UpdatePrompt("切线");
break;
case ObjectSnapMode.Int:
this.m_DynPrompt.UpdatePrompt("交点");
this._DynPrompt.UpdatePrompt("交点");
break;
default:
this.m_DynPrompt.Visible = false;
this._DynPrompt.Visible = false;
break;
}
}
else
this.m_DynPrompt.Visible = false;
this._DynPrompt.Visible = false;
}
//#endregion

@ -1,9 +1,9 @@
import { BufferGeometry, Line, LineSegments, Object3D, Vector3, Group } from "three";
import { BufferGeometry, Group, Line, LineSegments, Object3D, Vector3 } from "three";
import { app } from "../ApplicationServices/Application";
import { ColorMaterial } from "../Common/ColorPalette";
import { MatrixToPreViewMat } from "../Editor/UCSServices";
import { BufferGeometryUtils } from "../Geometry/BufferGeometryUtils";
import { PointShapeUtils } from "../Geometry/PointShapeUtils";
import { app } from "../ApplicationServices/Application";
import { MatrixToPreViewMat } from "../Editor/UCSServices";
//光标状态
export enum CursorMode
@ -11,6 +11,7 @@ export enum CursorMode
None = 0,
GetEntity = 1,
GetPoint = 2,//Or GetSelection
Cross = 3,
}
/**
@ -125,6 +126,9 @@ export class Cursor
else
this.CursorObject.add(this._CrossLineObject);
break;
case CursorMode.Cross:
this.CursorObject.add(this._CrossLineObject);
break;
default:
break;
}
@ -166,6 +170,7 @@ export class Cursor
this.UpdateEvent();
}
get CrossLineLength() { return this._LineLength; }
//-------------Event
UpdateEvent()

@ -16,27 +16,23 @@ export enum DrawMode
export class PreViewer
{
private m_bNeedUpdate: boolean;
private _bNeedUpdate: boolean;
//渲染器
private m_Render: WebGLRenderer;
private _Render: WebGLRenderer;
//场景
private m_Scene = new Scene();
private _Scene = new Scene();
//相机控制
protected m_Camera: CameraUpdate;
private m_Width: number;
private m_Height: number;
protected _Camera: CameraUpdate;
private _Width: number;
private _Height: number;
/**
*
*/
Cursor: Cursor;
//容器节点
private m_DomEl: HTMLElement;
constructor(container: HTMLElement)
constructor(private container: HTMLElement)
{
this.m_DomEl = container;
this.InitCamera();
this.InitRender();
@ -53,51 +49,51 @@ export class PreViewer
//当画布大小变换时调用
UpdateSize(width: number, height: number)
{
this.m_Width = width;
this.m_Height = height;
this._Width = width;
this._Height = height;
this.m_Camera.SetSize(this.m_Width, this.m_Height);
this.m_Camera.ViewHeight = this.m_Height;
this.m_Camera.Update();
this._Camera.SetSize(this._Width, this._Height);
this._Camera.ViewHeight = this._Height;
this._Camera.Update();
this.m_Render.setSize(this.m_Width, this.m_Height);
this._Render.setSize(this._Width, this._Height);
}
get Width()
{
return this.m_Width;
return this._Width;
}
get Height()
{
return this.m_Height;
return this._Height;
}
get Scene() { return this.m_Scene; }
get Camera() { return this.m_Camera.Camera; }
get Scene() { return this._Scene; }
get Camera() { return this._Camera.Camera; }
UpdateScreen()
{
this.m_bNeedUpdate = true;
this._bNeedUpdate = true;
}
StartRender = () =>
{
requestAnimationFrame(this.StartRender);
if (this.m_Scene != null && this.m_bNeedUpdate)
if (this._Scene != null && this._bNeedUpdate)
{
this.Render();
this.m_bNeedUpdate = false;
this._bNeedUpdate = false;
}
};
Render()
{
this.m_Render.render(this.Scene, this.Camera);
this._Render.render(this.Scene, this.Camera);
}
//#region -------------------------初始化代码-------------------------
private InitCamera()
{
this.m_Camera = new CameraUpdate();
this.m_Camera.ViewHeight = 1;
this.m_Camera.SetSize(1, 1);
this.m_Camera.Update();
this._Camera = new CameraUpdate();
this._Camera.ViewHeight = 1;
this._Camera.SetSize(1, 1);
this._Camera.Update();
}
private InitRender()
{
@ -114,9 +110,9 @@ export class PreViewer
canvas.style.left = "0px";
canvas.style.top = "0px";
this.m_DomEl.appendChild(canvas);
this.container.appendChild(canvas);
this.m_Render = new WebGLRenderer({ canvas: canvas, alpha: true });
this._Render = new WebGLRenderer({ canvas: canvas, alpha: true });
}
//#endregion
@ -131,15 +127,15 @@ export class PreViewer
//屏幕坐标系赚视图坐标系
ScreenPointToViewerPoint(p: Vector3)
{
p.x = p.x - this.m_Width * 0.5;
p.y = this.m_Height * 0.5 - p.y;
p.x = p.x - this._Width * 0.5;
p.y = this._Height * 0.5 - p.y;
return p;
}
//视图坐标系转屏幕坐标系
ViewerPointToScreenPoint(p: Vector3): Vector3
{
p.x = p.x + this.m_Width * 0.5;
p.y = this.m_Height * 0.5 - p.y;
p.x = p.x + this._Width * 0.5;
p.y = this._Height * 0.5 - p.y;
return p;
}
@ -149,7 +145,7 @@ export class PreViewer
Draw(mode: DrawMode, size: number, pt: Vector3, material: LineBasicMaterial | LineDashedMaterial, isWcs: boolean = true)
{
let PF, DrawType;
let PF: Function, DrawType: any;
switch (mode)
{
case DrawMode.Square:

@ -1,5 +1,5 @@
import hotkeys from 'hotkeys-js-ext';
import { AmbientLight, Box3, Frustum, Matrix4, Object3D, Scene, Vector2, Vector3, WebGLRenderer } from 'three';
import { AmbientLight, Box3, Color, Frustum, Matrix4, Object3D, PCFSoftShadowMap, Scene, SpotLight, Vector2, Vector3, WebGLRenderer } from 'three';
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass";
import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass";
@ -56,7 +56,7 @@ export class Viewer
private _RenderSelectScene = new Scene;
GripScene: GripScene;
DomEl: HTMLElement;
CameraLight: SpotLight;
private _Width: number;
private _Height: number;
@ -66,20 +66,22 @@ export class Viewer
LayoutScene = new Scene();
CurrentViewport: ViewportEntity;
//构造
constructor(canvasContainer: HTMLElement)
constructor(public canvasContainer: HTMLElement)
{
this._Scene.autoUpdate = false;
this.DomEl = canvasContainer;
this.DomEl.oncontextmenu = () => false;//禁止用户选中画布. TODO: 加入右键工具栏.
this.canvasContainer.oncontextmenu = () => false;//禁止用户选中画布. TODO: 加入右键工具栏.
this.GripScene = new GripScene();
this._Scene.add(this.GripScene);
this.CameraLight = new SpotLight(new Color, 15, 0, Math.PI / 2, 0, 0.5);
this._Scene.add(this.CameraLight);
this.PreViewer = new PreViewer(canvasContainer);
let oldDir = new Vector3();
end(this.CameraCtrl, this.CameraCtrl.Update, () =>
end(this.CameraCtrl, this.CameraCtrl.UpdateCameraMatrix, () =>
{
let dir = this.CameraCtrl.Direction;
this.PreViewer.Cursor.IsThreeMode =
@ -89,10 +91,26 @@ export class Viewer
if (app.Editor && !equalv3(dir, oldDir))
{
oldDir = dir.clone();
oldDir.copy(dir);
this.PreViewer.Cursor.Update3DLine();
}
//更新相机灯
if (this.CameraControl.CameraType === CameraType.PerspectiveCamera)
this.CameraLight.position.copy(this.Camera.position);
else
this.CameraLight.getWorldDirection(this.CameraLight.position).multiplyScalar(-2e3).add(this.Camera.position);
this.Camera.getWorldDirection;
if (this.CameraLight.target)
{
this.CameraLight.target.position.copy(this.CameraControl.Target);
this.CameraLight.target.updateMatrix();
this.CameraLight.target.updateMatrixWorld(false);
}
this.CameraLight.updateMatrix();
this.CameraLight.updateMatrixWorld(true);
this.PreViewer.UpdateScreen();
});
@ -205,6 +223,7 @@ export class Viewer
//如果设置那么它希望所有的纹理和颜色都是预乘的伽玛。默认值为false。
this.Renderer.shadowMap.enabled = true;
this.Renderer.shadowMap.type = PCFSoftShadowMap;
this.Renderer.setPixelRatio(window.devicePixelRatio);
this.Renderer.physicallyCorrectLights = true;
@ -225,7 +244,7 @@ export class Viewer
this.OnSize();
}
OnSize = (width = this.DomEl.clientWidth, height = this.DomEl.clientHeight) =>
OnSize = (width = this.canvasContainer.clientWidth, height = this.canvasContainer.clientHeight) =>
{
this._Width = width;
this._Height = height;

@ -150,6 +150,7 @@ export default class SunLightGui extends Component
commandMachine.CommandStart(KEY);
}
app.Database.SunLight.Intensity = val;
app.Database.AmbientLight.Intensity = Math.min(3, val / 20);
this.store.sunLightIntensity = val;
this.SyncSunLight();
};

@ -108,6 +108,7 @@ export default class ResourceStore
while (true)
{
let ptRes = await app.Editor.GetPoint({
Raycast: true,
Callback: p =>
{
e.Position = p.clone().add(move);

@ -1,4 +1,4 @@
import { Vector3, Matrix4 } from 'three';
import { Matrix4, Vector3 } from 'three';
import { end } from 'xaop';
import { app } from '../../ApplicationServices/Application';
import { midPoint, polar } from '../../Geometry/GeUtils';
@ -152,7 +152,7 @@ export class GetPoint2PromptBlock extends PromptBlock
let angSize = new Vector3(angRect.width, angRect.height);
angPos.clamp(new Vector3(), new Vector3(app.Viewer.Width, app.Viewer.Height).sub(angSize));
angPos.y += app.Viewer.DomEl.getBoundingClientRect().top;
angPos.y += app.Viewer.canvasContainer.getBoundingClientRect().top;
this.angleDynIpt.SetPosition(angPos.x, angPos.y);
}
get Dist(): number

Loading…
Cancel
Save