mirror of https://gitee.com/cf-fz/WebCAD.git
parent
1bc879bde1
commit
50a87fd8a8
@ -1,20 +1,107 @@
|
||||
import { SelectSetBase } from './SelectSet';
|
||||
import { Object3D, Raycaster, Vector2, Vector3, Line } from 'three';
|
||||
import { Vec3DTo2D } from '../Common/CurveUtils';
|
||||
import { Viewer } from '../GraphicsSystem/Viewer';
|
||||
import { Vector3 } from 'three';
|
||||
import { SelectBox } from './SelectBox';
|
||||
import { GripScene } from '../GraphicsSystem/GripScene';
|
||||
import { SelectType } from './SelectSet';
|
||||
|
||||
/**
|
||||
* 点选的数据结构
|
||||
*
|
||||
* @export
|
||||
* @class SelectPick
|
||||
* @extends {SelectSetBase}
|
||||
* @extends {SelectBox}
|
||||
*/
|
||||
export class SelectPick extends SelectSetBase
|
||||
export class SelectPick extends SelectBox
|
||||
{
|
||||
m_PickPoint: Vector3;
|
||||
|
||||
//用户点击选择时,点击的鼠标点(屏幕坐标系)
|
||||
m_PickPointVcs: Vector3;
|
||||
m_Raycaster: Raycaster = new Raycaster();
|
||||
constructor(view: Viewer, ptVcs: Vector3)
|
||||
{
|
||||
super(view);
|
||||
this.m_PickPoint = ptVcs.clone();
|
||||
super(view,
|
||||
Vec3DTo2D(ptVcs).add(new Vector2(-5, -5)),
|
||||
Vec3DTo2D(ptVcs).add(new Vector2(5, 5))
|
||||
);
|
||||
this.m_SelectType = SelectType.C;
|
||||
|
||||
this.m_PickPointVcs = ptVcs.clone();
|
||||
|
||||
this.m_Raycaster.setFromCamera({
|
||||
x: (ptVcs.x / view.Width) * 2 - 1, //-1 到 1 所以 (x-(w/2))/(w/2) =>
|
||||
y: - (ptVcs.y / view.Height) * 2 + 1 //y轴相反
|
||||
}, view.Camera);
|
||||
this.m_Raycaster.ray.origin.sub(this.m_Raycaster.ray.direction.clone().multiplyScalar(1e3));
|
||||
}
|
||||
|
||||
Select(selectList?: Object3D[], onlyOne = true)
|
||||
{
|
||||
selectList = selectList || this.m_Viewer.Scene.children;
|
||||
|
||||
//1.射线检测
|
||||
let pickObj: Object3D;
|
||||
let minDistance: number = 1e300;
|
||||
for (let obj of selectList)
|
||||
{
|
||||
if (this.IsNotRayCaster(obj)) continue;
|
||||
|
||||
let intersects = [];
|
||||
obj.traverse(o =>
|
||||
{
|
||||
if (intersects.length === 0 && !this.IsNotRayCaster(o))
|
||||
o.raycast(this.m_Raycaster, intersects)
|
||||
})
|
||||
if (intersects.length > 0)
|
||||
if (minDistance > intersects[0].distance)
|
||||
{
|
||||
pickObj = obj;
|
||||
minDistance = intersects[0].distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (pickObj)
|
||||
{
|
||||
this.m_SelectList.push(pickObj);
|
||||
return;
|
||||
}
|
||||
|
||||
//2. 交点检测
|
||||
this.Select(selectList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单选重构了该方法,可以检验对象是否在选择框内
|
||||
*
|
||||
* @param {Object3D} obj
|
||||
* @returns {Boolean}
|
||||
* @memberof SelectPick
|
||||
*/
|
||||
IntersectObject(obj: Object3D): Boolean
|
||||
{
|
||||
if (!this.FrustomIntersectObject(obj))
|
||||
return false;
|
||||
|
||||
//1.射线检测
|
||||
if (!this.IsNotRayCaster(obj))
|
||||
{
|
||||
let intersects = [];
|
||||
obj.traverse(o =>
|
||||
{
|
||||
if (!this.IsNotRayCaster(obj))
|
||||
{
|
||||
o.raycast(this.m_Raycaster, intersects)
|
||||
if (intersects.length > 0)
|
||||
return true;
|
||||
}
|
||||
})
|
||||
}
|
||||
//2.相交检测
|
||||
return super.IntersectObject(obj);
|
||||
}
|
||||
|
||||
IsNotRayCaster(obj: Object3D)
|
||||
{
|
||||
return (!obj.visible || obj instanceof Line || obj instanceof GripScene);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in new issue