代码迁移
This commit is contained in:
853
src/Obj/ModelController/EditGltf.js
Normal file
853
src/Obj/ModelController/EditGltf.js
Normal file
@ -0,0 +1,853 @@
|
||||
/**
|
||||
* @description 平移旋转3dtitle
|
||||
*/
|
||||
import Event from '../../Event'
|
||||
class EditGltf {
|
||||
constructor(sdk, model) {
|
||||
this.sdk = sdk
|
||||
this.model = model
|
||||
this.activeAxis
|
||||
this.activeCircle
|
||||
this.activeModelParam
|
||||
this.origin
|
||||
this.rayX
|
||||
this.rayY
|
||||
this.rayZ
|
||||
this.arrow = {}
|
||||
this.activeState
|
||||
this.coordArrows = []
|
||||
this.coordCircles = []
|
||||
this.originalMatrix = { ...model.modelMatrix }
|
||||
this.model.rotate || (this.model.rotate = { x: 0, y: 0, z: 0 })
|
||||
this.initParam()
|
||||
|
||||
this.MapEvent = new Event(this.sdk)
|
||||
}
|
||||
|
||||
initParam() {
|
||||
let _this = this
|
||||
let cartographic = Cesium.Cartographic.fromCartesian(this.model.position);
|
||||
let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
|
||||
let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
|
||||
let h = cartographic.height; // 高度
|
||||
this._params = {
|
||||
tx: lng, //模型中心X轴坐标(经度,单位:十进制度)
|
||||
ty: lat, //模型中心Y轴坐标(纬度,单位:十进制度)
|
||||
tz: h, //模型中心Z轴坐标(高程,单位:米)
|
||||
rx: this.model.rotate.x, //X轴(经度)方向旋转角度(单位:度)
|
||||
ry: this.model.rotate.y, //Y轴(纬度)方向旋转角度(单位:度)
|
||||
rz: this.model.rotate.z //Z轴(高程)方向旋转角度(单位:度)
|
||||
}
|
||||
return { lng, lat, alt: h, h, ...this.model.rotate }
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始编辑平移
|
||||
*/
|
||||
editTranslational() {
|
||||
this.destroy()
|
||||
this.activeState = 'translational'
|
||||
this.MapEvent = new Event(this.sdk)
|
||||
// this.sdk.viewer.scene.camera.flyTo({
|
||||
// destination: new Cesium.Cartesian3.fromDegrees(104.17401, 30.63593, 1000),
|
||||
// orientation: {
|
||||
// pitch: Cesium.Math.toRadians(-35.0)
|
||||
// },
|
||||
// duration: 1
|
||||
// })
|
||||
/**
|
||||
* 创建一条射线
|
||||
*/
|
||||
let _this = this
|
||||
let param = this.initParam()
|
||||
let lng = param.lng
|
||||
let lat = param.lat
|
||||
let h = param.h
|
||||
let viewer = this.sdk.viewer
|
||||
// let lon = 104.17401
|
||||
// let lat = 30.64593
|
||||
// let h = 0
|
||||
// 原点
|
||||
this.origin = Cesium.Cartesian3.fromDegrees(lng, lat, h)
|
||||
// 计算xyz轴方向
|
||||
const directionVectorX = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(this.origin, Cesium.Cartesian3.fromDegrees(lng - 0.001, lat, h), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
const directionVectorY = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(this.origin, Cesium.Cartesian3.fromDegrees(lng, lat - 0.001, h), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
const directionVectorZ = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(this.origin, Cesium.Cartesian3.fromDegrees(lng, lat, h - 1), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
this.rayX = new Cesium.Ray(this.origin, directionVectorX)
|
||||
this.rayY = new Cesium.Ray(this.origin, directionVectorY)
|
||||
this.rayZ = new Cesium.Ray(this.origin, directionVectorZ)
|
||||
this.arrow.positionX = Cesium.Ray.getPoint(this.rayX, 0)
|
||||
this.arrow.positionY = Cesium.Ray.getPoint(this.rayY, 0)
|
||||
this.arrow.positionZ = Cesium.Ray.getPoint(this.rayZ, 0)
|
||||
|
||||
const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(
|
||||
new Cesium.Cartesian3.fromDegrees(lng, lat, h)
|
||||
)
|
||||
// 获取相机的位置
|
||||
var cameraPosition = viewer.camera.position;
|
||||
// 计算相机与目标坐标之间的距离
|
||||
var distance = Cesium.Cartesian3.distance(cameraPosition, this.origin);
|
||||
let newRadius = distance / 15
|
||||
let scale = newRadius
|
||||
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(scale, scale, scale), matrix)
|
||||
let axisArrowX = this.createAxisArrow('model_edit_xAxis', [new Cesium.Cartesian3(0, 0.001, 0), new Cesium.Cartesian3(1, 0, 0)], matrix, Cesium.Color.RED)
|
||||
let axisArrowY = this.createAxisArrow('model_edit_yAxis', [new Cesium.Cartesian3(0, 0.001, 0), new Cesium.Cartesian3(0, 1, 0)], matrix, Cesium.Color.LIME)
|
||||
let axisArrowZ = this.createAxisArrow('model_edit_zAxis', [new Cesium.Cartesian3(0, 0.001, 0), new Cesium.Cartesian3(0, 0, 1)], matrix, Cesium.Color.BLUE)
|
||||
viewer.scene.primitives.add(axisArrowX)
|
||||
viewer.scene.primitives.add(axisArrowY)
|
||||
viewer.scene.primitives.add(axisArrowZ)
|
||||
|
||||
this.againArrow()
|
||||
|
||||
// this.sdk.viewer.entities.add({
|
||||
// id: "tool-position_plane_xy",
|
||||
// rectangle: {
|
||||
// coordinates: new Cesium.CallbackProperty(function () {
|
||||
// return Cesium.Rectangle.fromCartesianArray([positionX, positionY])
|
||||
// }, false),
|
||||
// material: Cesium.Color.YELLOW.withAlpha(0),
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
// 监听相机移动
|
||||
this.sdk.viewer.camera.percentageChanged = 0.001
|
||||
this.sdk.viewer.camera.changed.addEventListener(this.againArrow, this);
|
||||
|
||||
let coordinatesDiffer = { x: 0, y: 0 }
|
||||
let lastPickTime = 0;
|
||||
let timeoutEvent
|
||||
this.MapEvent.mouse_move((e, cartesian) => {
|
||||
moveEvent(e)
|
||||
})
|
||||
|
||||
function moveEvent(movement) {
|
||||
if (!_this.activeAxis) {
|
||||
const now = Date.now();
|
||||
if (now - lastPickTime < 100) {
|
||||
clearTimeout(timeoutEvent)
|
||||
timeoutEvent = setTimeout(() => {
|
||||
moveEvent(movement)
|
||||
}, 100);
|
||||
return
|
||||
}
|
||||
clearTimeout(timeoutEvent)
|
||||
lastPickTime = now;
|
||||
let primitives = _this.coordArrows
|
||||
for (let i = 0; i < primitives.length; i++) {
|
||||
if (primitives[i].getGeometryInstanceAttributes) {
|
||||
switch (primitives[i]._name) {
|
||||
case 'model_edit_xAxis':
|
||||
primitives[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: Cesium.Color.RED,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
})
|
||||
break;
|
||||
case 'model_edit_yAxis':
|
||||
primitives[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: Cesium.Color.LIME,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
})
|
||||
break;
|
||||
case 'model_edit_zAxis':
|
||||
primitives[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: Cesium.Color.BLUE,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
})
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let pickedObjectArray = viewer.scene.drillPick(movement.endPosition, 10);
|
||||
for (let i = pickedObjectArray.length - 1; i >= 0; i--) {
|
||||
let pick = pickedObjectArray[i]
|
||||
if (pick && pick.primitive && pick.id) {
|
||||
switch (pick.primitive._name) {
|
||||
case 'model_edit_xAxis':
|
||||
case 'model_edit_yAxis':
|
||||
case 'model_edit_zAxis':
|
||||
pick.primitive.appearance = new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: Cesium.Color.YELLOW,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
})
|
||||
return
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
let y = movement.startPosition.y - movement.endPosition.y //负数往下
|
||||
|
||||
let endPosition = { x: movement.endPosition.x - coordinatesDiffer.x, y: movement.endPosition.y - coordinatesDiffer.y }
|
||||
let ray = viewer.camera.getPickRay(endPosition);//获取一条射线
|
||||
let position = viewer.scene.globe.pick(ray, viewer.scene);
|
||||
let finalPosition = new Cesium.Cartesian3();
|
||||
let matrix4 = Cesium.Transforms.eastNorthUpToFixedFrame(viewer.camera.position);
|
||||
Cesium.Matrix4.inverse(matrix4, matrix4);
|
||||
Cesium.Matrix4.multiplyByPoint(matrix4, position, finalPosition);
|
||||
Cesium.Cartesian3.normalize(finalPosition, finalPosition);
|
||||
let param = _this.initParam()
|
||||
let pitch = 90 + Cesium.Math.toDegrees(Math.asin(finalPosition.z))
|
||||
let camera_cartographic = Cesium.Cartographic.fromCartesian(viewer.camera.position);
|
||||
let a = camera_cartographic.height
|
||||
let b = _this.activeModelParam.alt
|
||||
// let dd = Cesium.Cartesian3.distance(viewer.camera.position, position);
|
||||
let d = a / Math.cos(Cesium.Math.toRadians(pitch))
|
||||
let geodesic = new Cesium.EllipsoidGeodesic(Cesium.Cartographic.fromCartesian(position), Cesium.Cartographic.fromCartesian(viewer.camera.position))
|
||||
|
||||
position = Cesium.Ray.getPoint(ray, d * (1 - (b / a)))
|
||||
let cartographic = Cesium.Cartographic.fromCartesian(position);
|
||||
let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
|
||||
let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
|
||||
let m
|
||||
switch (_this.activeAxis._name) {
|
||||
case 'model_edit_xAxis':
|
||||
_this._params.tx = lng
|
||||
_this._params.ty = _this.activeModelParam.lat
|
||||
_this._params.tz = b
|
||||
|
||||
_this.origin = Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt)
|
||||
// 计算xyz轴方向
|
||||
const directionVectorX = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng - 0.001, param.lat, param.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
const directionVectorY = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat - 0.001, param.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
const directionVectorZ = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt - 1), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
_this.rayX = new Cesium.Ray(_this.origin, directionVectorX)
|
||||
_this.rayY = new Cesium.Ray(_this.origin, directionVectorY)
|
||||
_this.rayZ = new Cesium.Ray(_this.origin, directionVectorZ)
|
||||
break
|
||||
case 'model_edit_yAxis':
|
||||
_this._params.tx = _this.activeModelParam.lng
|
||||
_this._params.ty = lat
|
||||
_this._params.tz = b
|
||||
_this.origin = Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt)
|
||||
// 计算xyz轴方向
|
||||
const directionVectorX2 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng - 0.001, param.lat, param.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
const directionVectorY2 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat - 0.001, param.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
const directionVectorZ2 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt - 1), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
_this.rayX = new Cesium.Ray(_this.origin, directionVectorX2)
|
||||
_this.rayY = new Cesium.Ray(_this.origin, directionVectorY2)
|
||||
_this.rayZ = new Cesium.Ray(_this.origin, directionVectorZ2)
|
||||
break
|
||||
case 'model_edit_zAxis':
|
||||
_this.activeModelParam.alt += (Cesium.Cartesian3.distance(viewer.camera.position, Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt)) / 4300) * y * 3
|
||||
_this._params.tx = _this.activeModelParam.lng
|
||||
_this._params.ty = _this.activeModelParam.lat
|
||||
_this._params.tz = _this.activeModelParam.alt
|
||||
_this.origin = Cesium.Cartesian3.fromDegrees(param.lng, param.lat, _this.activeModelParam.alt)
|
||||
// 计算xyz轴方向
|
||||
const directionVectorX3 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng - 0.001, param.lat, _this.activeModelParam.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
const directionVectorY3 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat - 0.001, _this.activeModelParam.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
const directionVectorZ3 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat, _this.activeModelParam.alt - 1), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||
_this.rayX = new Cesium.Ray(_this.origin, directionVectorX3)
|
||||
_this.rayY = new Cesium.Ray(_this.origin, directionVectorY3)
|
||||
_this.rayZ = new Cesium.Ray(_this.origin, directionVectorZ3)
|
||||
break;
|
||||
default:
|
||||
}
|
||||
_this.updateModel(_this._params.tx, _this._params.ty, _this._params.tz, _this._params.rx, _this._params.ry, _this._params.rz)
|
||||
_this.againArrow()
|
||||
}
|
||||
}
|
||||
|
||||
this.MapEvent.mouse_left_down((event) => {
|
||||
let canvasCoordinates = viewer.scene.cartesianToCanvasCoordinates(this.origin)
|
||||
coordinatesDiffer.x = event.position.x - Math.floor(canvasCoordinates.x)
|
||||
coordinatesDiffer.y = event.position.y - Math.floor(canvasCoordinates.y)
|
||||
let pickedObjectArray = viewer.scene.drillPick(event.position, 10);
|
||||
for (let i = pickedObjectArray.length - 1; i >= 0; i--) {
|
||||
let pickedObject = pickedObjectArray[i]
|
||||
if (pickedObject && pickedObject.primitive && pickedObject.primitive._name) {
|
||||
if (_this.activeAxis) {
|
||||
_this.activeAxis = null
|
||||
_this.activeModelParam = null
|
||||
_this.controllerCallBack
|
||||
}
|
||||
else {
|
||||
switch (pickedObject.primitive._name) {
|
||||
case 'model_edit_xAxis':
|
||||
case 'model_edit_yAxis':
|
||||
case 'model_edit_zAxis':
|
||||
viewer.scene.screenSpaceCameraController.enableRotate = false;
|
||||
_this.activeAxis = pickedObject.primitive
|
||||
_this.activeModelParam = _this.initParam()
|
||||
pickedObject.primitive.appearance = new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: Cesium.Color.YELLOW,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
})
|
||||
return;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
this.MapEvent.mouse_left_up((event) => {
|
||||
viewer.scene.screenSpaceCameraController.enableRotate = true;
|
||||
for (let i = 0; i < _this.coordArrows.length; i++) {
|
||||
switch (_this.coordArrows[i]._name) {
|
||||
case 'model_edit_xAxis':
|
||||
_this.coordArrows[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: Cesium.Color.RED,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
})
|
||||
break;
|
||||
case 'model_edit_yAxis':
|
||||
_this.coordArrows[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: Cesium.Color.LIME,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
})
|
||||
break;
|
||||
case 'model_edit_zAxis':
|
||||
_this.coordArrows[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: Cesium.Color.BLUE,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
})
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if (_this.activeAxis) {
|
||||
_this.activeAxis = null
|
||||
_this.activeModelParam = null
|
||||
_this.controllerCallBack
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 重新计算箭头位置
|
||||
againArrow() {
|
||||
if (!this.activeState || this.activeState != 'translational' || !this.origin) {
|
||||
return
|
||||
}
|
||||
let _that = this
|
||||
_that.initParam()
|
||||
_that.origin = new Cesium.Cartesian3.fromDegrees(_that._params.tx, _that._params.ty, _that._params.tz)
|
||||
let viewer = _that.sdk.viewer
|
||||
// 获取相机的位置
|
||||
var cameraPosition = viewer.camera.position;
|
||||
// 计算相机与目标坐标之间的距离
|
||||
var distance = Cesium.Cartesian3.distance(cameraPosition, _that.origin);
|
||||
let scale = distance / 15
|
||||
const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(_that.origin)
|
||||
|
||||
let primitives = _that.coordArrows
|
||||
for (let i = 0; i < primitives.length; i++) {
|
||||
switch (primitives[i]._name) {
|
||||
case 'model_edit_xAxis':
|
||||
case 'model_edit_yAxis':
|
||||
case 'model_edit_zAxis':
|
||||
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(scale, scale, scale), primitives[i].modelMatrix)
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//重新计算圆
|
||||
againCircle() {
|
||||
if (!this.activeState || this.activeState != 'rtation' || !this.origin) {
|
||||
return
|
||||
}
|
||||
this.initParam()
|
||||
let _this = this
|
||||
let viewer = _this.sdk.viewer
|
||||
// 获取相机的位置
|
||||
var cameraPosition = viewer.camera.position;
|
||||
// 计算相机与目标坐标之间的距离
|
||||
var distance = Cesium.Cartesian3.distance(cameraPosition, _this.origin);
|
||||
let radius = distance / 15
|
||||
const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(_this.origin)
|
||||
let primitives = _this.coordCircles
|
||||
for (let i = 0; i < primitives.length; i++) {
|
||||
switch (primitives[i]._name) {
|
||||
case 'model_edit_zCircle':
|
||||
case 'model_edit_yCircle':
|
||||
case 'model_edit_xCircle':
|
||||
let scale = radius / 20
|
||||
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(scale, scale, scale), primitives[i].modelMatrix)
|
||||
primitives[i]._radius = radius
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始旋转编辑
|
||||
*/
|
||||
editRtation() {
|
||||
this.destroy()
|
||||
this.activeState = 'rtation'
|
||||
this.MapEvent = new Event(this.sdk)
|
||||
const param = this.initParam()
|
||||
this.origin = Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.h)
|
||||
this.createCircle(
|
||||
param.lng,
|
||||
param.lat,
|
||||
param.h,
|
||||
20
|
||||
)
|
||||
// 监听相机移动
|
||||
this.sdk.viewer.camera.percentageChanged = 0.001
|
||||
this.sdk.viewer.camera.changed.addEventListener(this.againCircle, this);
|
||||
}
|
||||
|
||||
createCircle(lng, lat, height, radius) {
|
||||
let _this = this
|
||||
let viewer = this.sdk.viewer
|
||||
const position = []
|
||||
for (let i = 0; i <= 360; i += 3) {
|
||||
const sin = Math.sin(Cesium.Math.toRadians(i))
|
||||
const cos = Math.cos(Cesium.Math.toRadians(i))
|
||||
const x = radius * cos
|
||||
const y = radius * sin
|
||||
position.push(new Cesium.Cartesian3(x, y, 0))
|
||||
}
|
||||
const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(
|
||||
new Cesium.Cartesian3.fromDegrees(lng, lat, height)
|
||||
)
|
||||
// 获取相机的位置
|
||||
var cameraPosition = viewer.camera.position;
|
||||
// 计算相机与目标坐标之间的距离
|
||||
var distance = Cesium.Cartesian3.distance(cameraPosition, this.origin);
|
||||
let newRadius = distance / 15
|
||||
let scale = newRadius / radius
|
||||
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(scale, scale, scale), matrix)
|
||||
// Cesium.Matrix4.multiply(
|
||||
// matrix,
|
||||
// x,
|
||||
// matrix
|
||||
// )
|
||||
//绕Z轴
|
||||
const axisSphereZ = this.createAxisSphere(
|
||||
'model_edit_zCircle',
|
||||
position,
|
||||
matrix,
|
||||
Cesium.Color.RED,
|
||||
newRadius
|
||||
)
|
||||
viewer.scene.primitives.add(axisSphereZ)
|
||||
|
||||
//绕Y周
|
||||
const axisSphereY = this.createAxisSphere(
|
||||
'model_edit_yCircle',
|
||||
position,
|
||||
matrix,
|
||||
Cesium.Color.BLUE,
|
||||
newRadius
|
||||
)
|
||||
viewer.scene.primitives.add(axisSphereY)
|
||||
let my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90))
|
||||
let rotationY = Cesium.Matrix4.fromRotationTranslation(my)
|
||||
Cesium.Matrix4.multiply(
|
||||
axisSphereY.geometryInstances.modelMatrix,
|
||||
rotationY,
|
||||
axisSphereY.geometryInstances.modelMatrix
|
||||
)
|
||||
|
||||
//绕X周
|
||||
const axisSphereX = this.createAxisSphere(
|
||||
'model_edit_xCircle',
|
||||
position,
|
||||
matrix,
|
||||
Cesium.Color.LIME,
|
||||
newRadius
|
||||
)
|
||||
viewer.scene.primitives.add(axisSphereX)
|
||||
let mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(90))
|
||||
let rotationX = Cesium.Matrix4.fromRotationTranslation(mx)
|
||||
Cesium.Matrix4.multiply(
|
||||
axisSphereX.geometryInstances.modelMatrix,
|
||||
rotationX,
|
||||
axisSphereX.geometryInstances.modelMatrix
|
||||
)
|
||||
|
||||
let lastPickTime = 0;
|
||||
let timeoutEvent
|
||||
this.MapEvent.mouse_move((movement) => {
|
||||
moveEvent(movement)
|
||||
})
|
||||
|
||||
function moveEvent(movement) {
|
||||
let endPosition = { ...movement.endPosition }
|
||||
if (!_this.activeCircle) {
|
||||
const now = Date.now();
|
||||
if (now - lastPickTime < 100) {
|
||||
clearTimeout(timeoutEvent)
|
||||
timeoutEvent = setTimeout(() => {
|
||||
moveEvent(movement)
|
||||
}, 100);
|
||||
return
|
||||
}
|
||||
clearTimeout(timeoutEvent)
|
||||
lastPickTime = now;
|
||||
let primitives = _this.coordCircles
|
||||
for (let i = 0; i < primitives.length; i++) {
|
||||
if (primitives[i].getGeometryInstanceAttributes) {
|
||||
let attributes = primitives[i].getGeometryInstanceAttributes(primitives[i]._name);
|
||||
switch (primitives[i]._name) {
|
||||
case 'model_edit_zCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED).value
|
||||
break;
|
||||
case 'model_edit_yCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE).value
|
||||
break;
|
||||
case 'model_edit_xCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.LIME).value
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
let pickedObjectArray = viewer.scene.drillPick(movement.endPosition, 10);
|
||||
for (let i = 0; i < pickedObjectArray.length; i++) {
|
||||
let pick = pickedObjectArray[i]
|
||||
if (pick && pick.primitive && pick.id && pick.primitive.getGeometryInstanceAttributes) {
|
||||
let attributes = pick.primitive.getGeometryInstanceAttributes(pick.id);
|
||||
switch (pick.primitive._name) {
|
||||
case 'model_edit_zCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW).value
|
||||
return;
|
||||
case 'model_edit_yCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW).value
|
||||
return;
|
||||
case 'model_edit_xCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW).value
|
||||
return;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
let position1 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, _this.ciclkPosition);
|
||||
|
||||
let _rx = 0,
|
||||
_ry = 0,
|
||||
_rz = 0 //xyz方向的旋转量(度)
|
||||
if (!position1) {
|
||||
return
|
||||
}
|
||||
const _yPix = movement.startPosition.y - endPosition.y
|
||||
const _xPix = movement.startPosition.x - endPosition.x
|
||||
switch (_this.activeCircle._name) {
|
||||
case 'model_edit_xCircle':
|
||||
_ry = 1 * _xPix
|
||||
break;
|
||||
case 'model_edit_yCircle':
|
||||
_rx = 1 * _yPix
|
||||
break;
|
||||
case 'model_edit_zCircle':
|
||||
_rz = 1 * _xPix
|
||||
break;
|
||||
default:
|
||||
}
|
||||
_this._params.rx -= _rx
|
||||
if (_this._params.rx > 360) {
|
||||
_this._params.rx = 1
|
||||
}
|
||||
if (_this._params.rx < 0) {
|
||||
_this._params.rx = 360
|
||||
}
|
||||
let mx = Cesium.Matrix3.fromRotationX(
|
||||
Cesium.Math.toRadians(_this._params.rx)
|
||||
)
|
||||
_this._params.ry -= _ry
|
||||
if (_this._params.ry > 360) {
|
||||
_this._params.ry = 1
|
||||
}
|
||||
if (_this._params.ry < 0) {
|
||||
_this._params.ry = 360
|
||||
}
|
||||
let my = Cesium.Matrix3.fromRotationY(
|
||||
Cesium.Math.toRadians(_this._params.ry)
|
||||
)
|
||||
_this._params.rz -= _rz
|
||||
if (_this._params.rz > 360) {
|
||||
_this._params.rz = 1
|
||||
}
|
||||
if (_this._params.rz < 0) {
|
||||
_this._params.rz = 360
|
||||
}
|
||||
_this.updateModel(_this._params.tx, _this._params.ty, _this._params.tz, _this._params.rx, _this._params.ry, _this._params.rz)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.MapEvent.mouse_left_down((event) => {
|
||||
let cartesian = viewer.scene.pickPosition(event.position);
|
||||
_this.ciclkPosition = cartesian
|
||||
let pickedObjectArray = viewer.scene.drillPick(event.position, 10);
|
||||
for (let i = 0; i < pickedObjectArray.length; i++) {
|
||||
let pickedObject = pickedObjectArray[i]
|
||||
if (pickedObject && pickedObject.primitive && pickedObject.id) {
|
||||
switch (pickedObject.primitive._name) {
|
||||
case 'model_edit_xCircle':
|
||||
case 'model_edit_yCircle':
|
||||
case 'model_edit_zCircle':
|
||||
let attributes = pickedObject.primitive.getGeometryInstanceAttributes(pickedObject.primitive._name);
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW).value
|
||||
_this.activeCircle = pickedObject.primitive
|
||||
_this.activeModelParam = _this.initParam()
|
||||
viewer.scene.screenSpaceCameraController.enableRotate = false
|
||||
return;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
_this.activeCircle = null
|
||||
_this.activeModelParam = null
|
||||
viewer.scene.screenSpaceCameraController.enableRotate = true
|
||||
})
|
||||
this.MapEvent.mouse_left_up((event) => {
|
||||
_this.activeCircle = null
|
||||
_this.activeModelParam = null
|
||||
viewer.scene.screenSpaceCameraController.enableRotate = true
|
||||
let primitives = _this.coordCircles
|
||||
for (let i = 0; i < primitives.length; i++) {
|
||||
if (primitives[i].getGeometryInstanceAttributes) {
|
||||
let attributes = primitives[i].getGeometryInstanceAttributes(primitives[i]._name);
|
||||
switch (primitives[i]._name) {
|
||||
case 'model_edit_zCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED).value
|
||||
break;
|
||||
case 'model_edit_yCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE).value
|
||||
break;
|
||||
case 'model_edit_xCircle':
|
||||
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.LIME).value
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//更新模型位置
|
||||
updateModel(_tx, _ty, _tz, _rx = 0, _ry = 0, _rz = 0) {
|
||||
this._params.tx = _tx = parseFloat(parseFloat(_tx).toFixed(8))
|
||||
this._params.ty = _ty = parseFloat(parseFloat(_ty).toFixed(8))
|
||||
this._params.tz = _tz = parseFloat(parseFloat(_tz).toFixed(2))
|
||||
this._params.rx = _rx = parseFloat(_rx)
|
||||
this._params.ry = _ry = parseFloat(_ry)
|
||||
this._params.rz = _rz = parseFloat(_rz)
|
||||
|
||||
this.model.position = new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz)
|
||||
this.model.rotate = { x: _rx, y: _ry, z: _rz }
|
||||
let mx = Cesium.Matrix3.fromRotationX(
|
||||
Cesium.Math.toRadians(_rx)
|
||||
)
|
||||
let my = Cesium.Matrix3.fromRotationY(
|
||||
Cesium.Math.toRadians(_ry)
|
||||
)
|
||||
let mz = Cesium.Matrix3.fromRotationZ(
|
||||
Cesium.Math.toRadians(_rz)
|
||||
)
|
||||
// 平移
|
||||
let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz))
|
||||
// 旋转
|
||||
let rotationX = Cesium.Matrix4.fromRotationTranslation(mx)
|
||||
let rotationY = Cesium.Matrix4.fromRotationTranslation(my)
|
||||
let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz)
|
||||
let originalMatrix = new Cesium.Matrix4()
|
||||
Cesium.Matrix4.multiply(m, rotationX, originalMatrix)
|
||||
Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix)
|
||||
Cesium.Matrix4.multiply(originalMatrix, rotationZ, this.model.modelMatrix)
|
||||
this.transformCallBack
|
||||
}
|
||||
|
||||
set transformCallBack(callback) {
|
||||
this._transformCallBack = callback
|
||||
}
|
||||
get transformCallBack() {
|
||||
this._transformCallBack && this._transformCallBack(this._params)
|
||||
}
|
||||
|
||||
createAxisArrow(name, position, matrix, color) {
|
||||
let result = new Cesium.Primitive({
|
||||
geometryInstances: new Cesium.GeometryInstance({
|
||||
id: name,
|
||||
geometry: new Cesium.PolylineGeometry({
|
||||
positions: position,
|
||||
width: 20
|
||||
}),
|
||||
attributes: {
|
||||
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
|
||||
}
|
||||
}),
|
||||
releaseGeometryInstances: false,
|
||||
appearance: new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||
color: color,
|
||||
}),
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
}),
|
||||
modelMatrix: matrix
|
||||
})
|
||||
result._name = name
|
||||
this.coordArrows.push(result)
|
||||
return result
|
||||
}
|
||||
|
||||
createAxisSphere(name, position, matrix, color, radius) {
|
||||
let result = new Cesium.Primitive({
|
||||
geometryInstances: new Cesium.GeometryInstance({
|
||||
id: name,
|
||||
geometry: new Cesium.PolylineGeometry({
|
||||
positions: position,
|
||||
width: 5
|
||||
}),
|
||||
attributes: {
|
||||
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
|
||||
}
|
||||
}),
|
||||
releaseGeometryInstances: false,
|
||||
appearance: new Cesium.PolylineColorAppearance({
|
||||
translucent: true,
|
||||
renderState: {
|
||||
depthTest: {
|
||||
enabled: false,
|
||||
},
|
||||
depthMask: false,
|
||||
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||
},
|
||||
}),
|
||||
modelMatrix: matrix
|
||||
})
|
||||
result._radius = radius
|
||||
result._name = name
|
||||
this.coordCircles.push(result)
|
||||
return result
|
||||
}
|
||||
|
||||
removeCoordArrows() {
|
||||
for (let i = 0; i < this.coordArrows.length; i++) {
|
||||
this.sdk.viewer.scene.primitives.remove(this.coordArrows[i])
|
||||
}
|
||||
this.coordArrows = []
|
||||
}
|
||||
|
||||
removeCoordCircle() {
|
||||
for (let i = 0; i < this.coordCircles.length; i++) {
|
||||
this.sdk.viewer.scene.primitives.remove(this.coordCircles[i])
|
||||
}
|
||||
this.coordCircles = []
|
||||
}
|
||||
|
||||
update() {
|
||||
this.againArrow()
|
||||
this.againCircle()
|
||||
}
|
||||
|
||||
removeAllTools() {
|
||||
this.removeCoordArrows()
|
||||
this.removeCoordCircle()
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭/注销
|
||||
*/
|
||||
destroy() {
|
||||
this.removeAllTools()
|
||||
this.activeState = undefined
|
||||
this.MapEvent && this.MapEvent.destroy()
|
||||
this.sdk.viewer.camera.changed.removeEventListener(this.againArrow)
|
||||
this.sdk.viewer.camera.changed.removeEventListener(this.againCircle)
|
||||
}
|
||||
|
||||
getActiveState() {
|
||||
return this.activeState
|
||||
}
|
||||
|
||||
getModel() {
|
||||
return this.model
|
||||
}
|
||||
|
||||
setModel(target) {
|
||||
this.model = model
|
||||
}
|
||||
}
|
||||
export default EditGltf
|
89
src/Obj/ModelController/EditParticle.js
Normal file
89
src/Obj/ModelController/EditParticle.js
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @description 平移旋转粒子效果(未完成)
|
||||
*/
|
||||
import Event from '../../Event'
|
||||
class EditParticle {
|
||||
constructor(sdk, model) {
|
||||
this.sdk = sdk
|
||||
this.model = model
|
||||
|
||||
let handlerGE = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
|
||||
this.MapEvent = new Event(this.sdk)
|
||||
|
||||
// 获取双击的实体
|
||||
const entity = model;
|
||||
if (!entity) return;
|
||||
|
||||
let diff = []; // 记录选中实体与鼠标位置信息的差异
|
||||
let type = null; // 记录选中的实体类型
|
||||
let positions = null; // 记录选中实体的位置信息
|
||||
let newPosition = null; // 记录鼠标移动的位置
|
||||
const position = changeToThree(event.position); // 获取鼠标双击点的位置,并转为世界坐标
|
||||
// 根据选中的实体类型获取位置信息
|
||||
if (entity.polygon) {
|
||||
if (!entity.polygon.hierarchy?._value) return;
|
||||
type = "polygon";
|
||||
positions = entity.polygon.hierarchy._value.positions;
|
||||
} else if (entity.polyline) {
|
||||
if (!entity.polyline.positions?._value) return;
|
||||
type = "polyline"
|
||||
positions = entity.polyline.positions._value;
|
||||
};
|
||||
// 记录选中实体与鼠标位置信息的差异
|
||||
positions.forEach(item => {
|
||||
diff.push({
|
||||
x: item.x - position.x,
|
||||
y: item.y - position.y,
|
||||
z: item.z - position.z,
|
||||
});
|
||||
});
|
||||
|
||||
// 鼠标移动开始移动实体
|
||||
handlerGE.setInputAction(event => {
|
||||
// 获取移动点的位置,且将格式转为世界坐标
|
||||
const movePosition = changeToThree(event.endPosition);
|
||||
// 根据鼠标位置以及选中实体与鼠标位置信息的差异计算出移动后的实体位置
|
||||
newPosition = diff.map(item => ({
|
||||
x: item.x + movePosition.x,
|
||||
y: item.y + movePosition.y,
|
||||
z: item.z + movePosition.z,
|
||||
}));
|
||||
if (type === "polygon") {
|
||||
// 动态改变面的位置信息
|
||||
entity.polygon.hierarchy = new Cesium.CallbackProperty(function () {
|
||||
return new Cesium.PolygonHierarchy(newPosition);
|
||||
}, false);
|
||||
// 动态改变面边框的位置信息
|
||||
entity.polygon.positions = new Cesium.CallbackProperty(function () {
|
||||
return newPosition.concat([newPosition[0]]);
|
||||
}, false);
|
||||
} else if (type === "polyline") {
|
||||
// 动态改变面的位置信息
|
||||
entity.polygon.positions = new Cesium.CallbackProperty(function () {
|
||||
return newPosition;
|
||||
}, false);
|
||||
};
|
||||
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||
|
||||
// 鼠标右键结束移动
|
||||
handlerGE.setInputAction(() => {
|
||||
// 根据选中的实体类型确认位置信息
|
||||
if (type === "polygon") {
|
||||
entity.polygon.hierarchy = newPosition;
|
||||
entity.polyline.positions = newPosition.concat([newPosition[0]]);
|
||||
} else if (type === "polyline") {
|
||||
entity.polyline.positions = newPosition;
|
||||
};
|
||||
// 初始化
|
||||
diff = [];
|
||||
type = null;
|
||||
positions = null;
|
||||
isMove = false;
|
||||
newPosition = null;
|
||||
// 清除鼠标移动监听和点击右键监听
|
||||
handlerGE.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||
handlerGE.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
||||
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
||||
}
|
||||
}
|
||||
export default EditParticle
|
Reference in New Issue
Block a user