123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- import math from './math'
- import Colors from '@sdk/modules/core/enum/Colors'
- import config from '@sdk/internal/configs'
- //画线等函数--by 许钟文
- import { Fatline, LineGeometry, LineMaterial } from '@sdk/modules/core/objects/Line.js'
- var defaultColor = Colors.lightGreen
- let player = null
- var LineDraw = {
- /*
- 多段普通线 (第二个点和第三个点之间是没有线段的, 所以不用在意线段顺序)
- */
- createLine: function (posArr, o) {
- var mat
- if (o.mat) {
- mat = o.mat
- } else {
- let prop = {
- color: o.color || defaultColor,
- transparent: o.dontAlwaysSeen ? false : true,
- depthTest: o.dontAlwaysSeen ? true : false,
- }
- if (o.deshed) {
- prop.lineWidth = o.lineWidth || 1 //windows无效。 似乎mac/ios上粗细有效 ?
- prop.dashSize = o.dashSize || 0.1
- prop.gapSize = o.gapSize || 0.1
- }
- mat = new THREE[o.deshed ? 'LineDashedMaterial' : 'LineBasicMaterial'](prop)
- }
- var line = new THREE.LineSegments(new THREE.BufferGeometry(), mat)
- line.renderOrder = o.renderOrder || 4
- this.moveLine(line, posArr)
- return line
- },
- moveLine: function (line, posArr) {
- if (posArr.length == 0) {
- return console.log(1)
- }
- let position = []
- posArr.forEach(e => position.push(e.x, e.y, e.z))
- line.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(position), 3))
- line.geometry.attributes.position.needsUpdate = true
- line.geometry.computeBoundingSphere()
- if (line.material instanceof THREE.LineDashedMaterial) {
- line.computeLineDistances()
- }
- },
- createFatLineMat: function (o) {
- let matParam = Object.assign(
- {},
- {
- //默认
- lineWidth: 5,
- color: 0xffffff,
- transparent: true,
- depthWrite: false,
- depthTest: false,
- dashSize: 0.1,
- gapSize: 0.1,
- },
- o,
- {
- //修正覆盖:
- // dashed
- /* polygonOffset: true, //是否开启多边形偏移 for not cover the lineMesh
- polygonOffsetFactor: -o.width * 2.5 || -5, //多边形偏移因子
- polygonOffsetUnits: -4.0, //多边形偏移单位 */
- }
- )
- var mat = new LineMaterial(matParam)
- return mat
- },
- /*
- 创建可以改变粗细的线。
- */
- createFatLine: function (posArr, o) {
- let geometry = new LineGeometry()
- geometry.setColors(o.color || [1, 1, 1])
- var matLine = o.material || this.createFatLineMat(o)
- let line = new Fatline(geometry, matLine)
- //line.computeLineDistances();
- line.scale.set(1, 1, 1)
- line.renderOrder = 2
- this.moveFatLine(line, posArr)
- return line
- },
- /* createFatLine: function (posArr, o) {
- var geometry = new THREE.BufferGeometry()
- geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(posArr), 3))
- geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(o.color || [1, 1, 1]), 3))
- var matLine = o.material || this.createFatLineMat(o)
- var line = new THREE.Line(geometry, matLine)
- line.computeLineDistances()
- line.scale.set(1, 1, 1)
- line.renderOrder = 2
- return line
- }, */
- moveFatLine: function (line, posArr) {
- var geometry = line.geometry
- var positions = []
- posArr.forEach(e => positions.push(e.x, e.y, e.z))
- if (positions.length > 0) {
- if (!geometry) {
- geometry = line.geometry = new LineGeometry()
- }
- if (geometry.attributes.instanceEnd && geometry.attributes.instanceEnd.data.array.length != positions.length) {
- //positions个数改变会有部分显示不出来,所以重建
- geometry.dispose()
- geometry = new LineGeometry()
- line.geometry = geometry
- }
- geometry.setPositions(positions)
- if (line.material.dashed) {
- //line.geometry.computeBoundingSphere();
- line.computeLineDistances()
- }
- } else {
- geometry.dispose()
- line.geometry = new LineGeometry()
- }
- },
- /* moveFatLine: function (line, posArr) {
- var geometry = line.geometry
- geometry.setPositions(posArr)
- }, */
- /*
-
- 为line创建用于检测鼠标的透明mesh,实际是个1-2段圆台。
- 由于近大远小的原因,假设没有透视畸变、创建的是等粗的圆柱的话, 所看到的线上每个位置的粗细应该和距离成反比。所以将圆柱改为根据距离线性渐变其截面半径的圆台,在最近点(相机到线的垂足)最细。如果最近点在线段上,则分成两段圆台,否则一段。
- */
- createBoldLine: function (points, o, p) {
- player = p
- o = o || {}
- var cylinder = o && o.cylinder
- var CD = points[1].clone().sub(points[0])
- var rotate = function () {
- //根据端点旋转好模型
- cylinder.lastVector = CD //记录本次的端点向量
- var AB = new THREE.Vector3(0, -1, 0)
- var axisVec = AB.clone().cross(CD).normalize() //得到垂直于它们的向量,也就是旋转轴
- var rotationAngle = AB.angleTo(CD)
- cylinder.quaternion.setFromAxisAngle(axisVec, rotationAngle)
- }
- if (o && o.type == 'init') {
- cylinder = new THREE.Mesh()
- cylinder.material = o.mat
- if (CD.length() == 0) return cylinder
- rotate()
- }
- if (CD.length() == 0) return cylinder
- if (o.type != 'update') {
- var CDcenter = points[0].clone().add(points[1]).multiplyScalar(0.5)
- cylinder.position.copy(CDcenter)
- if (!cylinder.lastVector || o.type == 'moveAndRotate') rotate()
- else if (cylinder.lastVector && CD.angleTo(cylinder.lastVector) > 0) rotate() //线方向改了or线反向了 重新旋转一下模型
- // if (config.isEdit && !objects.mainDesign.editing) return cylinder //节省初始加载时间?
- }
- //为了保证线段任何地方的可检测点击范围看起来一样大,更新圆台的结构(但是在镜头边缘会比中心看起来大)
- var height = points[0].distanceTo(points[1])
- var standPos = (o && o.standPos) || player.position
- var k = config.isMobile ? 20 : 40
- var dis1 = points[0].distanceTo(standPos)
- var dis2 = points[1].distanceTo(standPos)
- var foot = math.getFootPoint(standPos, points[0], points[1]) //垂足
- if (o.constantBold || player.mode != 'panorama') {
- var width = 0.1 //0.08;
- var pts = [new THREE.Vector2(width, height / 2), new THREE.Vector2(width, -height / 2)]
- } else if (foot.clone().sub(points[0]).dot(foot.clone().sub(points[1])) > 0) {
- //foot不在线段上
- var pts = [new THREE.Vector2(dis1 / k, height / 2), new THREE.Vector2(dis2 / k, -height / 2)]
- } else {
- //在线段上的话,要在垂足这加一个节点,因它距离站位最近,而两端较远
- var dis3 = foot.distanceTo(standPos)
- var len = foot.distanceTo(points[0])
- var pts = [new THREE.Vector2(dis1 / k, height / 2), new THREE.Vector2(dis3 / k, height / 2 - len), new THREE.Vector2(dis2 / k, -height / 2)]
- }
- cylinder.geometry && cylinder.geometry.dispose() //若不删除会占用内存
- cylinder.geometry = new THREE.LatheBufferGeometry(pts, 4 /* Math.min(dis1,dis2)<10?4:3 */)
- cylinder.renderOrder = 2
- return cylinder
- },
- updateBoldLine: function (cylinder, points, type, standPos, constantBold) {
- this.createBoldLine(points, { type: type, cylinder: cylinder, standPos: standPos, constantBold }, player) //type:move:平移 会改长短 , type:update根据距离和角度更新 不改长短
- },
-
-
-
- Fatline, fatLineGeometry:LineGeometry,
-
- }
- export default LineDraw
|